环境准备
-
两个很简单的表,学生表记录了老师的pk
-
以下两个实体类,学生表记录了老师的pk---->Teacher的id是Student的tid。
//省略了无参、有参构造、get、set、重写toString public class Student { private int id; private String name; private int tid; } public class Teacher { private int id; private String name; }
1.假如需求是查出每个学生的信息和对应老师的名字,那么sql语句应该是
select s.*,t,name from student s,teacher t where s.tid = t.id
2.直接把结果放在map里面就可以了
-
Mapper.xml
<mapper namespace="com.rzp.dao.StudentMapper"> <select id="getByTeacher" resultType="map"> select s.*,t.name as tname from student s,teacher t where t.id = s.tid </select> </mapper>
- Mapper接口
public interface StudentMapper { List<HashMap> getByTeacher(); }
-
测试
@Test public void getByTeacher(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<HashMap> studentList = mapper.getByTeacher(); for (Map student : studentList) { //通过get方法可以直接取出来 System.out.print(student.get("id")+" "); System.out.print(student.get("name")+" "); System.out.print(student.get("tid")+" "); System.out.print(student.get("tname")+" "); System.out.println(); } sqlSession.close(); }
3.这个方式如果只是做一些统计应该会比较好用,但是如果像这种情况还不如直接在Student里加一个temp属性,这样还能直接把List的泛型设置为Student,操作Student时还更方便。
4.但是以下两种情况就不好用了:
-
如果实体类里的属性是另一个实体类对象时,比如Student里有一个Teacher对象的属性。
-
又或者是实体类里的属性是另一个实体类的容器,比如Teacher里有一个Student的List。
-
这时候就要使用结果集映射的对象(associtation )和集合(collection)属性。
-
我的理解其实就是把普通结果集映射的properties替换成associtation而已,感觉就像是在xml文件里也定义了一个实体类,其中对象要用associtation来定义。
associtation
一、按照查询嵌套处理
-
Student里给了Teacher对象
//省略了无参、有参构造、get、set、重写toString public class Student { private int id; private String name; private int tid; private Teacher teacher; } public class Teacher { private int id; private String name; }
-
Mapper接口
public interface StudentMapper { //获取所有学生的信息 List<Student> getAllStudent(); }
-
Mapper.xml
<mapper namespace="com.rzp.dao.StudentMapper"> <!--查询所有学生和对应的老师,思路: 1.查询所有的学生信息 2.根据查询出来的学生tid寻找对应的老师 --> <select id="getAllStudent" resultMap="StudentMap"> select * from student </select> <resultMap id="StudentMap" type="Student"> <!--复杂的属性,需要单独处理 对象:associtation 集合:collection--> <!--结果集映射中定义一个“对象”(associtation)属性 property---student中这个对象的名称 javaType---student中这个对象的类 select---获取这个对象的查询语句(方法) column---使用这个语句要输入的参数,多个是column="{prop1=col1,prop2=col2}" --> <association property="teacher" column="tid" javaType="Teacher" select="getAllStudendTest"/> </resultMap> <select id="getAllStudendTest" resultType="Teacher"> select * from teacher where id = #{id} </select> </mapper>
-
测试方法
//查询所有学生 @Test public void getAllTeacher(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Student> studentList = mapper.getAllStudent(); for (Student student : studentList) { System.out.println(student); } sqlSession.close(); }
-
这个方式个人感觉不太符合一般联表查询的思维,更加像嵌套子查询。
二、按照结果嵌套处理
-
Mapper接口
//按照结果嵌套处理 List<Student> getAllStudent2();
-
Mapper.xml
<select id="getAllStudent2" resultMap="StudentMap2"> select s.id,s.name,s.tid,t.name tname from student s,teacher t where s.tid = t.id </select> <resultMap id="StudentMap2" type="Student"> <result property="id" column="id"/> <result property="name" column="name"/> <result property="tid" column="tid"/> <association property="teacher" javaType="Teacher"> <result property="name" column="tname"/> </association> </resultMap>
-
测试
//查询所有学生2 @Test public void getAllTeacher2(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Student> studentList = mapper.getAllStudent2(); for (Student student : studentList) { System.out.println(student); } sqlSession.close(); }
-
备注:测试结果之中,teacher对象的id是0,个人觉得这个很像一个有参构造器。
collection
三、按照结果嵌套处理
-
实体类
public class Student { private int id; private String name; private int tid; } public class Teacher { private int id; private String name; private List<Student> studentsList; }
-
Mapper.xml
<!--按结果嵌套查询--> <select id="getTeacherById" resultMap="TeacherMap"> select s.*,t.name tname from student s,teacher t where s.tid = t.id and t.id = #{tid} </select> <resultMap id="TeacherMap" type="Teacher"> <result property="name" column="tname"/> <collection property="studentsList" ofType="Student" > <result property="id" column="id"/> <result property="name" column="name"/> <result property="tid" column="tid"/> </collection> </resultMap>
-
Mapper接口
Teacher getTeacherById(@Param("tid") int id);
-
测试
@Test public void test1(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = mapper.getTeacherById(1); System.out.println(teacher); sqlSession.close(); }
四、按查询嵌套处理
-
Mapper.xml
<!--按查询嵌套处理--> <select id="getTeacherById2" resultMap="TeacherMap1"> select t.* from teacher t where t.id = #{id} </select> <resultMap id="TeacherMap1" type="Teacher"> <result property="id" column="id"/> <!--ofType--泛型--> <collection property="studentsList" javaType="ArrayList" ofType="Student" column="id" select="getStudent"/> </resultMap> <select id="getStudent" resultType="Student"> select * from student where tid = #{id} </select>
-
Mapper接口
Teacher getTeacherById2(int id);
-
测试
@Test public void test2(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = mapper.getTeacherById2(1); System.out.println(teacher); sqlSession.close(); }
对比
-
按结果查询,sql复杂,查询次数少,xml结构简单。
-
按查询嵌套处理,sql简单,查询了多次,xml结构复杂。