mybatis高级查询 一对一 多对一

Mybatis使用标签

<association> :一的一方配置<association>标签  对应返回值单个实体

<collection>:多的一方配置<collection>:标签       对应返回值集合

根据实体类的定义,如果是属性集合就配置<collection>,如果返回的数据是一个实体的就配置<association >

1. 根据数据库的关系创建实体类

多表查询时,需要一个实体类多个表的数据.那么需要将表与表的关系,也要反应在实体类与实体类之间的关系.

配置一条数据的一方,使用实体类的引用

配置多条数据的一方,使用List集合

 

地址表

 

public class Address {
    private Integer aid;
    private String aname;
    private Student student;
    public Student getStudent() {
    return student;
    }
    public void setStudent(Student student) {
    this.student = student;
    }
    public String getAname() {
    return aname;
    }
    public void setAname(String aname) {
    this.aname = aname;
    }
    public Integer getAid() {
    return aid;
    }
    public void setAid(Integer aid) {
    this.aid = aid;
	}
 
 
}

 

学生表

public class Student {
    private Integer sid;//int(11) not null auto_increment comment '编号',
    private Integer aid;//int(11) null default '0',
    private String sname;//varchar(50) null default null comment '姓名',


    private String sex;//char(3) null default null comment '性别',
    private Date birthday;//date null default null comment '生日',
    private Integer age;//int(11) null default null comment '年龄',
    //假定一个地址对应一个学生,那么这里就配置一个实体类
    private Address address;
    //多的一方,使用集合
    private List<Course> courses;
    public List<Course> getCourses() {
    return courses;
    }
    public void setCourses(List<Course> courses) {
    this.courses = courses;
    }
    public Address getAddress() {
    return address;
    }
    public void setAddress(Address address) {
    this.address = address;
    }
    public Integer getSid() {
    return sid;
    }
    public void setSid(Integer sid) {
    this.sid = sid;
    }
    public Integer getAid() {
    return aid;
    }
    public void setAid(Integer aid) {
    this.aid = aid;
    }

    public String getSex() {
    return sex;
    }
    public void setSex(String sex) {
    this.sex = sex;
    }
    public Date getBirthday() {
    return birthday;
    }
    public void setBirthday(Date birthday) {
    this.birthday = birthday;
    }
    public Integer getAge() {
    return age;
    }
    public void setAge(Integer age) {
    this.age = age;
    }
    public String getSname() {
    return sname;
    }
    public void setSname(String sname) {
    this.sname = sname;
    }
}

课程表

public class Course {
    private Integer cid;//int(11) not null auto_increment comment '科目编号',
    private Integer sid;//int(11) null default null comment '学生编号',
    private Integer tid;//int(11) null default null comment '教师编号',
    private String courseName;//varchar(50) null default null comment '科目名',
    public Integer getCid() {
    return cid;
    }
    public void setCid(Integer cid) {
    this.cid = cid;
    }
    public Integer getSid() {
    return sid;
    }
    public void setSid(Integer sid) {
    this.sid = sid;
    }
    public Integer getTid() {
    return tid;
    }
    public void setTid(Integer tid) {
    this.tid = tid;
    }
    public String getCourseName() {
    return courseName;
    }
    public void setCourseName(String courseName) {
    this.courseName = courseName;
    }
}

 

association标签

接口代码

 
public interface StudentMapper {
 
    /**
     * 查询所有的学生信息,并包括地址信息
     * @return
     */
    List<Student> findStudentAndAddress();
    /**
     * 查询所有的学生信息,并包括地址信息
     * @return
     */
    List<Student> findStudentAndAddress1();
    /**
     * 查询学生的信息,包括学生选择的课程
     * @return
     */
    List<Student> findStudentAndCourse();
    /**
     * 查询多个个表,将数据放在map里面
     * @return
     */
    List<Map<String,Object>> findStudentAndCourseToMap();
 
}

