最近开发进度进入平缓阶段,根据经验,这个时候正式调整优化的好时机,不然到后期做优化会很麻烦,于是静下心来琢磨对数据访问这块的优化问题。
项目已经开发了有将近两个月了,各种需求的变更导致数据库已经被改了N个版本了(移动互联网的痛)。建表的时候考虑到解耦和后期二次开发的问题就没有在数据库里做外键关联,把关联放到程序里做逻辑关联。太多的关联查询已经把已经写好的代码改的面目全非了,于是就考虑在sql查询的时候直接把所有一对多,一对一的关联信息全部查询出来。查阅了下之前前辈写的代码,结果发现前辈只写了一半就没有写了,后面都没有使用那段代码查询。没办法,那就只能靠自己摸索了,好了背景交代完毕,开写:
先从首页入手,大致的表结构我画了一个结构图,我要查询的是动态表,顺带要一对多的查询出动态对应的图片List及其中每个图片对应的Marker标记List和动态对应的评论List及其中每个评论人和回复人的用户信息,所以整个结构是一对多====》一对多===》一对一
1、一对多查询,下面引用别人已经写好的demo来做笔记
一对多中的"一"
<mapper namespace="dao.mapper.ClassMapper">
<resultMap id="classResultMap" type="Classes">
<id property="classid" column="classid1" />
<result property="classname" column="classname" />
<result property="teacherid" column="teacherid2" />
<collection property="studentList" column="classid" javaType="ArrayList" ofType="Student" select="StudentDao.getStudentByClassID" />
</resultMap>
<select id="selectAllByClassId" parameterType="int" resultMap="classResultMap">
select * from class c where c.classid = #{classid};
</select>
</mapper>
一对多中的"多"
<mapper namespace="StudentDao">
<resultMap type="Student" id="studentResultMap">
<id property="studentid" column="studentid" />
<result property="studentname" column="studentname" />
</resultMap>
<!-- 查询学生list,根据班级id -->
<select id="getStudentByClassID" parameterType="String" resultMap="studentResultMap">
select *from student st WHERE st.classid = #{classid1}
</select>
</mapper>
除了这种写法外,还有另外一种就是把两个写在一个xml里,但是看起来感觉很混乱,不是我喜欢的风格。上面代码里的class就是我的动态表,student就是我的动态图片表,一个班里有很多学生相当于我的一个动态有很多图片。在class加一个studenList字段来映射查询出来的结果,classid可以很明显的看出是取出结果里的一个值,传给getStudenByClassId,这样就是在A.xml里调用了B.xml里的这个查询方法,这段执行完成后在返回的结果里可以看到studenList里已经有值了,而且跟数据库里的记录是一直的,就说明这个一对多的查询成功了。
2、一对一查询,这个就更简单了,同样引用一段Demo代码
<mapper namespace="dao.mapper.ClassMapper">
<resultMap id="classResultMap" type="Classes">
<id property="classid" column="classid1" />
<result property="classname" column="classname" />
<result property="teacherid" column="teacherid2" />
<association property="teacher" column="teacherid" javaType="Teacher" select="getTeacher" />
<!-- <association property="teacher" column="teacherid" javaType="Teacher" select="dao.mapper.TeacherMapper.getTeacher" /> 两个XML文件之间调用 -->
</resultMap>
<select id="selectAllByClassId" parameterType="int" resultMap="classResultMap">
select * from class c where c.classid = #{classid};
</select>
<select id="getTeacher" parameterType="int" resultType="teacher">
select * from teacher tt where tt.teacherid = #{teacherid2}
</select>
</mapper>
一对一的查询也可以用两种方法,这个里面把两个xml之间调用的方法注释掉了,用的是在一个xml里做一对一的查询,大致的原理跟上面一样,要注意是两个类型是collection一个是association
3、一对多、一对一混合使用,上面两个都整出来了,这个就更不是问题了,在一对多里调用多的那个xml里使用一对一。反之一样。