Mybatis的相关知识

Mybatis

1.Mybatis概述

1
2
3
Mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花精力去处理加载驱动,创建连接,创建statement等繁杂的过程
Mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由Mybatis框架执行sql并将结果映射为java对象并返回。
采用ORM思想解决了实体和数据库映射的问题,对jdbc进行了封装,屏蔽jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

2.搭建Mybatis开发环境

2.1创建Maven工程

1
2
3
4
创建 mybatis01 的工程,工程信息如下:
Groupid:com.holicCode
ArtifactId:mybatis01
Packing:jar

2.2添加Mybatis3.4.5的坐标

在pom.xml文件中添加Mybatis3.4.5的坐标,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>

2.3编写必要代码(实体类和持久层接口)

2.4编写SqlMapConfig.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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>
<!-- 配置 mybatis 的环境 -->
<environments default="mysql">
<!-- 配置 mysql 的环境 -->
<environment id="mysql">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的信息:用的是数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/student"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 告知 mybatis 映射配置的位置 -->
<mappers>
<mapper resource="com/holicCode/dao/IUserDao.xml"/>
</mappers>
</configuration>

2.5编写映射配置文件

2.6编写测试类

3.Mybatis中用到的设计模式

1
2
3
工厂模式(SqlSessionFactory)
代理模式(MapperProxyFactory)
构建者模式(SqlSessionFactoryBuilder)

4.Mybatis与JDBC编程的比较

1
2
3
4
5
6
7
8
9
10
11
12
1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:
在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。
解决:
将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
3.向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。
解决:
Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。
4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对象解析比较方便。
解决:
Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的resultType 定义输出结果的类型。

5.当编写的实体类属性名和数据库表的列名不一致时

5.1出现的问题

1
2
查询出来的结果会都为null
有时有可能会出现某一列有值的情况,这是因为MySQL在Windows系统中不区分大小写!

5.2解决方案一

1
2
修改映射配置文件
给映射配置文件的SQL语句中的列名起别名(该方法当我们查询很多事,都使用的话写起来很麻烦)

5.3解决方案二

​ resultMap结果类型

1
2
resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。
在 select 标签中使用 resultMap 属性指定引用即可。同时 resultMap 可以实现将查询结果映射为复杂类型的 pojo,比如在查询结果映射对象中包括 pojo 和 list 实现一对一查询和一对多查询。

6.Mybatis连接池

1
Mybatis连接池与web中的连接池不同,Mybatis中的连接池使用的自己的连接池技术,在Mybatis的SqlMapConfig.xml配置文件中,通过<dataSource type="pooled">来实现Mybatis中连接池的配置。

6.1Mybatis连接池的分类

1
2
3
UNPOOLED		不使用连接池的数据源
POOLED 使用连接池的数据源(我们一般使用的数据源)
JNDI 使用JNDI实现的数据源
1
相应地,MyBatis 内部分别定义了实现了 java.sql.DataSource 接口的 UnpooledDataSource,PooledDataSource 类来表示 UNPOOLED、POOLED 类型的数据源。

6.2Mybatis中数据源的配置

1
2
3
4
5
6
7
8
9
10
11
12
数据源配置就是在 SqlMapConfig.xml 文件中,具体配置如下:
<!-- 配置数据源(连接池)信息 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
MyBatis 在初始化时,根据<dataSource>的 type 属性来创建相应类型的的数据源 DataSource,即:
type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

7.Mybatis中事务控制

7.3Mybatis中事务提交方式

1
Mybatis中事务的提交方式,本质上就是调用JDBC的setAutoComment()来实现事务控制,默认情况下setAutoComment()的参数为false,所以我们要手动使用SqlSession.commit()来提交事务

7.4Mybatis自动提交事务的设置

1
2
在创建SqlSession工厂对象时,传入true
SqlSession session = factory.openSession(true);

8.Mybatis中的动态SQL语句

1
2
3
4
主要就是使用Mybatis中提供的动态SQL语句标签
<if>
<where>
<foreach>

9.Mybatis延迟加载策略

9.1何为延迟加载

1
2
3
延迟加载:就是需要用到数据是才进行加载,不需要用到数据时就不加载数据。也称为懒加载
好处:先从单表查询,需要时再关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快
坏处:因为只有当需要用到数据时,才会进行数据库查询,这样大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体检下降。

9.2开启Mybatis的延迟加载策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1.需要再Mybatis的配置文件SqlMapConfig.xml文件中添加延迟加载的配置

<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

2.使用Collection实现延迟加载

<!-- collection 是用于建立一对多中集合属性的对应关系
ofType 用于指定集合元素的数据类型
select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称)
column 是用于指定使用哪个字段的值作为条件查询
-->
<collection property="accounts"
ofType="account"
select=""
column="">
</collection>


<collection>标签:
主要用于加载关联的集合对象
select 属性:
用于指定查询 account 列表的 sql 语句,所以填写的是该 sql 映射的 id
column 属性:
用于指定 select 属性的 sql 语句的参数来源,上面的参数来自于 user 的 id 列,所以就写成 id 这一个字段名了

10.Mybatis缓存

Mybatis通过缓存策略来减少数据库的查询次数,从而提高性能

10.1Mybatis一级缓存

1
2
一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。
一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

10.2Mybatis二级缓存

1
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

10.2.1二级缓存的开启与关闭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
第一步:在SqlMapConfig.xml文件开启二级缓存
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为false 代表不开启二级缓存。

第二步:配置相关的Mapper映射文件
<cache>标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值。
<?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 namespace="com.holicCode.dao.IUserDao">
<!-- 开启二级缓存的支持 -->
<cache></cache>
</mapper>

第三部:配置statement上面的useCache属性
<!-- 根据 id 查询 -->
<select id="findById" resultType="user" parameterType="int" useCache="true">
select * from user where id = #{uid}
</select>
将 UserDao.xml 映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。
注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存

10.2.2基于注解的二级缓存

1
2
3
4
5
6
7
8
9
10
1.在SqlMapConfig中开启二级缓存支持
<!-- 配置二级缓存 -->
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>

2.在持久层接口中使用注解配置二级缓存
@CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存
public interface IUserDao {}

10.2.3二级缓存的注意事项

1
当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,这种就可以使用序列化方式来保存对象。

11.Mybatis的注解开发

11.1Mybatis常用注解说明

1
2
3
4
5
6
7
8
9
10
11
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
Thanks
0%