文章目录
- 解决一对多数据问题
-
- 关联的嵌套 Select 查询
- 关联的嵌套结果映射
- 解决一对多问题
-
- 集合的嵌套Select查询
- 集合的嵌套结果映射
- 小结
解决一对多数据问题
- 在一对多的数据表结构中,比如一个老师教育着很多学生, 对于学生而言, 这就是一个一对多的问题
- 这个主要解决的就是如果我们的POJO对象的属性中,有一个是引用类型,不是基本类型或者String, 那么简单的sql语句肯定是解决不了的
- 学生类型
public class Student {
private int id;
private String name;
private Teacher teacher;
}
- 老师类型
public class Teacher {
private int id;
private String name;
}
- 比如我们现在有一个需求, 要查找数据库中所有的学生对象, 该如何做?
关联的嵌套 Select 查询
<select id="selectStudent" resultMap="studentTeacher">
select * from student;
</select>
<resultMap id="studentTeacher" type="student">
<association property="teacher" javaType="teacher" column="tid" select="selectOneTeacher"/>
</resultMap>
<select id="selectOneTeacher" resultType="teacher">
select * from teacher where id=#{ tid};
</select>
- 带你解读一下上面的代码, 首先id对应的是我们dao层接口的方法 ,返回值类型我们初始设置成resultmap, 首先查到的是数据库学生表的所有信息
- 然后到resultMap标签里, 这里的id要对应上述我们设置的resultMap的名子, 这个这个返回类型就是真实的返回类型, 所以是student, 其中student的id和name已经自动映射好了, 不需要我们再次建立映射关系, 最重要的就是teacher对象的映射, 我们使用association标签,property映射到student类型的teacher引用名, Javatype表示返回的是一个teacher类型, column表示所查到的学生信息中的tid要去这个老师对象建立连接, select表示调用下面的select语句
- 在最下面的select语句中,返回类型是teacher类型与上面进行对应, 在sql语句中通过上面的column设定的列的值进行对应建立连接
- 最后就是返回student这个对象
关联的嵌套结果映射
<select id="selectStudent2" 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 column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="teacher">
<result column="tname" property="name"/>
</association>
</resultMap>
- 使用这个代码易懂, 但是sql语句会变得复杂
- 一开始我们便使用很长的sql语句建立老师和学生的连接将所有信息查询出来
- 所以在resultmap中我们只需要将这些信息进行结果映射即可, 但是要注意引用类型的结果映射还得在association元素内使用, 还需指定返回的类型
- 注意我没有设置老师id的这个属性的映射关系, 所以查到显示的肯定是这个数据类型的默认值
解决一对多问题
- 还是最开始的那个例子, 一个老师教育很多学生, 对于老师而言这就是一对多的关系, 但是在这里我想复杂一下就是一个班级既有老师,又有学生, 也就是既有引用类型, 又有集合类型, 这种该如何查询
- 好, 我现在有一个需求 ,我指定老师的id 要得到这个教室的所有信息, 包括老师的信息和所有学生的信息
- 教室类型
public class ClassRoom {
private Teacher teacher;
private List<Student> students;
}
集合的嵌套Select查询
<select id="getClassRoom" parameterType="_int" resultMap="classRoomMap">
select * from teacher where id=#{ tid};
</select>
<resultMap id="classRoomMap" type="classRoom">
<association property="teacher" javaType="teacher">
<result column="id" property="id"/>
<result column="name" property="name"/>
</association>
<collection property="students" javaType="ArrayList" ofType="student" column="id" select="students"/>
</resultMap>
<select id="students" resultType="student">
select id, name from student where tid=#{ id};
</select>
- 首先最开始id对象方法名是getClassRoom, 通过老师的id查找, 所以会有一个参数parameterType是int型的, 初步返回类型是resultmap, 在初步的sql语句中,我通过老师的id找到这个老师的所有信息
- 在resultMap的对应名称classRoomMap里, 我指定返回类型当然是一个classroom类型, 接下来就是使用association元素对老师这个引用进行属性建立映射关系
- 接下来使用collection这个元素对学生这个集合进行构造, 首先明确使用collection这个元素, 你首先是要与classroom的属性名建立映射练习, 然后必须指定javatype和oftype, javatype是java中的什么集合类型, oftype是指定这个集合类型中的泛型参数的什么类型的,这个很重要, 然后column指定通过什么数据与后面的select建立联系
- 在最后的select中, 我们通过上述column传来的teacher的id与所有学生的替代建立联系, 查到对应要求的信息, 返回student类型, 值此再返回classRoom这个类型的查询结果
集合的嵌套结果映射
- 这里需要改一个东西, 就是如果要满足我们的需求, 使用上面的classroom类型如果使用集合的嵌套结果映射在SQL层面是实现不了的, 所以得把classroom的数据类型改一下
- 新的教室类型
public class ClassRoom {
private int tid;
private String tname;
private List<Student> students;
}
- ok
<select id="getClassRoom2" parameterType="_int" resultMap="classRoomMap2">
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="classRoomMap2" type="classRoom">
<result column="tid" property="tid"/>
<result column="tname" property="tname"/>
<collection property="students" javaType="ArrayList" ofType="student">
<result column="sid" property="id"/>
<result column="sname" property="name"/>
</collection>
</resultMap>
- 只要使用的是结果集的映射, 就是一开始就将所有信息都查出来, 然后在一个resultMap中进行属性名与数据库表中列的字段名建立连接
- 但是还是要注意这里的sql语句是比上面的复杂的, 而且要留意只要使用collection元素, 就必须设置其中的Javatype和oftype, 这点很重要
小结
- 关联association, 用于属性中有对象时使用, 用于一对多的环境
- 集合collection, 用于属性中有集合类型的时候使用,用于多对一的环境
- javatype, 用来指定java中指定实体属性中的类型, 就好比这个指定的是List类型
- oftype, 用来指定映射到java指定实体属性集合中泛型的具体类型,这个指定的就是List中Studente类型
- 如果需要使用引用类型, association, 只需注明属性名称, 注明javatype, 然后在里面进行设置值即可
- 如果是集合类型,使用collection,注明属性名称, 注明javatype类型, 和集合类型里面的泛型类型oftype, 然后在里面result值即可.
注意点:
- 保证sql的可读性, 尽量保证通俗易懂
- 注意多对一和一对多中属性名和字段名的匹配问题, 多用于日志