映射文件代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd" >
<!-- 命名空间,用于指定动态创建的对象返回的映射接口 -->
<mapper namespace="cn.mapper.StudentMapper">
 
   <!-- #查询学生的信息,并且包括学生的学习的课程 -->
   <resultMap type="Student" id="studentAndCourseResultMap" autoMapping="true">
     <!-- 多的一方使用collection -->
     <!--
     property:集合的属性名
     ofType:集合元素的类型
     select:就是指定查询的操作,操作的结果一定要与collection的类型匹配.
     column:就是传入到select的ID的字段名
      -->
     <collection property="courses" column="sid" autoMapping="true" ofType="Course" select="findCourseBySid">
        
     </collection>
   </resultMap>
   
 
   <!-- 创建一个resultMap组合 findStudentAndAddress操作的结果-->
   <resultMap type="Student" id="studentAndAddressResultMap" autoMapping="true">
     <!-- 如果是多个表组合autoMapping默认是false,如果不想所有字段都写,要显示声明autoMapping="true" -->
     <!--
     property:指定实体类的属性
     column:指定这个实体类属性对应的外键字段名
     javaType:指定实体类的类型
     autoMapping:表示,如果数据库的字段和属性一样,自动匹配
      -->
      <association property="address" column="aid" javaType="Address" autoMapping="true">
         <id property="aid" column="AID"/>
         <result property="aname" column="aname"/>
      </association>
   
   </resultMap>
   
   
   <resultMap type="Student" id="studentAndAddressResultMap1" autoMapping="true">
     <!-- 一的一方 -->
     <!-- 指定select查询的操作,查询的的结果一定要与property的实体类的字段匹配 -->
     <!-- 注意事项,使用select去获得地址表的数据,因为学生表与地址是通过aid来关联的,那么需要指定aid -->
     <!-- 一个映射调用另一个映射文件的操作是,使用"命名空间.操作ID" -->
     <association property="address" column="aid" autoMapping="true" select="cn.mapper.AddressMapper.findAddressById">
     </association>
   
   </resultMap>
 
  
  <!-- 需求:查询学生表的所有数据,并且包括地址表的记录 -->
  <!-- 方案1:将两个表的数据使用一条SQL语句查询出来,然后使用ResultMap组合查询的结果 -->
  <!-- 查询多个表数据不要使用resultType,因为resultType只能接收一个表的数据,如果要接收两个以上的表的数据使用resultMap -->
  <select resultMap="studentAndAddressResultMap" id="findStudentAndAddress">
    select * from student s,address  a where s.AID=a.aid
   </select>
   
   <!-- 方案2: 先查询Student表的记录,然后在resultMap的子标签association的select属性指定查询的操作,将结果返回到实体类-->
   <select resultMap="studentAndAddressResultMap1" id="findStudentAndAddress1">
     SELECT * FROM student
   </select>
   
   <!-- 查询学生的信息 -->
   <select resultMap="studentAndCourseResultMap" id="findStudentAndCourse">
     SELECT * FROM student
   </select>
   <!-- 查询指定学生编号的课程,通过学生的编号,我们知道该学生选择了哪些课程 -->
   <select resultType="Course" id="findCourseBySid">
     select * from course where sid=#{sid}
   </select>
 
   <select resultType="map" id="findStudentAndCourseToMap">
     select * from student s,course c where s.SID=c.SID
   </select>
   
</mapper>

测试

public class StudentMapperTest {

    @Test
    public void findStudentAndAddress(){
        SqlSession session = DbUtils.getSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.findStudentAndAddress();
        for(Student s:students){
            System.out.println("学生姓名:"+s.getSname()+",地址:"+s.getAddress().getAname());
        }
    }

    @Test
    public void findStudentAndAddress1(){
        SqlSession session = DbUtils.getSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.findStudentAndAddress1();
        for(Student s:students){
            System.out.println("学生姓名:"+s.getSname()+",地址:"+s.getAddress().getAname());
        }
    }


    @Test
    public void findStudentAndCourse(){
        SqlSession session = DbUtils.getSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.findStudentAndCourse();
        for(Student s:students){
            System.out.println("学生姓名:"+s.getSname());
            for(Course c:s.getCourses()){
                System.out.println("--课程:"+c.getCourseName());
            }
        }
    }

    @Test
    public void findStudentAndCourseToMap(){
        SqlSession session = DbUtils.getSession();
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Map<String, Object>> students = studentMapper.findStudentAndCourseToMap();
        for(Map<String, Object> map:students){
            //必须跟数据库的字段一致
            System.out.print("学生姓名:"+map.get("SNAME")+",");

            System.out.println("--课程:"+map.get("COURSE_NAME"));

        }
    }
}

 

collection标签的使用

