实体类:
import lombok.Data; @Data public class Student { private int id; private String name; private Teacher teacher; }
import lombok.Data; @Data public class Teacher { private int id; private String name; }
Studentmapper接口:
public interface Studentmapper { public List<Student> getStudent(); }
Studentmapper.xml映射文件
按照查询嵌套查询 <select id="getStudent" resultMap="StudentTeacher"> select * from student </select> <resultMap id="StudentTeacher" type="entity.Student"> <result property="id" column="id"/> <result property="name" column="name"/> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap> <select id="getTeacher" resultType="Teacher" > select * from teacher where id=#{tid} </select> 按照查询结果嵌套查询 <select id="getStudent" resultMap="Studentteacher"> select s.id sid,s.name sname,t.id tid,t.name tname from student s,teacher t where s.tid=t.id; </select> <resultMap id="Studentteacher" type="entity.Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <association property="teacher" javaType="entity.Teacher"> <result property="id" column="tid"/> <result property="name" column="tname"/> </association> </resultMap>
Test测试类
public void getTeacher(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); Studentmapper mapper = sqlSession.getMapper(Studentmapper.class); List<Student> student = mapper.getStudent(); for (Student student1 : student) { System.out.println(student1); } sqlSession.commit(); sqlSession.close();
查询结果:
Student(id=1, name=董xx, teacher=Teacher(id=1, name=老王))
Student(id=2, name=李沫x, teacher=Teacher(id=1, name=老王))
Student(id=3, name=马x林, teacher=Teacher(id=1, name=老王))
Student(id=4, name=马x狗, teacher=Teacher(id=2, name=老哥))
Student(id=5, name=李狗x, teacher=Teacher(id=2, name=老哥))
实体类
@Data public class Student { private int id; private String name; private int tid; }
因为是多对一,一个老师下面有很多学生,所以属性有一个学生集合。
@Data public class Teacher { private int id; private String name; private List<Student> students; }
Teachermapper接口:
public interface Teachermapper { Teacher getTeacher(@Param("tid") int id); }
Teachermapper.xml文件:
因为一个老师有多个学生,所以
<select id="getTeacher" resultMap="teacherStudent"> select s.id sid,s.name sname, t.id tid,t.name tname 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"/> <collection property="students" ofType="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="tid"/> </collection> </resultMap>
Test测试类
@Test public void getTeacher(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); Teachermapper mapper = sqlSession.getMapper(Teachermapper.class); Teacher teacher = mapper.getTeacher(1); System.out.println(teacher); sqlSession.commit(); sqlSession.close(); } }
查询结果
Teacher(id=1, name=老王, students=[Student(id=1, name=董瑞龙, tid=1), Student(id=2, name=李沫璇, tid=1), Student(id=3, name=马嘉林, tid=1)])
作用:标签用if标签进行判断然后拼接,用if标签时,要给原本的SQL语句后加一个"where 1=1" 以便后面进行SQL拼接。
Bookmapper接口:
public interface Bookmapper { List<Book> dongtaisqlIF(Map<String,String> map); }
Bookmapper.xml文件:
<select id="dongtaisqlIF" parameterType="map" resultType="Book" > select * from book where 1=1 <if test="title!=null"> and title =#{title} </if> <if test="author!=null"> and author =#{author} </if> </select>
Test测试类:
public void dongtaisqlIF() { SqlSession sqlSession = MybatisUtil.getSqlSession(); Bookmapper mapper = sqlSession.getMapper(Bookmapper.class); Map<String,String> map=new HashMap<>(); map.put("title","语文书"); List<Book> books = mapper.dongtaisqlIF(map); for (Book book : books) { System.out.println(book); } sqlSession.commit(); sqlSession.close(); }
查询结果
ook(id=4558e13487194a4196e2876f3ea72097, title=语文书, author=董瓜皮, createTime=Thu Oct 21 16:31:40 CST 2021, views=123)
Book(id=624ba970bac949f3a257c83a3d54b3de, title=语文书, author=董瓜皮, createTime=Thu Oct 21 16:28:05 CST 2021, views=2000)
根据刚才的动态sql语句我们可以得知我们经常在动态构造sql时,为防止注入或防止语句不当时会使用where 1=1,但这并不合适。所以我们引入了where标签。
where标签会知道如果它包含的标签中有返回值的话,它就会插入一个‘where’。此外,如果标签返回的内容是以AND 或OR开头的,则会把它去除掉。
<select id="dongtaisqlIF" parameterType="map" resultType="Book" > select * from book <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>
进入choose标签之后,按顺序只对一个标签中的sql语句进行查找,若都不满足则对中的语句进行查找。
例1:我传入三个数据,但是只对title进行了查询。
public void dongtaisqlIF() { SqlSession sqlSession = MybatisUtil.getSqlSession(); Bookmapper mapper = sqlSession.getMapper(Bookmapper.class); Map<String,String> map=new HashMap<>(); map.put("title","语文书"); map.put("author","皮"); map.put("views","1000"); List<Book> books = mapper.dongtaisqlIF(map); for (Book book : books) { System.out.println(book); } sqlSession.commit(); sqlSession.close(); }
返回的结果是title为语文书的所有对象
Book(id=4558e13487194a4196e2876f3ea72097, title=语文书, author=董瓜皮, createTime=Thu Oct 21 16:31:40 CST 2021, views=123)
Book(id=624ba970bac949f3a257c83a3d54b3de, title=语文书, author=董瓜皮, createTime=Thu Oct 21 16:28:05 CST 2021, views=2000)
sql片段可以用来解决重复造轮子的问题
<sql id="hhhhh" > <if test="title!=null"> and title =#{title} </if> <if test="author!=null"> and author =#{author} </if> </sql>
使用标签将需要复用的sql片段插入。
<select id="dongtaisqlIF" parameterType="map" resultType="Book" > select * from book <where> <include refid="hhhhh"></include> </where> </select>
open:开始的标志
close:结束的标志
separator:用什么隔开
collection:
item:
<select id="FOReach" parameterType="map" resultType="book"> select * from book <where> <foreach collection="ids" item="id" open="(" close=")" separator="or"> id=#{id} </foreach> </where> </select>
测试文件:
public void FOReach(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); Bookmapper mapper = sqlSession.getMapper(Bookmapper.class); HashMap map = new HashMap<>(); ArrayList<Integer> ids= new ArrayList<>(); ids.add(1); map.put("ids",ids); List<Book> books1 = mapper.FOReach(map); for (Book book : books1) { System.out.println(book); }
开始
接口:
public interface Teachermapper { Teacher getTeacher( int id); }
映射文档:
<select id="getTeacher" parameterType="java.lang.Integer" resultType="entity.Teacher"> select * from teacher where id =#{tid} </select>
测试类:
public void getTeacher(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); Teachermapper mapper = sqlSession.getMapper(Teachermapper.class); Teacher teacher = mapper.getTeacher(1); Teacher teacher2 = mapper.getTeacher(1); System.out.println(teacher); System.out.println("====================="); System.out.println(teacher2); System.out.println(teacher==teacher2); }
我们可以看到我们的sql只执行了一次,但是我们的两次查询结果是相同的,也就是说第二次的查询直接是在缓存中读取的。
(1)开启全局缓存
<settings> <setting name="cacheEnabled" value="true"/> </settings>
(2)在要使用二级缓存的mapper中使用
(3)二级缓存工作原理
用户先读取二级缓存再读取一级缓