赞
踩
查询条件实体类
public class QueryTeamVO { private String name; private Date beginTime; private Date endTime; private String location; public QueryTeamVO() { } public QueryTeamVO(String name, Date beginTime, Date endTime, String location) { this.name = name; this.beginTime = beginTime; this.endTime = endTime; this.location = location; } @Override public String toString() { return "QueryTeamVO{" + "name='" + name + '\'' + ", beginTime=" + beginTime + ", endTime=" + endTime + ", location='" + location + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBeginTime() { return beginTime; } public void setBeginTime(Date beginTime) { this.beginTime = beginTime; } public Date getEndTime() { return endTime; } public void setEndTime(Date endTime) { this.endTime = endTime; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
TeamMapper.java中添加接口方法
List<Team> queryByVO(QueryTeamVO vo);
TeamMapper.xml添加映射方法
<select id="queryByVO" parameterType="QueryTeamVO" resultMap="baseResultMap"> select * from team <where> <!--第一个判断条件中 and可写可不写--> <if test="name!=null"> and teamName like CONCAT('%',#{name},'%') </if> <if test="beginTime!=null"> and createTime>= #{beginTime} </if> <if test="endTime!=null"> and createTime <= #{endTime} </if> <if test="location!=null"> and location = #{location} </if> </where> </select>
添加测试类:
public class DynamicSqlTest {
private TeamMapper mapper = MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
@Test
public void test1() {
QueryTeamVO vo=new QueryTeamVO();
vo.setName("士");
vo.setEndTime(new Date());
List<Team> teams = mapper.queryByVO(vo);
teams.forEach(team -> {
System.out.println(team);
});
}
}
测试结果
查询sql的条件中与传入参数对应
添加Mapper接口方法:
Integer update1(Team team);
添加xml映射:
<update id="update1" parameterType="team">
update team
<set>
<if test="teamName!=null">
teamName=#{teamName},
</if>
<if test="location!=null">
location=#{location},
</if>
<if test="createTime!=null">
createTime=#{createTime}
</if>
</set>
where teamId=#{teamId}
</update>
添加测试方法:
@Test
public void test2(){
Team team = mapper.queryById(1117);
team.setTeamName("hotFire");
team.setCreateTime(new Date());
team.setLocation(null);
Integer num = mapper.update1(team);
System.out.println("影响结果数量:"+num);
}
接口添加方法:
void addList(List<Team> teamList);
mapper添加映射方法
<insert id="addList" parameterType="arrayList">
insert into team(teamName,location) values
<foreach collection="list" item="t" separator=",">
(#{t.teamName},#{t.location})
</foreach>
</insert>
添加测试方法
@Test
public void test3(){
List<Team> list=new ArrayList<>();
for (int i=0;i<3;i++){
Team team=new Team();
team.setTeamName("jk"+i);
team.setLocation("address"+i);
team.setCreateTime(new Date());
list.add(team);
}
mapper.addList(list);
MybatisUtil.getSqlSession().commit();
}
接口添加方法:
void delList(List<Integer> list);
mapper映射方法:
<delete id="delList" parameterType="arrayList">
delete from team where teamId in
<!--collection=要遍历的集合,参数直接写集合类型
item=遍历集合中的每一个元素
separator=遍历集合中每个元素用,分割
open=开始包裹元素,close=结束包裹元素-->
<foreach collection="list" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
添加测试方法:
@Test
public void test4(){
List<Integer> list=new ArrayList<>();
list.add(1116);
list.add(1117);
mapper.delList(list);
MybatisUtil.getSqlSession().commit();
}
<!--分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
<!-- 引入 pageHelper插件 --> <!--注意这里要写成PageInterceptor, 5.0之前的版本都是写PageHelper, 5.0之后要换成PageInterceptor-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--reasonable:分页合理化参数,默认值为false,直接根据参数进行查询。 当该参数设置为 true 时,pageNum<=0 时会查询第一页,
pageNum>pages(超过总数时),会查询最后一页。 方言可以省略,会根据连接数据的参数url自动推断-->
<!--<property name="reasonable" value="true"/>-->
</plugin>
</plugins>
@Test public void test5(){ // PageHelper.startPage 必须紧邻查询语句,而且只对第一条查询语句生效 PageHelper.startPage(2,5); // 查询语句结尾不能有; List<Team> teams = mapper.queryAll(); teams.forEach(team -> { System.out.println(team); }); PageInfo<Team> pageInfo=new PageInfo<>(teams); System.out.println("分页信息如下:"); System.out.println("当前页数:"+pageInfo.getPageNum()); System.out.println("总页数:"+pageInfo.getPages()); System.out.println("前一页:"+pageInfo.getPrePage()); System.out.println("后一页:"+pageInfo.getNextPage()); }
缓存是一般的ORM框架都会提供的功能,目的是提高查询效率和减少数据库压力。将经常查询的数据存在缓存中,用户查询数据时不需要再从磁盘上读取,直接从缓存中读取,提高查询效率,解决高并发问题。
sqlsession缓存,自动开启。在操作数据库时需要构造sqlsession对象,该对象拥有一个数据结构HashMap用户缓存数据。不同的sqlSession之间的HashMap互不影响。
一级缓存的作用域是同一个sqlSession,在同一个sqlSession执行两次的sql语句,第一次执行完毕就会将查询的结果写入到缓存中,第二次从缓存中读取而不是从数据库中查询,提高查询效率。
当一个sqlSession结束后,sqlsession中的一级缓存也就不存在了。
Mybatis默认开启一级缓存,存在内存中不能被关闭,可以调用clearCache()来清空本地缓存,或者改变缓存的作用域。
工作原理
测试类:
public class TestCache { private SqlSession sqlSession= MybatisUtil.getSqlSession(); @Test public void test1(){ TeamMapper teamMapper = sqlSession.getMapper(TeamMapper.class); Team team = teamMapper.queryById(1001); System.out.println(team); Team team1 = teamMapper.queryById(1001); System.out.println(team1); MybatisUtil.closeSqlSession();//关闭连接,清空缓存 sqlSession= MybatisUtil.getSqlSession(); teamMapper=sqlSession.getMapper(TeamMapper.class);//再次获取连接,此时缓存为空 Team team3 = teamMapper.queryById(1001); System.out.println(team3); teamMapper.delete(1131); MybatisUtil.getSqlSession().commit();//提交之后缓存清空 Team team4 = teamMapper.queryById(1001); System.out.println(team4); } }
清空缓存方式:
Mapper级别的缓存。多个SqlSession共同去操作一个Mapper的sql语句,多个SqlSession可以共用二级缓存。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace。
不同的sqlSession两次执行相同的namespace下的sql语句参数相同即执行相同的sql语句,第一次执行会将执行结果写入缓存,第二次执行直接从内存中获取结果,提高查询效率。
Mybatis默认没有开启二级缓存,需要在setting全局设置中配置开启二级缓存。
二级缓存原理图:
二级缓存是mapper级别,默认不启用。
1、Mybatis的全局配置文件中开启二级缓存
<settings>
<!-- 是否开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
2、在需要二级缓存的mapper中添加缓存标志
<mapper namespace="com.jsonliu.test.mapper.TeamMapper">
<cache></cache>
...
</mapper>
3、实体类必须实现Serializable接口
public class Team implements Serializable {
...
}
4、测试二级缓存
如果两个Session不是同一个Factory获取,那么二级缓存不起作用。
@Test public void test2(){ SqlSession sqlSession1 = MybatisUtil.getSqlSession(); TeamMapper mapper1 = sqlSession1.getMapper(TeamMapper.class); Team team1 = mapper1.queryById(1001); System.out.println(team1); MybatisUtil.closeSqlSession(); SqlSession sqlSession2 = MybatisUtil.getSqlSession(); TeamMapper mapper2 = sqlSession2.getMapper(TeamMapper.class); Team team2 = mapper2.queryById(1001); System.out.println(team2); MybatisUtil.closeSqlSession(); SqlSession sqlSession3= MybatisUtil.getSqlSession(); TeamMapper mapper3 = sqlSession3.getMapper(TeamMapper.class); Integer delete = mapper3.delete(1031); System.out.println(delete); MybatisUtil.closeSqlSession(); SqlSession sqlSession4 = MybatisUtil.getSqlSession(); TeamMapper mapper4 = sqlSession4.getMapper(TeamMapper.class); Team team4 = mapper4.queryById(1001); System.out.println(team4); MybatisUtil.closeSqlSession(); }
对于变化比较频繁的sql,可以禁用二级缓存。
在开始了二级缓存的XML中对应的statement中设置useCache=false禁用当前Select语句的二级缓存,意味着该SQL语句每次只需都去查询数据库,不会查询缓存。
useCache默认值是true。对于一些很重要的数据尽不放在二级缓存中。
<cache>
<property name="eviction" value="LRU"/><!--回收策略为LRU-->
<property name="flushInterval" value="60000"/><!--自动刷新时间间隔为60S-->
<property name="size" value="1024"/><!--最多缓存1024个引用对象-->
<property name="readOnly" value="true"/><!--只读-->
</cache>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。