Mybatis框架基础
1.动态SQL
Mybatis提供的拼接Sql语句的机制。
1.if
<select id="listSearchStudents" resultType="entity.Student">
select *
from stu
where sname = #{sname}
<if test="phone != null and phone !='' ">
and phone = #{phone}
</if>
</select>
2.choose when otherwise
<select id="listSearchStudents1" resultType="entity.Student">
select *
from stu
where 1=1
<choose>
<when test="sname != null and sname != '' ">
and sname like '%${sname}%'
</when>
<when test="phone != null and phone != '' ">
and phone like '%${phone}%'
</when>
<!-- 以上都不满足 -->
<otherwise>
</otherwise>
</choose>
</select>
3.where
子元素有返回值,在对应语句加where
<select id="listSearchStudents2" resultType="entity.Student">
select *
from stu
<where>
<if test="sname != null and sname != '' ">
and sname like '%${sname}%'
</if>
<if test="phone != null and phone != '' ">
and phone like '%${phone}%'
</if>
</where>
</select>
4.set
用于update
<update id="updateStudentBySid" parameterType="Integer">
update stu
<set>
<if test="sname != null and sname != '' ">
sname = #{sname},
</if>
<if test="phone != null and phone != '' ">
phone = #{phone},mj
</if>
</set>
where sid = #{sid}
</update>
5.trim
- prefix 指定给Sql语句增加的前缀
- prefixOverrides 指定给Sql语句要去掉的前缀
- suffix 指定给Sql语句增加的后缀
- suffixOverrides 指定给Sql语句要去掉的后缀
代替where和set使用
<trim prefix="where" prefixOverrides="and">
<if test="">
and sid = #{sid}
</if>
</trim>
<trim prefix="set" suffixOverrides=",">
<if test="">
sid = #{sid},
</if>
</trim>
6.foreach
用于遍历 支持数组 List Set 接口的集合
通常用于in关键字
<select id="listStudentsByForeach" resultType="entity.Student">
select *
from stu
where sid in
<foreach collection="list" item="sid" index="index" open="(" separator="," close=")">
#{sid}
</foreach>
</select>
2.缓存
1.一级缓存
同一个SqlSession对象第一次执行查询语句,把结果写入一级缓存
之后没有更新插入删除操作,执行相同的查询语句,会读取一级缓存内数据
1.1 原理
SqlSession级别的缓存。创建SqlSession时,对象引入HashMap作为储存数据区域。
key是SQL语句、条件、statement组成的唯一值
value是查询的结果对象
不同SqlSession之间HashMap不影响
1.2 应用
1.2.1 log4j日志配置
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
- log4j.properies 配置文件
log4j.rootLogger = ERROR,stdout
#mybatis???? namespace?
log4j.logger.mapper.StudentMapper = DEBUG
#???????
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %5p[%t] - %m%n
1.2.2 Test类
@Test
public void Test(){
String resource = "config.xml";
try{
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(in);
SqlSession sqlSession=ssf.openSession();
String statement="mapper.StudentMapper.getStudentBySid";
Student student = sqlSession.selectOne(statement,1);
System.out.println(student);
Student student1 = sqlSession.selectOne(statement,1);
System.out.println(student1);
sqlSession.commit();
sqlSession.close();
}catch (Exception e){
e.printStackTrace();
}
}
2.二级缓存
2.1 原理
作用域是Mapper,可以跨多个SqlSession,多个SqlSession操作同一个Mapper的Sql语句,共用二级缓存
HashMap与一级缓存一样
可以自定义缓存源
以namespace区分Mapper,SqlSesion执行查询,没有更新删除插入,别的SqlSession执行相同查询,从缓存拿到
2.2 应用
2.2.1 开启二级缓存
- 配置文件
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- Mapper.xml
<cache></cache>
默认特性:
- 缓存使用LRU算法收回
- 没有刷新间隔,缓存不会以任何时间顺序来刷新
- 缓存会存储列表集合或对象的1024个引用
- 缓存可读写,对象检索不是共享的,可以安全调用
![]()
2.2.2 实体类序列化
public class Student implements Serializable
2.2.3 测试类
@Test
public void cache(){
String resource = "config.xml";
try{
InputStream in = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(in);
SqlSession sqlSession1 = ssf.openSession();
SqlSession sqlSession2 = ssf.openSession();
String statement="mapper.StudentMapper.getStudentBySid";
Student student1 = sqlSession1.selectOne(statement,1);
System.out.println(student1);
// 是否在新的SQL查询之前没有关闭上一个SqlSession,导致命中了一级缓存而不需要查询二级缓存
sqlSession1.commit();
sqlSession1.close();
Student student2 = sqlSession2.selectOne(statement,1);
System.out.println(student2);
sqlSession2.commit();
sqlSession2.close();
}catch (Exception e){
e.printStackTrace();
}
}
3.整合EhCache
3.1 依赖
<!-- EhCache-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.8</version>
</dependency>
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.3</version>
</dependency>
3.2 ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="D:/cache"></diskStore>
<defaultCache
maxElementsInMemory="1"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
- diskStore 指定缓存数据转移到磁盘,path指定存储位置
- defaultCache 指定默认缓存配置信息
- cache 自定义配置信息
![]()
3.基础
1.工作流程
1.读取配置文件和映射文件。
2.生成SqlSessionFactory对象:生成SqlSession
3.SqlSession通过Executor执行器接口操作数据库,其有俩个实现类,一个是普通执行器,缓存执行器。
4.Executor执行器将Sql信息封装到MapperStatement对象中。执行Sql前,MapperStatement对象吧Java数据映射到Sql。执行后,执行结果映射为Java数据

2.SqlSessionFactory类
使用单列模式创建SqlSessionFactory对象,每一个数据库对应一个SqlSessionFactory对象。
3.SqlSession类
线程不安全 不能被共享

1.#{} 和 ${}
- 使用#{} 解析为SQL时,会将形参变量的值取出,并自动给其添加引号。
username="Amy"
使用#{}可以防止SQL注入而${}却不行 - ${} 解析为SQL时,将形参变量的值直接取出,直接拼接显示在SQL中
username=${value} -> username=Amy
username='${value}' -> username='Amy'
使用 某字段 in 时候使用
- 模糊查询场景
username LIKE '%${value}%'
username LIKE CONCAT('%', #{username}, '%')
作用一样 但是${}不安全 - 只能${}场景
ORDER BY ${value} ASC 如果用#{}则错误



浙公网安备 33010602011771号