映射文件代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd" >
<!-- 命名空间,用于指定动态创建的对象返回的映射接口 -->
<mapper namespace="cn.mapper.StudentMapper">
 
   <!-- #查询学生的信息,并且包括学生的学习的课程 -->
   <resultMap type="Student" id="studentAndCourseResultMap" autoMapping="true">
     <!-- 多的一方使用collection -->
     <!--
     property:集合的属性名
     ofType:集合元素的类型
     select:就是指定查询的操作,操作的结果一定要与collection的类型匹配.
     column:就是传入到select的ID的字段名
      -->
     <collection property="courses" column="sid" autoMapping="true" ofType="Course" select="findCourseBySid">
        
     </collection>
   </resultMap>
   
 
   <!-- 创建一个resultMap组合 findStudentAndAddress操作的结果-->
   <resultMap type="Student" id="studentAndAddressResultMap" autoMapping="true">
     <!-- 如果是多个表组合autoMapping默认是false,如果不想所有字段都写,要显示声明autoMapping="true" -->
     <!--
     property:指定实体类的属性
     column:指定这个实体类属性对应的外键字段名
     javaType:指定实体类的类型
     autoMapping:表示,如果数据库的字段和属性一样,自动匹配
      -->
      <association property="address" column="aid" javaType="Address" autoMapping="true">
         <id property="aid" column="AID"/>
         <result property="aname" column="aname"/>
      </association>
   
   </resultMap>
   
   
   <resultMap type="Student" id="studentAndAddressResultMap1" autoMapping="true">
     <!-- 一的一方 -->
     <!-- 指定select查询的操作,查询的的结果一定要与property的实体类的字段匹配 -->
     <!-- 注意事项,使用select去获得地址表的数据,因为学生表与地址是通过aid来关联的,那么需要指定aid -->
     <!-- 一个映射调用另一个映射文件的操作是,使用"命名空间.操作ID" -->
     <association property="address" column="aid" autoMapping="true" select="cn.mapper.AddressMapper.findAddressById">
     </association>
   
   </resultMap>
 
  
  <!-- 需求:查询学生表的所有数据,并且包括地址表的记录 -->
  <!-- 方案1:将两个表的数据使用一条SQL语句查询出来,然后使用ResultMap组合查询的结果 -->
  <!-- 查询多个表数据不要使用resultType,因为resultType只能接收一个表的数据,如果要接收两个以上的表的数据使用resultMap -->
  <select resultMap="studentAndAddressResultMap" id="findStudentAndAddress">
    select * from student s,address  a where s.AID=a.aid
   </select>
   
   <!-- 方案2: 先查询Student表的记录,然后在resultMap的子标签association的select属性指定查询的操作,将结果返回到实体类-->
   <select resultMap="studentAndAddressResultMap1" id="findStudentAndAddress1">
     SELECT * FROM student
   </select>
   
   <!-- 查询学生的信息 -->
   <select resultMap="studentAndCourseResultMap" id="findStudentAndCourse">
     SELECT * FROM student
   </select>
   <!-- 查询指定学生编号的课程,通过学生的编号,我们知道该学生选择了哪些课程 -->
   <select resultType="Course" id="findCourseBySid">
     select * from course where sid=#{sid}
   </select>
 
   <select resultType="map" id="findStudentAndCourseToMap">
     select * from student s,course c where s.SID=c.SID
   </select>
   
</mapper>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis一对一查询是指在数据库中存在一对一关系的两张表,通过MyBatis框架进行查询操作。在一对一查询中,通常会有一个主查询和一个从查询。主查询用于查询主表的数据,而从查询用于查询从表的数据。在执行一对一查询时,查询语句的执行顺序是先执行主查询,然后根据主查询的结果去执行从查询。这样就可以将主表和从表的数据进行关联,返回一个包含主表和从表数据的结果集。 然而,在执行一对一查询时,存在一些问题。一是查询结果中从表的数据可能没有用到。这是因为从表的数据可能只是为了满足关联关系而查询出来的,并不一定会在业务逻辑中使用到。二是在一对一关系中,如果主查询的结果有N个用户,则需要执行N次查询,每次查询都会再次执行从查询,这可能导致性能问题。 为了解决这些问题,可以采用其他方式来进行一对一查询。例如,可以在用户表中设置外键指向博客表,通过外键关联的方式来进行一对一查询。这样就可以在用户实体类中添加一个博客属性,通过映射关系将用户和博客进行关联。 总之,MyBatis一对一查询可以通过主查询和从查询来实现,但也存在一些问题。通过合适的业务逻辑和关联方式,可以解决这些问题,提高查询性能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Mybatis高级查询一对一查询的四种方法(笔记)](https://blog.csdn.net/LeoFitz/article/details/89484688)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值