Mybatis学习笔记

一、数据库字段名与实体类属性名不相同问题

1.1 准备数据表和数据

CREATE TABLE orders(
	order_id INT PRIMARY KEY AUTO_INCREMENT,
	order_no VARCHAR(20), 
	order_price FLOAT
);
INSERT INTO orders(order_no, order_price) VALUES('aaaa', 23);
INSERT INTO orders(order_no, order_price) VALUES('bbbb', 33);
INSERT INTO orders(order_no, order_price) VALUES('cccc', 22);

1.2 定义实体类

public class Order {
	private int id;
	private String orderNo;
	private float price;
}

1.3 查询数据实现

方式一: 通过在sql语句中定义别名
<select id="selectOrder" parameterType="int" resultType="_Order">
	select order_id id, order_no orderNo,order_price price from orders where order_id=#{id}
</select>
		
方式二: 通过<resultMap>
<select id="selectOrderResultMap" parameterType="int" resultMap="orderResultMap">
	select * from orders where order_id=#{id}
</select>

<resultMap type="_Order" id="orderResultMap">
	<id property="id" column="order_id"/>
	<result property="orderNo" column="order_no"/>
	<result property="price" column="order_price"/>
</resultMap>

二、一对一关联表查询

2.1 创建表和数据

CREATE TABLE teacher(
	t_id INT PRIMARY KEY AUTO_INCREMENT, 
	t_name VARCHAR(20)
);
CREATE TABLE class(
	c_id INT PRIMARY KEY AUTO_INCREMENT, 
	c_name VARCHAR(20), 
	teacher_id INT
);
ALTER TABLE class ADD CONSTRAINT fk_teacher_id FOREIGN KEY (teacher_id) REFERENCES teacher(t_id);	

INSERT INTO teacher(t_name) VALUES('LS1');
INSERT INTO teacher(t_name) VALUES('LS2');

INSERT INTO class(c_name, teacher_id) VALUES('bj_a', 1);
INSERT INTO class(c_name, teacher_id) VALUES('bj_b', 2);


提出需求:根据班级id查询班级信息(带老师的信息)


2.2 定义实体类

public class Teacher {
	private int id;
	private String name;
}
public class Classes {
	private int id;
	private String name;
	private Teacher teacher;
}

2.3 定义SQL映射文件ClassMapper.xml

<!-- 
方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
         封装联表查询的数据(去除重复的数据)
select * from class c, teacher t where c.teacher_id=t.t_id and  c.c_id=1
-->
<select id="getClass" parameterType="int" resultMap="ClassResultMap">
	select * from class c, teacher t where c.teacher_id=t.t_id and  c.c_id=#{id}
</select>
<resultMap type="_Classes" id="ClassResultMap">
	<id property="id" column="c_id"/>
	<result property="name" column="c_name"/>
	<association property="teacher" javaType="_Teacher">
		<id property="id" column="t_id"/>
		<result property="name" column="t_name"/>
	</association>
</resultMap>

<!-- 
方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
	SELECT * FROM class WHERE c_id=1;
	SELECT * FROM teacher WHERE t_id=1   //1 是上一个查询得到的teacher_id的值
-->

 <select id="getClass2" parameterType="int" resultMap="ClassResultMap2">
	select * from class where c_id=#{id}
 </select>
 <resultMap type="_Classes" id="ClassResultMap2">
	<id property="id" column="c_id"/>
	<result property="name" column="c_name"/>
	<association property="teacher" column="teacher_id" select="getTeacher">
</association>
 </resultMap>
 
 <select id="getTeacher" parameterType="int" resultType="_Teacher">
	SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
 </select>


三、一对多的关联查询

3.1 增加学生表

