MyBatis基础
1. MyBatis开发dao
1. SqlSession的使用范围
(1)SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用,不需要使用单例模式进行管理
(2)SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理SqlSession
(3)SqlSession
面向用户的接口,提供了很多操作数据库的方法:
selectOne:返回单个对象
selectList:返回单个或多个对象
SqlSession是线程不安全的,在其实现类中除了有接口中的方法(操作数据库的方法),还有数据域属性
最佳的应用场合是在方法体中,定义成局部变量
2. 原始dao的开发方法
需要写dao接口和实现类,需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession
存在的问题:
dao接口实现类中存在大量的模板方法
调用SqlSession时将Statement的ID硬编码
3. Mapper代理方法
只需要写Mapper接口(相当于dao接口,需要遵循一些开发规范)和mapper.xml映射文件,这样MyBatis就可以自动生成Mapper接口实现类的代理对象
开发规范:
(1)在mapper.xml中namespace等于mapper接口地址
(2)mapper.java接口中的方法名和mapper.xml中statement的ID一致
(3)mapper.java接口中的方法输入参数类型和mapper.xml中的statement的patameterType指定的类型一致
(4)mapper.java接口中的方法返回值类型和mapper.xml中的statement的resultType指定的类型一致
代码:
(a)mapper.xml
<?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">
<!-- 对sql进行分类化管理,理解sql隔离
使用Mapper代理的方式进行开发,namespace=mapper接口的全路径名
-->
<mapper namespace="cn.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="cn.mybatis.entity.User">
SELECT * FROM USER WHERE id=#{id}
</select>
</mapper>
在SqlMapConfig.xml文件中加载映射文件
<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
(b)mapper.java
public interface UserMapper {
public User findUserById(int id);
}
(c)测试
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws IOException{
String resource = "SqlMapConfig.xml";
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(resource));
}
@Test
public void testFindUserById(){
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,MyBatis自动生成Mapper的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用UserMapper的方法
User user = userMapper.findUserById(10);
System.out.println(user);
}
}
2. SqlMapConfig
1. properties定义
<!--加载属性文件-->
<properties resource="db.properties">
<property name="" value="">
</properties>
注意:
MyBatis按照如下的顺序加载属性:
在properties元素体内定义的属性首先被读取
然后会读取properties元素中resource或url加载的属性,它会覆盖已读取的同名属性
最后读取parameterType传递的属性,它会覆盖已读取的同名属性
2. settings全局参数配置
Mybatis框架在运行时可以调整一些运行参数,比如:开启二级缓存、开启延迟加载
3. typeAliases(别名)
自定义别名
<typeAliases>
<!--针对单个别名定义-->
<typeAlias type="cn.mybatis.entity.User" alias="user">
<!--批量别名定义
指定包名,MyBatis自动扫描包中的pojo类,自动定义别名,别名就是类名
-->
<package name="cn.mybatis.entity">
</typeAliases>
4. 类型处理器
MyBatis中通过typeHandlers完成jdbc类型和java类型的转换
5. Mappers(Mapper的映射配置)
(1)加载单个映射文件
<mapper resource="mapper/UserMapper.xml">
(2)通过Mapper接口加载映射文件
规范:
Mapper接口名和mapper.xml映射文件名保持一致,且在一个目录
前提是:使用Mapper代理方法
<mapper class="cn.mybatis.mapper.UserMapper"/>
(3)批量加载包名
指定mapper接口的包名,MyBatis自动扫描包中的所有Mapper接口进行加载
<package name="cn.mybatis.mapper"/>
3. 输入映射
通过parameterType指定输入参数的类型,可以是简单类型、HashMap、pojo包装类型
4. 输出映射
(1)resultType
只有查询出来的列名和pojo的属性名一致,才可以映射成功
如果查询出来的列名和pojo的属性名全部不一致,则没有创建pojo对象
如果查询出来的列名和pojo的属性名有一个一致,则创建pojo对象
查询出来的结果集只有一行一列,可以使用简单类型进行输出映射
输入pojo对象活着pojo列表,在mapper.xml文件中resultType指定的类型是一样的,在mapper.java指定的方法的返回值类型不一样
(2)resultMap
完成高级输出结果映射
只有查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系
定义resultType
<!--
type:rsultMap最终映射的java对象,可使用别名、
id:对resultMap的唯一标示
-->
<resultMap type="user" id="userResultMap">
<!--
id:表示查询结果的唯一标示
column:表示查询出来的列名
property:type pojo的属性名
-->
<id co/>
<!--对普通名映射定义-->
<result/>
</rsultMap>
使用resultMap作为statemnet的输出映射类型
5. 动态SQL
Myatis的核心是对sql语句的灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装
(1) if判断
<where>
<if test="">
</if>
</where>
(2)sql片段
经验:基于单表定义sql片段,提高重用性,在sql片段中不包括where
<where>
<!--引入sql片段的ID-->
<include refid=""/>
</where>
(3)sql-foreach
向sql中传递了数组活着list,MyBatis使用foreach解析
<!--
collection:指定输入对象中的集合属性
item:每个遍历生成对象
open:
close:
separator:遍历的两个对象中需要拼接的串
-->
<foreach collection="" item="" open="AND (" close=")" separator="">
<!--每个遍历需要拼接的串-->
</foreach>