新建学生表和学生证表

--学生表
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使用-高级用法(二)的更多相关文章

  1. JavaScript高级用法二之内置对象

    综述 本篇的主要内容来自慕课网,内置对象,主要内容如下 1 什么是对象 2 Date 日期对象 3 返回/设置年份方法 4 返回星期方法 5 返回/设置时间方法 6 String 字符串对象 7 返回 ...

  2. Knockout.Js官网学习(Mapping高级用法二)

    使用ignore忽略不需要map的属性 如果在map的时候,你想忽略一些属性,你可以使用ignore累声明需要忽略的属性名称集合: " }; var mapping = { 'ignore' ...

  3. sqlalchemy(二)高级用法

    sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...

  4. redis(二)高级用法

    redis(二)高级用法 事务 redis的事务是一组命令的集合.事务同命令一样都是redis的最小执行单元,一个事务中的命令要么执行要么都不执行. 首先需要multi命令来开始事务,用exec命令来 ...

  5. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  6. SolrNet高级用法(分页、Facet查询、任意分组)

    前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...

  7. 再谈Newtonsoft.Json高级用法

    上一篇Newtonsoft.Json高级用法发布以后收到挺多回复的,本篇将分享几点挺有用的知识点和最近项目中用到的一个新点进行说明,做为对上篇文章的补充. 阅读目录 动态改变属性序列化名称 枚举值序列 ...

  8. Newtonsoft.Json高级用法(转)

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  9. 【转】 Newtonsoft.Json高级用法

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

随机推荐

  1. Mongo-JS-导出数据为insert语句

    ======2014-11-14 数据提取======= [query@query-server hurl]$ cat test.sh tlist=`cat ./username.txt`; for ...

  2. Java 判断中文字符

    Java判断一个字符串中是否有中文字符有两种方法,但是原理都一样,就是通过Unicode编码来判断,因为中文在Unicode中的编码区间为:0x4e00--0x9fa5 第一种: String chi ...

  3. multiple web application host under the same website on IIS (authentication mode)

    第一种方式,修改forms的name how to set the forms authentication cookie path assume you have already solved th ...

  4. Microsoft ASP.NET SignalR

    SignalR类似与JavaScript实时框架,如Socket.IO.SignalR能够完成客户端向服务器的异步通信,并同时支持服务器向浏览器客户端推送事件.SignalR的连接通过日益流行的Web ...

  5. Google Chrome调试常用快捷键

    Ctrl+Shift+I调出开发者工具 Ctrl+R刷新(界面显示不清楚,刷新后变清楚)

  6. mysql如何查询最新插入的数据

    在MySQL中,使用auto_increment类型的id字段作为表的主键,并用它作为其他表的外键,形成“主从表结构”,这是数据库设计中常见的用法.但是在具体生成id的时候,我们的操作顺序一般是:先在 ...

  7. Gym - 101981A The 2018 ICPC Asia Nanjing Regional Contest A.Adrien and Austin 简单博弈

    题面 题意:一堆有n个石子,编号从1⋯N排成一列,两个人Adrien 和Austin玩游戏,每次可以取1⋯K个连续编号的石子,Adrien先手,谁不能取了则输 题解:k==1时,显然和n奇偶相关,当k ...

  8. 有关于dict(字典)的特性与操作方法

    有关于dict(字典)的特性与操作方法 1.字典的特性 语法: dic = {key1 : value1,key2 : value2,key3 : value3............} 注:字典中k ...

  9. BZOJ 4332 FFT+快速幂

    思路: 最裸的方程:f[i][j]=Σf[i-1][j-k]*F[k] 诶呦 这不是卷积嘛 f[i]就可以用f[i-1]卷F 求到 但是这样还是很慢 设p[i] 为Σ f[j](1<=j< ...

  10. Java实现九宫格

    import java.util.Scanner; public class Sudoku { public static void main(String[] args) { System.out. ...