CREATE TABLE student(
	s_id INT PRIMARY KEY AUTO_INCREMENT, 
	s_name VARCHAR(20), 
	class_id INT
);
INSERT INTO student(s_name, class_id) VALUES('xs_A', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_B', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_C', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_D', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_E', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_F', 2);

由于学生表的加入,创建Student实体类,并修改Classes类,class与student是一对多的关系。

public class Student {
	private int id;
	private String name;
}

public class Classes {
	private int id;
	private String name;
	private Teacher teacher;
	private List<Student> students;
}

3.2 定义映射文件

<!-- 
方式一: 嵌套结果: 使用嵌套结果映射来处理重复的联合结果的子集
SELECT * FROM class c, teacher t,student s WHERE c.teacher_id=t.t_id AND c.C_id=s.class_id AND  c.c_id=1
 -->
<select id="getClass3" parameterType="int" resultMap="ClassResultMap3">
	select * from class c, teacher t,student s where c.teacher_id=t.t_id and c.C_id=s.class_id and  c.c_id=#{id}
</select>
<resultMap type="_Classes" id="ClassResultMap3">
	<id property="id" column="c_id"/>
	<result property="name" column="c_name"/>
	<association property="teacher" column="teacher_id" javaType="_Teacher">
		<id property="id" column="t_id"/>
		<result property="name" column="t_name"/>
	</association>
	<!-- ofType指定students集合中的对象类型 -->
	<collection property="students" ofType="_Student">
		<id property="id" column="s_id"/>
		<result property="name" column="s_name"/>
	</collection>
</resultMap>

<!-- 
	方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
		SELECT * FROM class WHERE c_id=1;
		SELECT * FROM teacher WHERE t_id=1   //1 是上一个查询得到的teacher_id的值
		SELECT * FROM student WHERE class_id=1  //1是第一个查询得到的c_id字段的值
 -->
 <select id="getClass4" parameterType="int" resultMap="ClassResultMap4">
	select * from class where c_id=#{id}
 </select>
 <resultMap type="_Classes" id="ClassResultMap4">
	<id property="id" column="c_id"/>
	<result property="name" column="c_name"/>
	<association property="teacher" column="teacher_id" javaType="_Teacher" select="getTeacher2"></association>
	<collection property="students" ofType="_Student" column="c_id" select="getStudent"></collection>
 </resultMap>
 
 <select id="getTeacher2" parameterType="int" resultType="_Teacher">
	SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
 </select>
 
 <select id="getStudent" parameterType="int" resultType="_Student">
	SELECT s_id id, s_name name FROM student WHERE class_id=#{id}
 </select>


四、动态SQL与模糊查询

4.1 准备数据表

create table d_user(  
	id int primary key auto_increment,  
	name varchar(10),
	age int(3)
); 

insert into d_user(name,age) values('Tom',12);  
insert into d_user(name,age) values('Bob',13);  
insert into d_user(name,age) values('Jack',18);

需求:实现多条件查询用户(姓名模糊匹配, 年龄在指定的最小值到最大值之间)


4.2 查询条件实体类ConditionUser

private String name;
private int minAge;
private int maxAge;

4.3 表实体类User

private int id;
private String name;
private int age;

4.4 SQL映射文件userMapper.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.day03_mybatis.test6.userMapper">
<select id="getUser" parameterType="com.atguigu.day03_mybatis.test6.ConditionUser" resultType="com.atguigu.day03_mybatis.test6.User">
			select * from d_user where age>=#{minAge} and age<=#{maxAge}
		<if test='name!="%null%"'>and name like #{name}</if>
	</select>
</mapper>

4.5 测试

String statement = "com.atguigu.day03_mybatis.test6.userMapper.getUser";
List<User> list = sqlSession.selectList(statement, new ConditionUser("%a%", 1, 12));
System.out.println(list);

Mybatis中可用的动态SQL标签

Mybatis学习笔记_第1张图片


五、Mybatis缓存

正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持
1. 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。
2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。
3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。


5.1 一级缓存

一级缓存: 也就Session级的缓存(默认开启)


a. 一级缓存: 也就Session级的缓存(默认开启)

b. 查询条件是一样的

c. 没有执行过session.clearCache()清理缓存或者session.close()

d. 没有执行过增删改的操作(这些操作都会清理缓存)


5.2 二级缓存

只需要在userMapper.xml文件中添加一个标签,即启用二级缓存:

<cache/>  <!—映射文件级别的缓存 -->

5.3 补充说明

a. 映射语句文件中的所有select语句将会被缓存。 
b. 映射语句文件中的所有insert,update和delete语句会刷新缓存。 
c. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。 
d. 缓存会根据指定的时间间隔来刷新。 
e. 缓存会存储1024个对象

<cache 
eviction="FIFO"  //回收策略为先进先出
flushInterval="60000" //自动刷新时间60s
size="512" //最多缓存512个引用对象
readOnly="true"/> //只读


你可能感兴趣的:(mybatis)