mybatis使用-高级用法(二)
新建学生表和学生证表
- --学生表
- CREATE TABLE student(
- id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'id',
- `name` VARCHAR(20) NOT NULL COMMENT '姓名',
- `age` INT NOT NULL COMMENT '年龄',
- sex INT NOT NULL COMMENT '性别 1 男 0 女',
- cid INT NOT NULL COMMENT '班级id',
- cardId INT COMMENT '学生证id'
- )
- --学生证表
- CREATE TABLE Card
- (
- id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'id',
- number INT NOT NULL COMMENT '学生证id',
- studentId INT NOT NULL COMMENT '学生id'
- )
动态标签
include&sql
实现sql复用
- <sql id="columns">
- id,name,age
- </sql>
- <!--useCache 表示使用缓存 -->
- <select id="selectOne" parameterType="string" flushCache="false"
- useCache="true" resultMap="studentAndClassMap">
- select <include refid="columns"/> from student
- <!--模拟if标签 -->
- <if test="id !=null and id!=''">
- where id=#{id}
- </if>
- </select>
where&if
- <select id="selectOne" parameterType="string" flushCache="false"
- useCache="true" resultMap="studentAndClassMap">
- select <include refid="columns"/> from student
- <where>
- <if test="id !=null and id!=''">
- and id=#{id}
- </if>
<if test="name !=null and name!=''">
and name=#{name}
</if>- </where>
- </select>
where标签里面有if标签成立 则自动在sql后面拼接where 同时去除多余的and
choose, when, otherwise
- <select id="find" parameterType="map" resultType="student">
- select * from student
- <!-- if else if else -->
- <where>
- <choose>
- <when test="sex != null">
- and sex=#{sex}
- </when>
- <when test="name != null and name != ''">
- and name like concat('%',#{name},'%')
- </when>
- <!-- <otherwise>
- ...
- </otherwise> -->
- </choose>
- </where>
- </select>
trim, set
- select * from user
- <trim prefix="WHERE" prefixoverride="AND |OR">
- <if test="name != null and name.length()>0"> AND name=#{name}</if>
- <if test="gender != null and gender.length()>0"> AND gender=#{gender}</if>
- </trim>
满足条件拼接 where 同时去掉前面多余的and或者or
- update user
- <trim prefix="set" suffixoverride="," suffix=" where id = #{id} ">
- <if test="name != null and name.length()>0"> name=#{name} , </if>
- <if test="gender != null and gender.length()>0"> gender=#{gender} , </if>
- </trim>
满足条件拼接set 同时去掉后面多余的, 再拼接 suffix
- update user
- <set>
- <if test="name != null and name.length()>0"> name=#{name} , </if>
- <if test="gender != null and gender.length()>0"> gender=#{gender} , </if>
- </set>
满足条件拼接set 同时去掉多余的,
一对多级联
1.学生mapper增加一个根据班级获取学生
- <select id="findByClassesId" parameterType="int" resultType="student">
- select * from student where cid=#{id}
- </select>
- public List<Student> findByStudent(Student params);
2.在classes类增加一个学生集合
- public class Classes implements Serializable{
....
private List<Student> students;
}
2.classesMapper增加自定义resultMap
- <resultMap id="classVoMap" type="com.liqiang.vo.ClassesVo">
- <id property="id" column="id" />
- <result property="name" column="name" />
- <collection property="students" column="id"
- select="com.liqiang.mapper.StudentMapper.findByClassesId"></collection>
- </resultMap>
- select为调用指定mapperStatement(可以理解是指定key的标签namespace+id)
column 为将哪个列作为参数传递
students 返回结果赋值的属性
可以设置 fetchType="eager(默认值 不按层级加载)|lazy" 就是有有很多级的时候 是否一下把所有级加载出来
3.在需要使用resultMap的地方指定resultMap 如根据id获得class
- <select id="findById" parameterType="Integer" resultMap="classVoMap">
- select *
- from classes where id=#{id}
- </select>
多对一, 一对一级联
1.学生表增加classes
- public class Student implements Serializable{
....- private Classes classes;
}
2.学生表增加自定义resultMap
- <resultMap id="studentAndClassMap" type="student" >
- <id property="id" column="id" />
- <result property="name" column="name" />
- <result property="age" column="age" />
- <result property="cid" column="cid" />
- <association property="classes" column="cid"
- select="com.liqiang.mapper.ClassesMapper.findById"></association>
- </resultMap>
3.在需要级联的地方resultMap改为这个
- <!--useCache 表示使用缓存 -->
- <select id="selectOne" parameterType="string" flushCache="false"
- useCache="true" resultMap="studentAndClassMap">
- select * from student
- <!--模拟if标签 -->
- <if test="id !=null and id!=''">
- where id=#{id}
- </if>
- </select>
跟多对一一样 只是标签改为association
可以通过Sesstio全局设置级联是否延迟加载
- <settings>
- <setting name="lazyLoadingEnabled" value="true"></setting><!--开启级联延迟加载-->
- <!--不按层级延迟加载 根据get 来加载 可以在collection 或者association 加上属性覆盖全局 fetchType="eager(默认值 不按层级)|lazy"-->
- <setting name="aggressiveLazyLoading" value="false"></setting>
- </settings>
层级加载的意思 就是 比如学生级联班级,班级又有学校级联 当延迟加载情况getClass时是否也级联加载学校,或者非延迟加载 所有的都加载出来
resultMap或者ParameterMap继承
- <resultMap id="studentMap" type="studentVo">
- <id property="id" column="id" />
- <result property="name" column="name" />
- <result property="age" column="age" />
- <result property="cid" column="cid" />
- <association property="card" column="id"
- select="com.liqiang.mapper.CardMapper.findByStudentId"></association>
- </resultMap>
- <resultMap id="studentAndClassMap" type="student" >
- <id property="id" column="id" />
- <result property="name" column="name" />
- <result property="age" column="age" />
- <result property="cid" column="cid" />
- <association property="classes" column="cid"
- select="com.liqiang.mapper.ClassesMapper.findById"></association>
- </resultMap>
如我定义了2个Resultmap 一个需要class级联 一个只需要学生证级联,是否发现前面几个属性几乎是copy的
我们可以这样
- <resultMap id="simpleType" type="student">
- <id property="id" column="id" />
- <result property="name" column="name" />
- <result property="age" column="age" />
- <result property="cid" column="cid" />
- </resultMap>
- <resultMap id="studentMap" type="student" extends="simpleType">
- <association property="card" column="id"
- select="com.liqiang.mapper.CardMapper.findByStudentId"></association>
- </resultMap>
- <resultMap id="studentAndClassMap" type="student" extends="simpleType" >
- <association property="classes" column="cid"
- select="com.liqiang.mapper.ClassesMapper.findById"></association>
- </resultMap>
使用extends="simpleType" 继承
Mybatis对枚举支持
1.添加一个性别枚举
- public enum SexEnum {
- MALE(1, "男"), FEMAL(0, "女");
- private int id;
- private String name;
- private SexEnum(int id, String name) {
- this.id = id;
- this.name = name;
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
2.将学生性别改为枚举类型
- public class Student implements Serializable{
....- private SexEnum sex;
- }
3.resultMap的TypeHandle处理器改为mybatis提供的枚举处理器
- <resultMap id="studentMap" type="studentVo">
- ....
- <result property="sex" column="sex"
- typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
自定义TypeHandle
实现TypeHandle接口就好了。然后像上面一样typeHandle改为自己指定的,因为mybatis默认提供个TypeHandle基本够用了。找不到例子 测试
自定义缓存
分布式 或者集群我们缓存都是存在redis或者其他nosql上面,redis缓存默认是存在当前服务器内存,
这种时候我们需要自定义缓存
- public class MyCache implements org.apache.ibatis.cache.Cache{
- private String id;
- /**
- *读的时候其他线程可以读
- *读的时候其他线程不能写
- *写的时候其他线程不能写
- *写的时候不能读
- * getData(){
- * try{
- * readWriteLock.readLock(); 读锁
- * }catch(execption e){
- *
- * }finally{
- * readWriteLock.readLock().unlock();
- * }
- * }
- *
- * setData(){
- * * try{
- * readWriteLock.writerLock(); 写锁
- * }catch(execption e){
- *
- * }finally{
- * readWriteLock.writerLock().unlock();
- * }
- * }
- * 外部代理类会在get 和put 方法 加上读写锁
- */
- private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();//读写锁
- public MyCache(String id){
- System.out.println(id);//对应的mapper全名称标示
- this.id=id;
- }
- private static Map<Object, Object> cacheManager=new HashMap<Object, Object>();//模拟redis
- //获取缓存编号
- public String getId() {
- // TODO Auto-generated method stub
- return id;
- }
- //缓存数据
- public void putObject(Object key, Object value) {
- System.out.println("缓存对象 key为:"+key.toString());
- // TODO Auto-generated method stub
- cacheManager.put(key, value);
- }
- //获取缓存
- public Object getObject(Object key) {
- // TODO Auto-generated method stub
- System.out.println("获取对象 key为:"+key.toString());
- return cacheManager.get(key);
- }
- //删除缓存
- public Object removeObject(Object key) {
- return cacheManager.remove(key);
- }
- //清空缓存
- public void clear() {
- cacheManager.clear();
- }
- //获取缓存对象大小
- public int getSize() {
- // TODO Auto-generated method stub
- return cacheManager.size();
- }
- //获取缓存读写锁
- public ReadWriteLock getReadWriteLock() {
- // TODO Auto-generated method stub
- return readWriteLock;
- }
- }
实现Cache 接口
在需要Mapper缓存的Mapper.xml配置
- <!-- eviction 回收策略 LRU:最近最少使用 FIFO:先进先出 SOFT 软引用 WEAK 移除最长时间不使用的对象 flushInterVal:刷新时间间隔
- 毫秒。不配置 执行inser update delete 才会刷新 type :自定义缓存需要实现 org.apache.ibatis.cache.Cache -->
- <cache eviction="LRU" flushInterval="100000" size="1024"
- readOnly="true" type="com.liqiang.tool.MyCache"></cache>
在需要更新缓存的地方
- <!--flushCache 是否刷新缓存 -->
- <update id="update" parameterType="student" flushCache="true">
- update student set name=#{name},sex=#{sex} where id=#{id}
- </update>
打上flushCache="true"
mybatis缓存的粒度不是很细。一刷新缓存整个表就刷新了。比如id为1的数据修改 你想只更新这个缓存,mybatis是更新整个表
mybatis使用-高级用法(二)的更多相关文章
- JavaScript高级用法二之内置对象
综述 本篇的主要内容来自慕课网,内置对象,主要内容如下 1 什么是对象 2 Date 日期对象 3 返回/设置年份方法 4 返回星期方法 5 返回/设置时间方法 6 String 字符串对象 7 返回 ...
- Knockout.Js官网学习(Mapping高级用法二)
使用ignore忽略不需要map的属性 如果在map的时候,你想忽略一些属性,你可以使用ignore累声明需要忽略的属性名称集合: " }; var mapping = { 'ignore' ...
- sqlalchemy(二)高级用法
sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...
- redis(二)高级用法
redis(二)高级用法 事务 redis的事务是一组命令的集合.事务同命令一样都是redis的最小执行单元,一个事务中的命令要么执行要么都不执行. 首先需要multi命令来开始事务,用exec命令来 ...
- C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com
原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...
- SolrNet高级用法(分页、Facet查询、任意分组)
前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...
- 再谈Newtonsoft.Json高级用法
上一篇Newtonsoft.Json高级用法发布以后收到挺多回复的,本篇将分享几点挺有用的知识点和最近项目中用到的一个新点进行说明,做为对上篇文章的补充. 阅读目录 动态改变属性序列化名称 枚举值序列 ...
- Newtonsoft.Json高级用法(转)
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- 【转】 Newtonsoft.Json高级用法
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
随机推荐
- 0x6A 网络流初步
CH Round #17-C 这个算是一个技能点吧,不点不会,点了就没什么了.懒得写看书吧书上的1应该是0... 我又回来了太懒了不想翻书还是写写吧 必须边的判定条件:该边流量为0且两端的点在残余网络 ...
- Opencv保存摄像头视频&&各种编码器下视频文件占用空间对比
打开视频文件或摄像头视频需要使用Opencv中的VideoCapture类,保存视频或摄像头视频到本地磁盘,需要使用Opencv中的VideoWriter类,使用都很简单,这篇文章就记录一下Video ...
- Webkit内核开源爬虫蜘蛛引擎
C#开发的基于Webkit内核开源爬虫蜘蛛引擎 https://www.cnblogs.com/micro-chen/p/9075590.html 概述 在各个电商平台发展日渐成熟的今天.很多时候,我 ...
- Java-JRE:JRE百科
ylbtech-Java-JRE:JRE百科 JRE是Java Runtime Environment缩写,指Java运行环境,是Sun的产品.运行JAVA程序所必须的环境的集合,包含JVM标准实现及 ...
- 1tb等于多少g 1TB和500G有什么区别
转自:http://www.a207.com/article/view_39392 移动硬盘.U盘是生活中常见的用品,他们的内存大小是什么标准.很多人对于1tb等于多少g和1tb和500g有什么区别不 ...
- hdu2089不要62(数位dp)
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 移动App服务端架构设计
我从事手机app服务端开发现在已经是3个年头,自己也整理出了一套相对好用的服务架构,写出来,跟大家一起分享.如有不足,还请多指教. 一:基础流程图. 其实有一点还需要加上,就是对json的压缩和加 ...
- 如何在Eclipse中创建Web服务器
使用Eclipse开发Web项目时,需要先配置Web服务器,如果已经配置好Web服务器,就不需要再重新配置了.也就是说,本节的内容不是开发每个项目时,都必须经过的步骤.创建Web服务器的具体步骤如下: ...
- mysql主从不同步,提示更新找不到记录
查看丛库状态show slave status\G 从库原文提示:Last_Error: Coordinator stopped because there were error(s) in the ...
- python3 str类型
python3 的str就是unicode,只有encode函数,调用encode返回的是bytes. bytes只有decode函数,调用decode返回的是str.