前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MyBatis+Spring MVC开发指南(一)前言没有MyBatis之前 MyBatis框架的架构Quick StartMapper代理开发关于自增主键返回关于动态SQL

MyBatis+Spring MVC开发指南(一)前言没有MyBatis之前 MyBatis框架的架构Quick StartMapper代理开发关于自增主键返回关于动态SQL

作者头像
用户2890438
发布2018-08-21 09:50:11
4820
发布2018-08-21 09:50:11
举报

前言

MyBatis+Spring MVC这套组合,在实际互联网项目中非常流行,博主工作中也涉及过,打算由浅入深、系统的写出来!这个系列将会涵盖MyBatis开发详解、Spring MVC开发详解,以及2者的结合使用,并会分析它们的原理!(可以参考博主的另一篇文章了解Spring MVC原理:《写出我的第一个框架:迷你版Spring MVC》)

没有MyBatis之前

在早期,我们都是通过原生的JDBC来操作数据库的,而这种方式存在很多问题。

我们先来看一个例子:

原生JDBC操作方式

问题有哪些呢? 第一,在创建数据库连接这块,程序是需要时创建,用完后关闭。如果频繁的创建、关闭数据库连接,显然存在问题。当然,我们可以通过数据库连接池来处理这个问题。 第二,硬编码的地方太多了。比如,数据库连接相关的一些信息,SQL相关的一些信息。当然,我们可以通过使用配置文件,来避免这个问题。 第三,实质上,我们编写JDBC是有步骤可循的,比如,我们得先得到数据库连接对象,得有SQL,有输入参数,设置参数,去执行SQL,然后遍历结果集将数据库SQL执行的结果对象转化为JAVA对象,然后再去业务处理,最后释放资源。那么这个过程,实际上是个模板,能不能抽离出来,更好的去完成这个过程呢? 比如,Hibernate,这个纯粹的ORM(对象关系映射)框架,让程序员以面向对象的方式来完成数据库的操作,功能很强大,SQL都帮我们自动生成了,但是这也带来了一些其他问题,比如门槛较高,有时候我们想编写SQL,修改SQL,优化SQL都费劲,在互联网项目快速迭代开发中,太过笨重了! 基于这些因素,出现了iBatis,并发展为今天的MyBatis,作为Apache的顶级项目,目前已经托管到github下。

MyBatis框架的架构

上面我们说了一些JDBC的缺点,而MyBatis是避免了这些问题的。如果让我们来实现MyBatis的话,我们会怎么想呢? 第一,应该存在一个配置文件A,可以将数据库的连接信息,事务信息等放入其中; 第二,应该提供一个配置文件B,可以让程序员编写SQL,重点需要解决的是如何给SQL传递参数,以及如何将结果映射为JAVA对象; 第三,应该提供API可以执行文件B中的SQL

基于上面的分析,我们来看一下MyBatis的架构:

MyBatis的架构

这里,我们先简单了解些概念: SqlSessionFactory用于创建SqlSession,SqlSession即操作DB的接口,其内部借助Executor执行器完成对数据库的操作。 全局配置文件,就是图中的SqlMapConfig.xml;SQL文件即是Mapper.xml文件。 对于MappedStatement而言,会完成输入映射以及输出映射。

Quick Start

这里先写个简单的DEMO带大家初步了解下。

POM依赖:

pom.xml

MyBatis的全局配置文件:

SqlMapConfig.xml

需要注意下: 第一,我们把MySQL的一些连接信息放入到db.properties中,使用<properties>标签加载属性文件,并通过${XXX}的方式引用。 第二,要知道现在的日志框架有很多,这里使用<settings>设置下日志使用LOG4J实现。 第三,我们说SQL结果集要完成到JAVA对象的映射,那么根据反射的原理,我们都能猜到必须要提供带包路径的全限定名称,那么为了简化,提供<typeAliases>标签进行别名映射处理。提供了2种方式,一个是单个的类型别名映射,一个是基于包扫描的批量映射。当然批量映射的别名就是类名。 第四,需要<mappers>标签加载SQL文件。同上面一样,也提供了基于包扫描的批量加载。

log4j.properties:

log4j.properties

在开发阶段,显然,我们希望MyBatis能够为我们打印SQL日志,方便调试,排查问题。

SQL配置:

Student.xml

