文章目录
测试环境搭建
1.导入lombok
2.新建实体类Teacher,Student
3.建立Mapper接口
4.建立Mapper.xml文件
5.在核心配置文件中绑定注册我们的Mapper接口或者文件
6.测试查询是否能够成功
按照查询嵌套处理
<!--
思路:
1.查询所有的学生信息
2.根据查询出来的学生的tid,寻找对应的老师
-->
<select id="getStudent" resultMap="StudentTeacher">
SELECT * FROM mybatis.student;
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性,我们需要单独处理
对象:association
集合:collection
-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
SELECT * FROM teacher WHERE id=#{id}
</select>
按照结果嵌套处理
<!--按照结果嵌套处理-->
<select id="getStudent" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname
from student s,teacher t
where s.tid=t.id;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
回顾Mysql多对一查询方式:
○子查询
○联表查询
11、一对多
比如:一个老师拥有多个学生
对于老师而言,就是一对多的关系。
1.环境搭建,就跟刚才一样
实体类
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List<Student> students;
}
public class Student {
private int id;
private String name;
private int tid;
}
按照结果嵌套处理
<!--按结果嵌套查询-->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid,s.name sname,t.name tname,t.id tid
from student s,teacher t
where s.tid=t.id AND t.id=#{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!--指定属性的类型 集合中的泛型信息,我们使用ofType获取 -->
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
按照查询嵌套查询
<select id="getTeacher2" resultMap="TeacherStudent2">
SELECT * FROM mybatis.teacher WHERE id=#{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
SELECT * FROM mybatis.student WHERE tid=#{tid}
</select>
小结
1.关联-association 【多对一】
2.集合-collection 【一对多】
3.javaType&ofType
1.javaType用来指定实体类中属性的类型
2.ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型。
注意点:
○保证sql的可读性,通俗易懂
○注意一对多和多对一中,属性名和字段的问题。
○如果问题不好排查,可以使用日志,建议使用Log4j。
12、动态SQL
什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句
搭建环境
create table blog(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=innoDB DEFAULT CHARSET=utf8
创建一个基础工程
1.导包
2.编写配置文件
3.编写实体类
public class Blog {
private int id;
private String title;
private String author;
private Date createTime;
private int views;
public Blog() {
}
public Blog(int id, String title, String author, Date createTime, int views) {
this.id = id;
this.title = title;
this.author = author;
this.createTime = createTime;
this.views = views;
}
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public int getViews() {
return views;
}
public void setViews(int views) {
this.views = views;
}
@Override
public String toString() {
return "Blog{" +
"id=" + id +
", title='" + title + '\'' +
", author='" + author + '\'' +
", createTime=" + createTime +
", views=" + views +
'}';
}
}
4.编写实体类对应Mapper接口和Mapper.xml文件
IF
<select id="queryBlogIF" parameterType="map" resultType="Blog">
SELECT * FROM mybatis.blog WHERE 1=1
<if test="title !=null">
AND title=#{title}
</if>
<if test="author !=null">
and author=#{author}
</if>
</select>
choose(when,otherwise)
<select id="queryBlogChoose" parameterType="map" resultType="blog">
SELECT * FROM mybatis.blog
<where>
<choose>
<when test="title !=null">
title=#{title}
</when>
<when test="author !=null">
and author=#{author}
</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
trim(where,set)
<select id="queryBlogIF" parameterType="map" resultType="Blog">
SELECT * FROM mybatis.blog
<where>
<if test="title !=null">
title=#{title}
</if>
<if test="author !=null">
and author=#{author}
</if>
</where>
</select>
<update id="updateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title !=null">
title=#{title},
</if>
<if test="author !=null">
author=#{author}
</if>
</set>
WHERE id=#{id}
</update>
所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码
SQL片段
有的时候,我们可能会将一些功能的部门抽取出来,方便复用。
1.使用SQL标签抽取公共的部分
<sql id="if-title-author">
<if test="title !=null">
title=#{title}
</if>
<if test="author !=null">
and author=#{author}
</if>
</sql>
2.在需要使用的地方使用include标签引用即可
<select id="queryBlogIF" parameterType="map" resultType="Blog">
SELECT * FROM mybatis.blog
<where>
<include refid="if-title-author">
</include>
</where>
</select>
注意事项:
○最好基于单表来定义SQL片段。
○不要存在where标签
动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就可以了。
13、缓存
13.1、简介
13.2、Mybatis缓存
13.3、一级缓存
13.4、二级缓存
步骤:
1.开启全局缓存
<!--显式的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
2.在要使用二级缓存的mapper中开启
<!--在当前Mapper.xml中使用二级缓存-->
<cache/>
也可以自定义参数
3.测试
1.问题:我们需要将实体类序列化,否则就会报错
小结:
只要开启了二级缓存,在同一个Mapper下就有效
所有的数据都会先放在一级缓存
只有当会话提交或者关闭的时候,或者关闭的时候,才会提交到二级缓存中。
13.5、缓存原理
13.6、自定义缓存Ehcache
要先导包