OneToMany
1.在”one”的实体类总添加many的一对多关系:
private List<Student> studentList;//(get和set方法略)
2.在”many”的配置文件中添加查询的方法:
<!--老师关联学生-->
<select id="selectStudentByTeacherId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select * from student where teacher_id=#{teacherId,jdbcType=INTEGER}
</select>
<!--
id为查询的id,自己取个名;
parameterType为参数类型;
resultMap为查询结果转换为java的类属性
-->
3.在”one”的配置文件的resultMap中添加一个集合:
<!--OneToMany老师关联学生-->
<collection property="studentList" column="teacher_id" ofType="com.shinowit.entity.Student" select="com.shinowit.dao.mapper.StudentMapper.selectStudentByTeacherId">
</collection>
<!--
property为one中实体类添加的集合的pojo对象;
column为根据哪个字段查询,一般是one的主键;
ofType为单个查询结果的数据类型;
select为many的配置文件的<mapper>标签的namespace+many中刚才添加的查询方法的id:namespace+selectStudentByTeacherId
-->
4.编写单元测试
@Resource
private Teacher1Mapper teacher1DAO;
protected final Logger logger = Logger.getLogger(getClass());
@Test
public void test1() {
Teacher1 teacher11=teacher1DAO.selectByPrimaryKey(1);
for(Student stu:teacher11.getStudentList()){
logger.debug(stu.getName());
}
}
ManyToOne
1.在”many”的实体类总添加one的多对一关系:
private Teacher1 tea;//(get和set方法略)
2.在many的配置文件中添加映射的关联(association):
(因为查many的数据本质是从xml文件查的,所以要在xml文件中把刚才的tea字段添加到映射result中)
<!--关联老师-->
<association property="tea" column="teacher_id" javaType="com.shinowit.entity.Teacher1" select="com.shinowit.dao.mapper.Teacher1Mapper.selectByPrimaryKey"/>
<!--
property为many实体类中添加的pojo对象;
column意思是用哪个字段去做关联查询;
javaType为这个字段是什么类型的;
select为数据取出的方法,用one的配置文件的<mapper>标签的namespace+one中的根据主键查询的方法id:namespace+selectByPrimaryKey
-->
3.编写单元测试
@Resource
private StudentMapper studentDAO;
protected final Logger logger = Logger.getLogger(getClass());
@Test
public void test1() {
Student stu=studentDAO.selectByPrimaryKey(2);//ManyToOne查学生信息,会把老师信息一同查出
logger.debug(stu.getTea().getName());
}
解决N+1查询问题
方法一:
在one的<mapper>标签下添加一个<cache/>标签
方法二:
1. 在many的实体类中添加要附带查出来的字段,如:
private String teacherName;//(get和set方法略)
2.在many的Mapper中添加一个接口,如:
List<Student> selectStudentWithTeacherNameByPrimaryKey(Integer student_id);
3.在many的xml文件最下面新添加一个和一个,如:
<!--解决N+1问题-->
<resultMap id="resultMapWithTeacherName" type="com.shinowit.entity.Student" extends="BaseResultMap">
<result column="teacher_name" property="teacherName" jdbcType="VARCHAR"/>
</resultMap>
<!--
type为实体类类型
extends="BaseResultMap"就照着抄上面的就行
column是要查询的对应的数据库的字段
property是实体类的pojo对象对应的数据库的字段类型
-->
<!--解决N+1问题的查询-->
<select id="selectStudentWithTeacherNameByPrimaryKey" parameterType="java.lang.Integer" resultMap="resultMapWithTeacherName">
select a.*,b.name as teacher_name from student a inner join teacher1 b on a.teacher_id=b.teacher_id where student_id=#{student_id,jdbcType=INTEGER}
</select>
<!--
id是接口中的方法名
resultMap是上面<resultMap>的id
中间的sql语句的{}中的student_id是接口中的参数
-->
4.编写单元测试
@Resource
private StudentMapper studentDAO;
protected final Logger logger = Logger.getLogger(getClass());
@Test
List<Student> studentList=studentDAO.selectStudentWithTeacherNameByPrimaryKey(1);
//用自己写sql语句的方法解决N+1查询问题 logger.debug(studentList.get(0).getTeacherName());
}
注:尽量少用collection 和association 标签,因是他是N+1查询,而hibernate就是N+1查询
方法二扩展:
1.在many的实体类中添加要附带查出来的字段,如:
private String teacherName;//(get和set方法略)
2.在many的Mapper中添加一个接口,如:
List<Student> selectStudentWithTeacherNameByPrimaryKey(StudentExample example);
3.在many的xml文件最下面新添加一个和一个,如:
<!--解决N+1问题-->
<resultMap id="resultMapWithTeacherName" type="com.shinowit.entity.Student" extends="BaseResultMap">
<result column="teacher_name" property="teacherName" jdbcType="VARCHAR"/>
</resultMap>
<!--解决N+1问题的查询-->
<select id="selectStudentWithTeacherNameByPrimaryKey" parameterType="com.shinowit.entity.StudentExample" resultMap="resultMapWithTeacherName">
select *,(select name from teacher1 where teacher1.teacher_id=student.teacher_id) as teacher_name from student
<if test="_parameter != null">
<include refid="Example_Where_Clause"/>
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
4.编写单元测试
@Resource
private Teacher1Mapper teacher1DAO;
protected final Logger logger = Logger.getLogger(getClass());
@Test
public void test1() {
StudentExample ex=new StudentExample();//比较复杂的用StudentExample作参数的方法解决N+1问题
ex.createCriteria().andTeacherIdEqualTo(1);
List<Student> studentList=studentDAO.selectStudentWithTeacherNameByPrimaryKey(ex);
for(Student student:studentList){
logger.debug(student.getTeacherName());
}}
版权声明:本文为d470969047h原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。