目录
一.初识MyBatis
MyBatis是当前主流的java持久层框架之一,因其性能优异,具有高度的灵活性且可优化性和易于维护等特点,是当下大型互联网项目首选的持久层框架。
1.MyBatis概述
MyBatis是一个支持普通SQL查询、存储过程以及高级映射的持久层框架. MyBatis框架也被称之为ORM(Object/ Relational Mapping,即对象关系映射)框架。使用ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的方式来操作持久化对象(Persisent Object,PO)。
(1).什么是MyBatis
当前的ORM框架产品有很多,常见的ORM框架有Hibernate和MyBatis。
①.Hibernate:一个全表映射的框架。通常开发者只需定义好持久化对象到数据库表的映射关系,就可以通过 Hibernate提供的方法完成持久层操作。开发者并不需要熟练地掌握SQL语句的编写,Hibernate会根据制定的存储逻辑自动生成对应的SQL,并调用JDBC接口来执行,所以其开发效率会高于MyBatis。然而 Hibernate自身存在着一些缺点,例如它在多表关联时,对SQL查询的支持较差;更新数据时,需要发送所有字段;不支持存储过程;不能通过优化SQL来优化性能等。这些问题导致其只适合在场景不太复杂且对性能要求不高的项目中使用。
②.MyBatis:一个半自动映射的框架。这里所谓的“半自动”是相对于Hibernate全表映射而言的,MyBatis需要手动匹配提供POJO、SQL和映射关系,而Hibernate只需提供POJO和映射关系即可。与Hibernate相比,虽然使用MyBatis手动编写SQL要比使用Hibernate的工作量大,但MyBatis可以配置动态SQL并优化SQL,可以通过配置决定SQL的映射规则,它还支持存储过程等。对于一些复杂的和需要优化性能的项目来说,显然使用MyBatis更加合适。
(2).MyBatis的下载和使用
https://github.com/mybatis/mybatis-3/releases
可以通过网址下载得到。下载并解压mybatis-3.5.4.zip压缩包,会得到一个名为mybatis-3.5.4的文件夹,里面有核心包mybatis-3.5.4.jar和一个lib文件夹(里面有MyBatis的依赖包)。
使用 MyBatis框架非常简单,只需在应用程序中引入MyBatis的核心包mybatis-3.5.4.jar和lib目录中的依赖包即可。
注意:如果底层采用的是MySQL数据库,还需要将MySQL数据库的驱动JAR包添加到应用程序的类路径中;如果采用其他类型的数据库,同样需要将对应类型的数据库驱动包添加到应用程序的类路径中。
2.MyBatis入门程序
平时我们都用JDBC访问数据库,除了需要自己写SQL之外,还必须操作Connection, Statement, ResultSet 这些其实只是手段的辅助类。 不仅如此,访问不同的表,还会写很多雷同的代码,显得繁琐和枯燥。
那么用了Mybatis之后,只需要自己提供SQL语句,其他的工作,诸如建立连接,Statement, JDBC相关异常处理等等都交给Mybatis去做了,那些重复性的工作Mybatis也给做掉了,我们只需要关注在增删改查等操作层面上,而把技术细节都封装在了我们看不见的地方。
MyBatis入门级程序(增删改查)_无忧#的博客-CSDN博客
二.MyBatis的核心配置
MyBatis的核心配置主要有:
- Mybatis核心对象
- MyBatis配置文件
- MyBatis映射文件
1.MyBatis核心对象
通过入门程序发现,MyBatis有两个核心对象:SqlSessionFactory和SqlSession。
(1).SqlSessionFactory
SqlSessionFactory是单个数据库映射关系经过编译后的内存镜像,用于创建 SqlSession。 SqlSessionFactory对象的实例通过SqlSessionFactoryBuilder对象来构建,它通过XML配置文件或一个预先定义好的 Configuration实例构建出SqlSessionFactory的实例。
通过XML配置文件构建出SqlSessionFactory实例的实现代码如下:
//读取配置文件
InputStream inputStream = Resources.getResourceAsStream("配置文件位置");
//根据配置文件构建 sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
(2).SqlSession
SqlSession是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作。SqlSession对象包含了数据库中所有执行SQL操作的方法,它底层封装了JDBC连接,所以可以直接使用其实例来执行已映射的SQL语句。
使用完 SqISession对象之后,要及时将它关闭,通常可以将其放在finally块中关闭。
SqlSession对象常用方法有22个。
参考:mybatis框架:SqlSession 的常用方法_BTBIG@Mr. Chen的博客-CSDN博客_sqlsession方法
注意:为了简化开发,可以将构建SqlSessionFactory对象、创建 SqlSession对象等重复性代码封装到一个工具类中,然后通过工具类来创建 SqlSession。
2.MyBatis配置文件
在MyBatis框架的核心配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在<contiguration>元素内配置。例如:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 属性 -->
<properties></properties>
<!-- 设置 -->
<settings></settings>
<!-- 类型名称 -->
<typeAliases></typeAliases>
<!-- 类型处理器 -->
<typeHandlers></typeHandlers>
<!-- 对象工厂 -->
<objectFactory type=""></objectFactory>
<!-- 插件 -->
<plugins></plugins>
<!-- 配置环境 -->
<environments >
<!-- 环境变量 -->
<environment >
<!-- 事务管理器 -->
<transactionManager />
<!-- 数据源 -->
<dataSource />
</environment>
</environments>
<!-- 数据库厂商标识 -->
<databaseIdProvider type=""></databaseIdProvider>
<!-- 映射器 -->
<mappers></mappers>
</configuration>
<properties>是一个配置属性的元素,它通过外部配置来动态替换内部定义的属性。例如,数据库的连接等属性,具体方式如下:
(1)在项目的src目录下,创建一个名称为 db.properties的配置文件;
(2)在MyBatis配置文件mybatis-config.xml中配置<properties/>属性;
(3)修改配置文件中数据库连接的信息
<settings>元素主要用于改变MyBatis运行时的行为,例如开启二级缓存、开启延迟加载等。
<!--设置-->
<settings>
<setting name="cacheEnabled" value="true" />
<setting name="lazyLoadingEnabled" value="true" />
<setting name="multipleResultsetsEnable d" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
……
</settings>
<typeAliases>元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余。使用< typeAliases>元素配置别名的方法如下。
<!--定义别名-->
<typeAliases>
<typeAlias alias="user" type="com. ssm.po.User"/>
</typeAliases>
注意:上述方式的别名只适用于没有使用注解的情况。如果在程序中使用了注解,则别名为其注解的值,具体如下。
@Alias(value ="user")
public class User {
//user的属性和方法
……
}
MyBatis在预处理语句(PreparedStatement)中设置一个参数或者从结果集(Resultset)中取出一个值时,都会用其框架内部注册了的typeHandler(类型处理器)进行相关处理。typeHandler的作用就是将预处理语句中传入的参数从javaType(Java类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。
<typeHandler>元素就是用于在配置文件中注册自定义的类型处理器的。它的使用方式有两种,具体如下。
1.注册一个类的类型处理器
<typeHandlers>
<!--以单个类的形式配置-->
<typeHandler handler="com.ssm.type.UsertypeHandlerl" />
</typeHandlers>
2.注册一个包中所有的类型处理器
<typeHandlers>
<!-注册一个包中所有的 typeHandier,系统在启动时会自动扫描包下的所有文件-->
<package name="com.ssm.type" />
</typeHandlers>
<environments>元素用于在配置文件中对环境进行配置。MyBatis的环境配置实际上就是数据源的配置,可以通过<environments>元素配置多种数据源,即配置多种数据库。
对于数据源的配置,MyBatis框架提供了UNPOOLED、POOLED和JNDI三种数据源类型。
1. UNPOOLED
配置此数据源类型后,在每次被请求时会打开和关闭连接。它对没有性能要求的简单应用程一个很好的选择。
2. POOLED
此数据源利用“池”的概念将JDBC连接对象组织起来,避免了在创建新的连接实例时所需要初始化和认证的时间。这种方式使得并发Web应用可以快速地响应请求,是当前流行的处理方式。
3. JNDI
此数据源可以在EJB或应用服务器等容器中使用。容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。
在配置文件中,<mappers>元素用于指定MyBatis映射文件的位置,一般可以使用以下4种方法引入映射器文件,具体如下所示。
1.使用类路径引入
<mappers>
<mapper resource="com/ssm/mapper/UserMapper.xmI"/>
</mappers>
2.使用本地文件路径引入
<mappers>
<mapper url=file: ///D:/com/ssm/mapper/UserMapper.xml"/>
</mappers>
3.使用接口类引入
<mappers>
<mapper class="com. ssm.mapper.UserMapper"/>
</mappers>
4.使用包名引入
<mappers>
<package name=""com. ssm. mapper"/>
</mappers>
3.MyBatis映射文件
在映射文件中,<mapper>元素是映射文件的根本元素,其他元素都是他的子元素。映射文件中的子元素主要如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper >
<!-- 映射查询语句,可以自定义参数,返回结果集等 -->
<select />
<!-- 映射插入语句,执行后返回一个整数,代表插入的条数 -->
<insert/>
<!-- 映射更新语句,执行后返回一个整数,代表更新的条数 -->
<delete/>
<!-- 映射删除语句,执行后返回一个整数,代表删除的条数 -->
<update/>
<!-- 用于定义一部分SQL,然后可被其他语句引用此SQL -->
<sql />
<!-- 给命名空间的缓存配置 -->
<cache/>
<!-- 其他命名空间缓存配置的引用 -->
<cache-ref />
<!-- 用于描述如何从数据库结果集中加载对象 -->
<resultMap />
</mapper>
<select>元素用于映射查询语句,它用于从数据库中读取出数据,并组装数据给业务开发人员。
<select id="findUserById" parameterType="Integer" resultType="com.ssm.po.User">
select * from t_user where id=#{id}
</select>
上述语句中的唯一标识为findUserById,它接收一个 Integer类型的参数,并返回一个User类型的对象。
<insert>元素用于映射插入语句,在执行完元素中定义的SQL语句后,会返回一个表示插入记录数的整数。<insert>元素的配置示例如下。
<insert id="addUser" parameterType="com.ssm.po.User" flushCache="true"
statementType="PREPARED" keyProperty="id" keyColumn=""
useGeneratedKeys="" timeout="20">
insert into t_user(username,jobs,phone)values(#{username},#{jobs},#{phone})
</insert>
< update>和<delete>元素的使用比较简单,它们的属性配置也基本相同:
<update
id="updateUser"
parameterType="com.ssm.po.User"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteUser"
parameterType="com.ssm.po.User"
flushCache="true"
statementType="PREPARED"
timeout="20">
<sql>元素的作用就是定义可重用的SQL代码片段,然后在其他语句中引用这一代码片段。
例如,定义一个包含id、username、jobs和 phone字段的代码片段如下。
<sql id="user Columns">id,username,Jobs, phone</sql>
<resultMap>元素表示结果映射集,它的主要作是定义映射规则、级联更新以及定义类型转化器等。
<resultMap>元素中包含了一些子元素,它的元素结构如下所示。
<!-- resultMap的元素结构-->
<resultMap type="" id="">
<constructor> <!--类在实例化时,用来注入结果到构造方法中-->
<idArg /> <!--ID参数;标记结果作为ID-->
<arg /> <!--注入到构造方法的一个普通结果-->
</constructor>
<id /> <!--用于表示哪个列是主键-->
<result /> <!--注入到字段或Javabean属性的普通结果-->
<association property="" /> <!--用于一对一关联-->
<collection property="" /> <!--用于一对多关联-->
<discriminator javaType=""> <!--使用结果值来决定使用哪个结果映射-->
<case value="" /> <!--基于某些值的结果映射-->
</discriminator>
</resultMap>
三.动态SQL
MyBatis提供对SQL语句动态组装的功能,能很好的解决看发人员在使用JDBC或框架进行数据库开发时手动拼装SQL这一非常麻烦且痛苦的工作。动态SQL是MyBatis的强大特性之一,myBatis3采用了强大的基于OGNL的表达式来完成动态SQL。
- <if>:判断语句,用于单条件分支判断。
- <choose>(<when>,<otherwise>):用于多条件分支判断。
- <where>.<trim>.<set>:辅助元素,用于处理一些SQL拼装,特殊字符问题。
- <foreach>:循环语句,常用于in语句等列举条件中。
- <bind>:从OGNL表达式中创建一个变量,并将其绑定到上下文,常用于模糊查询的SQL中。
具体用法和例子参考:MyBatis使用动态SQL用法以及例题_无忧#的博客-CSDN博客
MyBatis的关联映射
在实际应用中,对数据库的操作会涉及多张表,这在面向对象中就涉及对象与对象之间的关联关系。针对多表之间的操作,MyBatis提供了关联映射,通过关联映射来处理与对象之间的关联联系。
1.关联关系概述
在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多。
一对一:在任意一方引入对方主键作为外键。
一对多:在“多”的一方,,添加“一”的一方的主键作为外键。
多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键。
2.MyBatis中的关联关系
(1).一对一
在现实生活中,一对一关联关系是十分常见的。例如,一个学生只有一本学生证,同时一本学生证也只对应一个学生。
<resultMap>元素中包含一个<association>子元素,MyBatis就是通过该元素来处理一对一关联关系的。
在<association>元素中,通常可以配置以下属性。
- property:指定映射到的实体类对象属性,与表字段一一对应。
- column:指定表中对应的字段。
- javaType:指定映射到实体对象属性的类型。
- select:指定引入嵌套查询的子SQL语句,用于关联映射中的嵌套查询。
- fetchType:指定在关联查询时是否启动延迟加载,有lazy和eager两个属性值,默认值为lazy。
注意:
MyBatis在映射文件中加载关联关系对象,主要通过两种方式:嵌套查询和嵌套结果。嵌套查询是指通过执行另一条SQL映射语句来返回预期的复杂类型;嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。
(2).一对多
在实际应用中,应用更多的关联关系是一对多(或多对一)。例如一个班级有多个学生,也即多个学生属性一个班级。班级与学生之间是一对多的关联关系,但如果从单个学生的角度出发,一个学生只能属于一个班级,即一对一的关联关系。
<resultMap>元素中,包含了一个<collection>子元素,MyBatis就是通过该元素来处理一对多关联关系的。
(3).多对多
在实际项目开发中,多对多的关联关系也是非常常见的。以学生和课程为例,一个学生可以选修多门课程,而一门课程又可以被多个学生选修,学生和课程就属于多对多的关联关系。