Mybatis总结
一、入门
1. 构架的概念和Mybatis的概念
2. Mybatis的快速入门
- 创建Maven的Java项目,配置好坐标,引入Mybatis的依赖:数据库驱动,mybatis,log4j,junit
- 准备JavaBean。最好属性名和字段一致
- 创建映射器接口(只要接口,不要实现类)
- 创建映射配置文件:和映射器接口同名、同位置
- 创建Mybatis的核心配置文件:主要配置数据库连接信息,和映射器的配置
- 引入log4j.properties显示日志信息
3. Mybatis自定义
- Mybatis使用的设计模式
- 构造者模式:SqlSessionFactoryBuilder的build方法,构造一个工厂对象
- 根据参数、配置文件,定制生产一个对象。目的是隐藏复杂的构造过程
- 工厂模式:SqlSessionFactory工厂生产一个SqlSession对象
- 用来代理new对象的一种方式,降低程序之间的耦合性(耦合性不能完全消除)
- 代理模式:通过SqlSession的getMapper方法,得到映射器接口的代理对象
- 通过代理对象,间接调用目标对象。
- 通过给接口创建代理对象,让代理对象实现功能。
- 职责明确:在不影响目标对象的代码的情况下,增加它们的功能–由代理对象实现增加的功能
- 构造者模式:SqlSessionFactoryBuilder的build方法,构造一个工厂对象
- 自定义Mybatis
- 读取配置文件,封装成Configuration对象
- 构造者里得到Configuration对象,传递给工厂对象;工厂对象再把Configuration对象传递给SqlSession对象
- SqlSession使用Configuration对象。通过创建代理,让代理对象根据Configuration里的信息,操作数据库
二、应用-CURD
1. 映射器接口代理对象的方式,实现CURD
1.1 开发步骤
1. 在映射器接口里增加方法
2. 在映射配置文件里增加配置信息:sql,parameterType,resultType
1.2 参数parameterType的设置
- 简单类型:基本数据类型和String。 int, boolean, double, string…
- POJO类型:JavaBean。在SQL语句里需要使用
#{}
或者${value}
通过OGNL表达式,获取JavaBean里属性值 - POJO包装类:JavaBean嵌套JavaBean。使用OGNL表达式的语法获取
#{}
和${}
的区别:#${}
是预编译对象的占位符方式;有效的防止SQL注入;会自动转换Java类型和JDBC类型;在{}里可以写任意的OGNL表达式内容${value}
:是SQL拼接的方式;不能防止SQL注入;不会转换JDBC类型和Java类型;在{}里只能写value固定名称
1.3 结果集的封装
- 使用resultType属性进行封装
- 简单类型
- POJO类型
- 使用resultMap进行封装—通常用于处理JavaBean属性名和字段名不一致的情况
- 子标签id:用来封装主键对应的属性值/字段
- 子标签result:用来封装非主键对应的属性/字段
2. 映射器接口实现类的方式,实现CURD
2.1 涉及的API
- SqlSession:面向用户的一个接口,提供了一系列操作数据库的方法
- SqlSession对象是线程不安全的。 使用要求:随用随取,用完就关, 一定要关
- selectList(String statement, Object param):查询多条数据,封装集合
- selectOne(String statement, Object param):查询一条数据封装JavaBean;查询一个数据
- insert(String statement, Object param):执行insert语句
- update(String statement, Object param):执行update语句
- delete(String statement, Object param):执行delete语句
- SqlSessionFactory:用来生产SqlSession对象的。一个应用里只要有一个工厂对象,通常使用单例模式进行管理。
- SqlSessionFactoryBuilder:相当于一个工具类,当这个构造者对象构造出来SqlSessionFactory之后,这个对象就可以抛弃了
2.2 实现类的开发
public class UserDaoImpl implements IUserDao{
private SqlSessionFactory factory;
public UserDaoImpl(SqlSesssionFactory factory){
this.factory = factory;
}
public List<User> queryAll(){
SqlSession session = factory.openSession();
List<User> users = session.selectList("com.viking.dao.IUserDao.queryAll");
session.commit();//如果执行了DML语句,一定要先commit()然后再close()
session.close();
return users;
}
}
3. Mybatis的核心配置文件
3.1 properties属性
- 通常用于引入外部的properties文件:
<properties resource="jdbc.properties"></properties>
<properties url="http://host:port/context/servlet"></properties>
<properteis>
<property name="driver" value="com.mysql.jdbc.Driver"></property>
</properteis>
-
优先级:外部文件的优先级高于property标签配置
加载顺序是:Mybatis先加载property标签,然后再加载外部properties;覆盖已经存在的同名属性
3.2 typeAliases类型别名
-
作用:减少映射配置文件里的冗余代码。别名不区分大小写
-
Mybatis提供了一些别名
-
自定义类型别名
<typeAliases> <typeAlias type="com.viking.bean.User" alias="user"></typeAlias> </typeAliases> <typeAliases> <package name="com.viking.bean"></package> </typeAliases>
3.3 mappers映射器
-
<mapper resource=""></mapper>
<mappers> <mapper resource="映射配置文件xml的路径"></mapper> </mappers>
不要求xml文件的名称、位置 和 映射器接口的名称、位置相同
-
<mapper class=""></mapper>
<mappers> <mapper class="com.viking.dao.IUserDao"></mapper> </mappers>
要求xml的文件名称、位置 和映射器接口的名称位置相同
支持XML开发和注解开发
-
<package></package>
<mappers> <package name="com.viking.dao"></package> </mappers>
要求xml的文件名称、位置 和映射器接口的名称位置相同
支持XML开发和注解开发
三、深入
1. 数据源了解
- UNPOOLED:没有使用连接池技术的数据源
- POOLED:使用了连接池技术的数据源。连接池的技术是Mybatis自己开发
- JNDI:调用服务器软件里配置的数据源,得到数据源对象
2. 事务管理了解
- Mybatis的默认事务管理机制:执行完成之后,需要手动提交事务
- Mybatis使用自动提交事务方式:factory.openSession(true)
3. SQL深入
3.1 动态SQL的拼接
-
if标签:用来判断拼接
<select id="search" parameterType="queryVo" resultType="user"> select * from user where 1=1 <if test="user.username != null"> and username like #{user.username} </if> <if test="user.sex != null"> and username = #{user.sex} </if> </select>
-
where标签:用来代替where 1=1
<select id="search" parameterType="queryVo" resultType="user"> select * from user <where> <if test="user.username != null"> and username like #{user.username} </if> <if test="user.sex != null"> and username = #{user.sex} </if> </where> </select>
-
foreach标签:用来循环遍历一个集合,把集合里的数据拼接SQL语句
<select id="findByIds" parameterType="queryVo" resultType="user"> select * from user where 1=1 <foreach collection="ids" open=" and id in (" item="id" separator="," close=")"> #{id} </foreach> </select>
3.2 sql片段
<!-- 定义sql片段 -->
<sql id="selectUser">select * from user</sql>
<!-- 引用sql片段 -->
<include refid="selectUser"></include>
4. 多表关联查询
4.1 一对一(多对一)查询
- JavaBean里要有关联的JavaBean的引用。比如:Account里要有User的引用
- 准备好多表关联查询的SQL语句,要保证SQL语句的结果中没有重名的列
- 在映射器接口里定义方法
- 在映射配置文件里配置信息
- 要使用resultMap封装结果
- 要使用association标签封装引用的JavaBean对象的数据
4.2 一对多(多对多)查询
- JavaBean里要有关联的JavaBean的集合。比如:User里要有Account的集合
- 准备好多表关联查询的SQL语句,要保证SQL语句的结果集中没有重名的列
- 在映射器接口里定义方法
- 在映射配置文件里配置信息
- 要使用resultMap封装结果
- 要使用collection封装关联的JavaBean的集合数据
四、其它
1. 延迟加载策略
用于多表关联查询里的一种策略。按需加载。
注意事项:SQL语句需要拆分成两个单表查询语句,不要再写多表关联查询的SQL了
1.1 一对一的延迟加载
-
JavaBean里要有另外一个JavaBean的引用。比如:Account里有User的引用
-
准备好关联查询的方法备用。比如:准备好IUserDao.findUserById方法
-
编写延迟加载查询的代码:
- 定义映射器接口里的方法。比如:IAccountDao.findAccountById()
- 在映射配置文件里配置信息
- 必须使用resultMap封装结果集
- 封装关联的JavaBean属性时,要使用标签association
- association标签增加column和select属性
- select:调用准备好的关联查询的方法IUserDao.findUserById
- column:调用关联查询的方法时,需要的参数值从哪个列里取
-
修改Mybatis的核心配置文件,开启延迟加载的开关
<settings> <!--开启延迟加载的全局开关--> <setting name="lazyLoadingEnabled" value="true"/> <!--关闭积极加载,使用按需加载--> <setting name="aggressiveLazyLoading" value="false"/> </settings>
1.2 一对多的延迟加载
-
JavaBean里要有另外一个JavaBean的集合。比如:User里有Account的集合
-
准备好关联查询的方法备用。比如:准备好IAccountDao.findAccountsByUid
-
编写延迟加载查询的代码:
- 定义映射器接口里的方法。比如:IUserDao.findUserById
- 在映射配置文件里配置信息
- 必须使用resultMap封装结果集
- 封装关联的JavaBean集合时,要使用标签collection
- collection标签增加column和select属性
- select:调用准备好的关联查询的方法IAccountDao.findAccountsByUid
- column:调用关联查询的方法时,需要的参数值从哪个列里取
-
修改Mybatis的核心配置文件,开启延迟加载的开关
<settings> <!--开启延迟加载的全局开关--> <setting name="lazyLoadingEnabled" value="true"/> <!--关闭积极加载,使用按需加载--> <setting name="aggressiveLazyLoading" value="false"/> </settings>
2. Mybatis的缓存
2.1 Mybatis的一级缓存
- 是SqlSession对象的提供的缓存
- 当使用SqlSession对象查询数据,这个数据会被保存到SqlSession的缓存里。下次再查询相同 的数据,会从缓存里获取,而不再查询数据库
- 当执行了SqlSession对象的添加、修改、删除、commit()、close()、clearCache()方法时,缓存会被清空
2.2 Mybatis的二级缓存
-
是SqlSessionFactory对象提供的缓存。
-
由同一个工厂对象生产的多个SqlSession,可以共享缓存。
-
二级缓存默认没有开启,需要开启后才可以使用
-
修改Mybatis的核心配置文件,开启二级缓存(默认是true,可以省略不配置)
<settings> <!--全局的开启二级缓存。因为是默认开启状态的,所以这一步可以省略不写--> <setting name="cacheEnabled" value="true"/> </settings>
-
修改映射配置文件,哪个映射器接口要使用二级缓存,就给哪个映射配置文件开启缓存
<mapper namespace="com.viking.dao.IUserDao"> <!--当前映射器要使用二级缓存--> <cache/> <!--给某个statement增加属性:userCache="true",表示这个方法要使用二级缓存--> <select id="findById" parameterType="int" resultType="user" useCache="true"> SELECT * FROM USER WHERE id = #{id} </select> </mapper>
-
修改映射配置文件里statement的,增加
useCache="true"
。加在了哪个方法上,哪个方法就可以使用二级缓存。
-
3. Mybatis的注解开发
- @Select:相当于select标签
- @Insert:相当于insert标签
- @SelectKey:相当于selectKey标签,用于添加数据之后,查询得到最新的主键值
- @Update:相当于update标签
- @Delete:相当于delete标签
- @Results:相当于resultMap标签
- @Result:相当于resultMap里的result标签,是和@Results配合使用的
- @One:相当于association标签,用于一对一关联查询时,封装关联的JavaBean对象
- @Many:相当于collection标签,用于一对多关联查询时,封装关联的JavaBean集合