Mybatis
介绍及其环境搭建
一、数据持久化概念
数据持久化是将内存的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。
二、Mybatis框架及ORM
1、Mybatis框架简介
Mybatis是一个开源的数据持久层框架。它支持定制化 SQL、存储过程以及高级映射。Mybatis是一种半自动化的ORM实现。
2、ORM
ORM:对象关系映射,是一种数据持久化技术。
3、Mybatis的环境搭建以及使用
1、搭建开发环境
-
添加数据库和mybatis的jar包
-
创建Mybatis核心配置文件
(1)、常用元素:
properties 描述数据库连接的相关配置 settings 行为设置 environments 配置多套运行环境 mapper 具体制定SQL映射文件的路径 typeAliases 配置类型别名 <?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
- 创建持久化类POJO和SQL映射文件
(1)、pojo
符合JavaBean规范的实体类
(2)、常用元素
mapper namespace:用于区分不同的mapper,全局唯一 select id:该命名空间下唯一标识符,resultType:返回值类型,paramType:传入参数类型,resultMap:对外部的resultMap定义的引用,对应外部resultMap的id,表示返回结果映射到哪一个resultMap上。 cache 缓存 cache-rsf 从其他命名空间引用缓存配置 resultMap 用来描述数据库结果集和对象的对应关系 sql 可以重用的SQL块,也可以被其他语句引用 insert 映射插入语句,id:唯一标识符 update 映射修改语句,id:唯一标识符 selete 映射查询语句,id:唯一标识符 <?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="org.mybatis.example.BlogMapper"> <select id="selectBlog" resultType="Blog"> select * from Blog where id = #{id} </select> </mapper>
- 测试类
(1)、读取全局配置文件
String res="mybatis=config.xml"; //获取文件的输入流 InputStream is=Resources.getResourcesAsStream(res);
(2)、创建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
(3)、创建SqlSession对象
SqlSession session = sqlSessionFactory.openSession(); 接收=session.getMapper(对应接口名.class);
(4)、关闭SqlSession
session.close();
4、Mybatis核心对象
1、三个基本要素
-
核心接口和类
1.1 SqlSessionFactoryBuilder
(1)、SqlSessionFactoryBuilder负责构建SqlSessionFactory。
(2)、生命周期:用过即丢,,一旦创建了 SqlSessionFactory,就不再需要它了。
(3)、作用域:SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域。
1.2 SqlSessionFactory
(1)、创建SqlSession实例的工厂
(2)、作用域:Application
(3)、openSession():默认值false
true:开启事务控制
false:关闭事务控制
1.3、SqlSession
(1)、生命周期不是永久的,在每次访问数据库时都需要创建它,每个线程都有自己的SqlSession实例, SqlSession不能被共享,也不是线程安全的。
(2)、作用域:request/方法体作用域
(3)、使用方式
通过SqlSession实例来执行已映射的SQL语句
基于mapper接口方式操作数据
-
核心配置文件
-
SQL映射文件
5、使用@Param注解实现多参数入参
@Param 方法就是使用注解的方式,进行参数传递
6、使用resultMap实现高级结果映射
(1)、属性
id 唯一标识 type 表示该resultMap的映射结果类型 (2)、resultMap子元素
id:一般对应数据库中该行的主键id
result:映射到JavaBean的某个简单类型属性
association:映射到JavaBean的某个“复杂类型”属性,比如JavaBean类
collection:映射到JavaBean的某个“复杂类型”属性,比如集合(3)、标签
3.1 association:仅处理一对 一的关联关系
3.1.1属性
property 映射数据库列的实体对象的属性 javaType 完整Java类名或者别名 resultMap 引用外部resultMap 3.1.2子元素
id 唯一标识 result property:映射数据库列的实体对象的属性。 column:数据库列名或者别名 -
3.2:一对多,映射一个嵌套结果集到一个列表
3.2.1 属性
property 映射数据库列的实体对象的属性 ofType 完整Java类名或者别名(集合所包括的类型) resultMap 引用外部resultMap 3.2.2 子元素
id 唯一标识 result property:映射数据库列的实体对象的属性。 column:数据库列名或者别名 (4)、resultMap自动映射的三个匹配级别
NONE 禁止自动匹配 PARTIAL 自动匹配所有属性,内部嵌套除外 FULL 自动匹配所有 7、Mybatis缓存
-
一级缓存:同一个SqlSession中可以共用
基于MyBatis自带的HashMap的一个本地缓存,作用范围只在session作用域中。flush或者close后,session域中都会清空。
-
二级缓存:多个SqlSession可以共用
-
二级缓存的配置
-
MyBatis的全局cache配置
<settings> <setting name="cacheEnabled" value="true"/> </settings>
-
在Mapper XML文件中设置缓存,默认情况下:未开启。global cache只针对mapper的namespace内。
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
-
在Mapper XML文件配置支持cache后,若需要对个别查询进行调整,可以单独设置cache
<select id="selectAll" resultType="" useCache="true">
-
-
三、动态SQL
1、使用动态SQL完成多条件查询
1.1元素
if | 条件选择 |
---|---|
choose | 相当于switch语句 |
where | 简化where条件判断 |
set | 解决动态更新语句 |
trim | 可以灵活地去除多余的关键字 |
froeach | 迭代一个集合,通常用于in条件 |
1.2 if+where实现多条件查询
if元素的test属性表示进入if内满足的条件
where元素标签会自动识别标签内是否有返回值,若有,就插入一个where。若标签内返回内容是以and or开头的,会自动剔除。
<select id="selectAllQuestions" resultType="java.util.Map">
SELECT *
FROM qt
<where>
<if test="question_content != null and question_content != ''">
and question_content LIKE CONCAT(CONCAT('%',#{question_content}),'%')
</if>
</where>
</select>
1.3If+trim实现多条件查询
trim元素也会自动识别其标签内是否有返回值,若有返回值,会有自己包含的内容前加上某些前缀,也可以在其后加上后缀,与之对应的属性是prefix和stuffix;也可把包含内容的首部某些内容覆盖,或者把尾部的某些内容覆盖。
prefix | 前缀 |
---|---|
suffix | 后缀 |
prefixOverrides | 对于trim包含内容的首部进行指定内容的忽略 |
suffixOverrides | 对于trim包含内容的首尾部进行指定内容的忽略 |
<select id="selectKh4" parameterType="string" resultType="pojo.Role">
select * from smbms_role
<trim prefix="where" prefixOverrides="and | or" >
<if test="roleName!=null and roleName!=''">
and roleName like concat('%',#{roleName},'%')
</if>
</trim>
</select>
1.4if+set改造更新操作
set元素主要用于更新操作,主要是在包含的语句前输出一个set,若包含的语句是以逗号结束的,会自动把该逗号忽略掉,再配合if元素就可以动态的更新需要修改的字段,还可以剔除追加到条件末尾的任何不相关逗号。
<update id="updateKH4" parameterType="pojo.Role">
update smbms_role
<set>
roleName=#{roleName}
</set>
where id=#{id}
</update>
1.5foreach迭代
(1)、属性
item | 表示集合中每一个元素进行迭代时的别名 |
---|---|
index | 指定一个名称,用于表示在迭代过程中,每次迭代到的位置 |
open | 以什么开始 |
separator | 表示在每次进行迭代之间以什么符号作为分隔符 |
close | 以什么结束 |
collection | 必须指定,三种情况:list,array,map |
(2)、collection入参清况
基本类型:变量名作为key,变量值为value,此时生成的map只有一个元素
对象:对象的属性名作为key,属性值为value
list:默认list作为key,属性值为value
数组:默认array作为key,该数组即为value
map:键值不变
<select id="selectSJ6" resultType="Bill">
select *
from smbms_bill b,smbms_provider p
where b.providerId=p.id and billCode like concat('%',#{billCode},'%')
and b.providerId in
<foreach collection="map" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
1.6 choose(when,otherwise)
(1)、元素
when | 当其test属性中条件满足时,就会输出when元素中的内容 |
---|---|
otherwise | 当when元素的所有条件都不满足的时候,就会自动输出otherwise元素的内容 |
<select id="selectSJ7" resultType="provider">
select id,proCode,proName,proPhone,proContact,creationDate
from smbms_provider where 1=1
<choose>
<when test="proCode!=null and proCode!=''">
and proCode like CONCAT('%',#{proCode},'%')
</when>
<when test="proName!=null and proName!=''">
and proName like CONCAT('%',#{proName},'%')
</when>
<when test="proContact!=null and proContact!=''">
and proContact like CONCAT('%',#{proContact},'%')
</when>
<otherwise>
and YEAR(creationDate)=YEAR(NOW())
</otherwise>
</choose>
</select>
Mybatis实现分页功能
-
引用jar
<!-- pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version> </dependency> <!-- jsqlparser --> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>3.0</version> </dependency>
-
配置拦截
<!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers? --> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="reasonable" value="true"/> </plugin> </plugins>
-
定义sql:不能以;结尾!!
<select id="selectPage" resultMap="membersMap"> select id,mname,mgender,mage from membersinfo where 1 = 1 </select>
-
测试
@Test public void testPage(){ SqlSession sqlSession = MybatisUtils.open(); MembersInfoMapper mapper = sqlSession.getMapper(MembersInfoMapper.class); //引用pagehelper设置分页信息,这行代码必须在执行mapper层的sql前一行!!! PageHelper.startPage(1, 3, true); List<Membersinfo> list = mapper.selectPage(); for (Membersinfo membersinfo : list) { System.out.println(membersinfo.getId() + "," + membersinfo.getMname()); } MybatisUtils.close(sqlSession); }