需要关注下: 第一,namespace,顾名思义,命名空间,其实是想隔离SQL,不过到了MyBatis和Spring结合使用时,具有特殊的意义。这里暂且使用全限定类名。 第二,<select>等SQL Command标签需要一个ID,还需要输入参数parameterType,输出参数映射resultType等。其实这些在MyBatis的底层封装成了一个MappedStatement对象。当然定位这个对象,需要namespace.id的方式。 第三,${value} VS #{xxx} 其实2者,都可以接受JAVA简单类型,如int,也可以接受POJO,Map等复杂类型。如果是JAVA简单类型,那么$的方式必须是${value},而#{}可以随意,是因为在这种情况下,$会通过反射getValue()的方式取值。如果是POJO等复杂类型,2者其实都可以通过OGNL表达式取到,只不过#会额外的进行JAVA类型到数据库类型的转换,而$没有类型处理过程,它直接拼接。也就是说#会使用预编译成?,而$将在SQL编译阶段就采取替换操作,可能带来SQL注入的问题。所以在实际开发中,我们当然优先采用#的方式取值。

测试程序:

Test

测试程序,并没有太多可以说的,关注2点即可: 第一,selectOne VS selectList 显然,我们需要清楚的知道,SQL返回的结果集是一条记录,还是多条记录,如果使用selectOne那么必须最多返回一条记录。那么返回多条记录与返回一条记录的时候,resultType有变化么?(其实是不变的。) 第二,SqlSession SqlSessionFactoryBuilder -> SqlSessionFactory -> SqlSession 我们重点关注的是SqlSession,它其实是一个interface,定义了很多操作数据库的接口,而且extends Closeable,很明确是需要close的。 它的实现类DefaultSqlSession中有一些数据域(比如说autoCommit,在默认情况下是不开启自动提交的),而且方法也并不是Synchronized,这说明SqlSession并不是线程安全的,因此我们应该是局部使用SqlSession,使用完毕后close掉。

Mapper代理开发

其实,除了Mapper代理开发外,还有一种原始Dao开发的方式。原始Dao开发方式的思路大致是这样的: 第一,我们提供Dao接口,有增、删、改、查的方法。 第二,我们提供Dao的实现类,在实现类中,我们利用Spring注入SqlSessionFactory,然后在各个方法中得到SqlSession,进行操作后,关闭SqlSession即可。 这种方式,重复的代码太多,已经OUT了,目前使用最多的就是Mapper代理开发。

提供Mapper.java接口:

Mapper接口

提供与之对应的Mapper.xml文件:

Mapper.xml

在全局配置文件中加载Mapper.xml:

加载mapper.xml配置

测试代码示例:

调用方式

从这里,你应该可以看出Mapper的开发应该遵循一些规范,这样MyBatis才可以自动帮助我们生成XXXMapper类的代理实现类。(说白了,这些规范,就是为了利用反射) 第一,保证XXXMapper.xml中的namespace同XXXMapper.java的全限定名称一致 第二,保证XXXMapper.xml中的Statement的ID同XXXMapper.java的方法名称一致 第三,保证XXXMapper.xml中的Statement的输入参数的类型(parameterType)、输出参数的类型(resultType)同XXXMapper.java的保持一致 从这里,你大致可以了解到Mapper代理开发,程序员主要关注的就是Mapper.java以及Mapper.xml的生成,可以说极大的简化了工作量!

关于自增主键返回

很多时候,我们面临这样的需求,A表的字段ID是主键,而且是auto_increment自动增长的;我们完成A表的插入后,希望得到主键,以便后续的操作,比如另外一个表B,和表A存在主外键关系。 MyBatis当然早就替我们想好了,只需要稍微配置下,就可以将MySQL自动生成的主键取出设置到对应的JAVA对象的属性上。

看一个例子:

自动获取主键设置

特别注意keyProperty是表示将获取到的自动增长的值设置到哪个Field域上。

关于动态SQL

我们知道,在JSP中,可以使用JSTL标签开发;而动态SQL就是类似于JSTL的一组标签,可以帮助我们灵活的生成SQL,比如实现判断,遍历数组/集合,SQL片段的复用等。值得关注的是,有些标签还挺智能,比如<where>还可以替你去掉第一个and..... 本篇博客并不会说明各个标签的使用方式,这样的例子,网上很多,大家可以参考。一句话,在开发阶段,我们只需要让MyBatis打印SQL,我们就能明白,我们的动态SQL是不是使用对了!

到这里,本篇博客就准备结束了,下一篇博客将会为大家介绍MyBatis的一些高级开发知识~

See U next time~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.06.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 没有MyBatis之前
  • MyBatis框架的架构
  • Quick Start
  • Mapper代理开发
  • 关于自增主键返回
  • 关于动态SQL
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档