新建学生表和学生证表

--学生表
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. 浅谈EL与JSTL

    讲道理,自己在博大精深的Java世界里还只是一个很小很小的菜鸟.处于成长与学习之中,但学习一个漫长的过程.尤其对于那些知识点我觉得总结是尤为重要的.反正在我看来这段时间里虽然过了很多知识但却是一脸懵逼 ...

  2. Spring Boot、微服务架构和大数据

    一文读懂 Spring Boot.微服务架构和大数据治理三者之间的故事 https://www.cnblogs.com/ityouknow/p/9034377.html 微服务架构 微服务的诞生并非偶 ...

  3. 比较两个map里的数据

    template <class DataType>void ProcessMap(std::map<std::string, std::vector<DataType> ...

  4. ”W: GPG 错误:http://ppa.launchpad.net lucid Release: 由于没有公钥,无法验证下列签名:“的问题

    在安装更新时,即在运行,命令行sudo apt-get update 或者运行更新管理器的时候,出现如下错误: W: GPG 错误:http://ppa.launchpad.net lucid Rel ...

  5. php循环跳出

    PHP中的循环结构大致有for循环,while循环,do{} while 循环以及foreach循环几种,不管哪种循环中,在PHP中跳出循环大致有这么几种方式: 代码: <?php $i = 1 ...

  6. Django模板常用语法规则

    Django 模板标签 if/else 标签 for 标签 ifequal/ifnotequal 标签 注释标签 过滤器 include 标签 URL标签 模板继承   if/else 标签 1. 基 ...

  7. Django models 常用字段类型

    1.CharField字符串字段,存较短的字符串,长文本要用TextField.必须的参数:max_length 字符的最大长度2.TextField容量很大的文本字段.admin中用 <tex ...

  8. 查看 Android App 的 versionCode

    有 App 源码时,可以直接查看 AndroidManifest.xml 文件. <manifest android:versionName="1.4" android:ve ...

  9. Windows-Server-2008、IIS7.0环境下配置伪静态化

    在Windows-Server-2008.IIS7.0环境下配置伪静态化                首先,是IIS7.0的配置,由于Windows Server 2008操作系统默认的IIS版本为 ...

  10. ROS:ubuntuKylin17.04-Ros使用OrbSLAM2

    忙于图像处理和DCNN,很长时间不使用ROS,重新安装系统后,再次使用ORB-SLAM2(ROS)进行三维重建和实时追踪的演示. 参考以前的文章:ROS:ubuntu-Ros使用OrbSLAM ORB ...