MyBatis 一对多和多对一的关系
配置和jar包
MyBatisConfig和MyBatisUtils(SqlSessionFactory工厂)配置和一对一配置一样,详情见一对一配置,架包也一样
实体类
-
public class Classes {
-
private int cid;
-
private String cname;
-
private String cdate;
-
-
List<Student> stus;
-
public class Student {
-
private int sid;
-
private String sname;
-
private String sex;
-
private int age;
-
private String addr;
-
private String birth;
-
private int cid;
-
private String major;
-
-
private Classes classes;
方法一:Mapper配置文件
mapper.xml配置
-
"1.0" encoding="UTF-8" xml version=
-
-
-
-
<mapper namespace="test">
-
<!-- 一对多 -->
-
<resultMap type="Classes" id="Classess" >
-
<id column="cid" property="cid" />
-
<collection property="stus" column="cid" select="findStudent" />
-
</resultMap>
-
<select id="findStudent" parameterType="int" resultType="Student">
-
select * from Student where cid=#{value}
-
</select>
-
<select id="seeAll" resultMap="Classess">
-
select * from Classes
-
</select>
-
-
<!-- 多对一 -->
-
<resultMap type="Student" id="seeStudents">
-
<id column="sid" property="sid" />
-
<association property="classes" column="cid" select="seeClasses" />
-
</resultMap>
-
<select id="seeClasses" resultType="Classes" parameterType="int" >
-
select * from Classes where cid=#{value}
-
</select>
-
<select id="seeAllStudents" resultMap="seeStudents">
-
select * from student
-
</select>
-
</mapper>
-
//一对多
-
Test.junit.
-
public void test () throws Exception {
-
SqlSession session = MyBatisUtils.getSqlSession();
-
List<Classes> list = session.selectList( "test.seeAll");
-
for(Classes cl:list){
-
System.out.println(cl);
-
for(Student s:cl.getStus()){
-
System.out.println(s);
-
}
-
}
-
}
-
//多对一
-
Test.junit.
-
public void test2 () throws Exception {
-
SqlSession session = MyBatisUtils.getSqlSession();
-
List<Student> list = session.selectList( "test.seeAllStudents");
-
for(Student st:list){
-
System.out.println(st+ "____"+st.getClasses());
-
}
-
}
方法二:注解方式
接口类
一对多(ClassesDao)
-
package com.mingde.dao;
-
-
import java.util.List;
-
-
import org.apache.ibatis.annotations.Many;
-
import org.apache.ibatis.annotations.Result;
-
import org.apache.ibatis.annotations.ResultMap;
-
import org.apache.ibatis.annotations.Results;
-
import org.apache.ibatis.annotations.Select;
-
import org.apache.ibatis.mapping.FetchType;
-
-
import com.mingde.po.Classes;
-
-
public interface ClassesDao {
-
-
//查询所有
-
"select * from Classes")(
-
//定义ResultMap
-
"ClassesResult",value={(id=
-
"cid",property= "cid"),(column=
-
"cid",property= "stus",many= (select= "com.mingde.dao.StudentDao.findStudents",fetchType=FetchType.LAZY))(column=
-
})
-
public List<Classes> SeeAllClasses()throws Exception;
-
-
//根据id查询
-
"select * from Classes where cid=#{value}")(
-
"ClassesResult") //引入上面定义的ResultMap(
-
public Classes findClasses(int cid)throws Exception;
-
}
多对一(StudentDao)
-
package com.mingde.dao;
-
-
import java.util.List;
-
-
import org.apache.ibatis.annotations.One;
-
import org.apache.ibatis.annotations.Result;
-
import org.apache.ibatis.annotations.ResultMap;
-
import org.apache.ibatis.annotations.Results;
-
import org.apache.ibatis.annotations.Select;
-
import org.apache.ibatis.mapping.FetchType;
-
-
import com.mingde.po.Student;
-
-
public interface StudentDao {
-
-
//根据班级cid查询
-
"select * from student where cid=#{value}")(
-
public List<Student> findStudents(int cid)throws Exception;
-
-
//查询所有
-
"select * from student")(
-
"findClasses",value={ //定义ResultMap(id=
-
"sid",property= "sid"),(column=
-
"cid",property= "classes",one= (select= "com.mingde.dao.ClassesDao.findClasses",fetchType=FetchType.LAZY))(column=
-
})
-
public List<Student> SeeStudents()throws Exception;
-
-
//根据学生sid查询
-
"select * from student where sid=#{value}")(
-
"findClasses") //引用上面的ResultMap(
-
public Student findStudentById(int sid)throws Exception;
-
-
}
注意:上面的配置是即配置一对多也配置多对一,这里是为了学者学习;但一般配置一对多后,就不会多对一,因为这样互相配置后会产生循环加载,导致内存溢出
测试类
-
//注解一对多
-
Test.junit.
-
public void test3 () throws Exception {
-
//获取工厂,连接接口使用方法
-
SqlSession session = MyBatisUtils.getSqlSession();
-
ClassesDao mapper = session.getMapper(ClassesDao.class);
-
//查询所有
-
List<Classes> seeAllClasses = mapper.SeeAllClasses();
-
for(Classes c:seeAllClasses){
-
System.out.println(c);
-
for(Student st:c.getStus()){
-
System.out.println(st);
-
}
-
}
-
//根据id查询
-
Classes findClasses = mapper.findClasses( 1);
-
System.out.println(findClasses);
-
System.out.println(findClasses.getStus());
-
}
-
//注解多对一
-
Test.junit.
-
public void test4 () throws Exception {
-
//获取工厂,连接接口使用方法
-
SqlSession session = MyBatisUtils.getSqlSession();
-
StudentDao mapper = session.getMapper(StudentDao.class);
-
//查询所有
-
List<Student> seeStudents = mapper.SeeStudents();
-
for(Student s:seeStudents){
-
System.out.println(s+ "______"+s.getClasses());
-
}
-
//根据id查询
-
Student st = mapper.findStudentById( 1126);
-
System.out.println(st);
-
System.out.println(st.getClasses());
-
}
总结:
1、在Mapper.xml配置中一对一和多对一的映射关联用:association,一对多和多对多用collection
2、一般配置一对多后,就不会多对一,因为这样互相配置后会产生循环加载,导致内存溢出
3、配置一对多或多对一的依赖关系,主要抓住配置二者的主键和外建,如:
-
//查询所有
-
"select * from student")(
-
"findClasses",value={ //定义ResultMap(id=
-
"sid",property= "sid"), //主键,下面的是外建(column=
-
"cid",property= "classes",one= (select= "com.mingde.dao.ClassesDao.findClasses",fetchType=FetchType.LAZY))(column=
-
})
-
public List<Student> SeeStudents()throws Exception;
-
<!-- 一对多 -->
-
<resultMap type="Classes" id="Classess" >
-
<id column="cid" property="cid" /> //主键id
-
<collection property="stus" column="cid" select="findStudent" /> //外建
-
</resultMap>
-