Mybatis 一对一,一对多

一对一与一对多:

一对一映射
        Student和Address是一个【一对一】关系
        建表语言:
        drop table students;
        drop table addresses;
        如果需要可以使用 cascade constraints;

        create table addresses(
          addr_id number primary key,
          street varchar2(50) not null,
          city varchar2(50) not null,
          state varchar2(50) not null,
          zip varchar2(10),
          country varchar2(50)
        );

        create table students(
          stud_id number primary key,
          name varchar2(50) not null,
          email varchar2(50),
          phone varchar2(15),  
          dob date ,
          addr_id number references addresses(addr_id)
        );

        java类:
        public class PhoneNumber {
            private String countryCode;
            private String stateCode;
            private String number;
            get/set
        }
        public class Address{
            private Integer addrId;
            private String street;
            private String city;
            private String state;
            private String zip;
            private String country;
            get/set
        }
        public class Student {
            private Integer studId; 
            private String name; 
            private String email; 
            private Date dob;
            private PhoneNumber phone;
            private Address address;
            get/set
        }


        addresses 表的样例输入如下所示:
        addr_id  street     city     state  zip   country 
            1    redSt      kunshan   W     12345  china 
            2    blueST     kunshan   W     12345  china 

        insert into addresses(addr_id,street,city,state,zip,country) values(1,'redSt','kunshan','W','12345','china');
        insert into addresses(addr_id,street,city,state,zip,country) values(2,'blueST','kunshan','W','12345','china');


        students 表的样例数据如下所示:
        stud_id  name    email          phone       addr_id 
           1    John  [email protected]  123-456-7890   1 
           2    Paul  [email protected]  111-222-3333   2 
        
        insert into students(stud_id,name,email,phone,addr_id) values(1,'John','[email protected]','123-456-7890',1);
        insert into students(stud_id,name,email,phone,addr_id) values(2,'Paul','[email protected]','111-222-3333',2);

        
        mapper XML:
         
         
           
           
           
           
           
           
           
           
           
           
         
         

        我们可以使用(对象.属性名)的方式为内嵌的对象的属性赋值。在上述的resultMap中,Student的address属性使用该方式被赋上了 address 对应列的值。同样地,我们可以访问【任意深度】的内嵌对象的属性。
 
        //接口定义 
        public interface Student Mapper{ 
            Student selectStudentWithAddress(int studId); 
        } 

        //方法调用
        int studId = 1; 
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); 
        Student student = studentMapper.selectStudentWithAddress(studId); 
        System.out.println("Student :" + student); 
        System.out.println("Address :" + student.getAddress()); 


        上面展示了一对一关联映射的一种方法。然而,使用这种方式映射,如果address结果需要在其他的SELECT映射语句中映射成Address对象,我们需要为每一个语句重复这种映射关系。MyBatis提供了更好地实现一对一关联映射的方法:【嵌套结果】ResultMap和【嵌套查询】select语句。接下来,我们将讨论这两种方式。

        


        3.4.1 使用嵌套结果ResultMap实现一对一关系映射
        我们可以使用一个嵌套结果ResultMap方式来获取Student及其Address信息,代码如下:
         
           
           
           
           
           
           
         
         
           
           
           
           
        
         
        
        注:association是关联的意思
        元素被用来导入“有一个”(has-one)类型的关联。在上述的例子中,我们使用了元素引用了另外的在同一个XML文件中定义的。

        同时我们也可以使用 定义内联的resultMap,代码如下所示:
         
           
           
           
           
             
             
             
             
             
             
           
         

 
        3.4.2 使用嵌套查询实现一对一关系映射
        我们可以通过使用嵌套select查询来获取Student及其Address信息,代码如下:
         
           
           
           
           
           
           
        
         

         
           
           
           
           
        
         

        在此方式中,元素的select属性被设置成了id为findAddressById的语句。这里,两个分开的SQL语句将会在数据库中分别执行,第一个调用findStudentById加载student信息,而第二个调用findAddressById来加载address信息。
        addr_id列的值将会被作为输入参数传递给selectAddressById语句。
        
        我们可以如下调用findStudentWithAddress映射语句:
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); 
        Student student = mapper.selectStudentWithAddress(studId); 
        System.out.println(student); 
        System.out.println(student.getAddress());



    3.5 一对多映射
        一个讲师tutors可以教授一个或者多个课程course。这意味着讲师和课程之间存在一对多的映射关系。
        注意:在一对多关系中,数据库建表的时候外键一定是在多的那一方建立.
        建表语句:
        drop table tutors;
        drop table courses;
        如果需要可以使用 cascade constraints;

        create table tutors(
          tutor_id number primary key,
          name varchar2(50) not null,
          email varchar2(50) ,
          phone varchar2(15) ,  
          addr_id number(11) references addresses (addr_id)
        );

        create table courses(
          course_id number primary key,
          name varchar2(100) not null,
          description varchar2(512),
          start_date date ,
          end_date date ,
          tutor_id number references tutors (tutor_id)
        );

        tutors 表的样例数据如下:
        tutor_id   name     email         phone     addr_id 
            1       zs  [email protected]   123-456-7890    1 
            2       ls  [email protected]   111-222-3333    2 
        
        insert into tutors(tutor_id,name,email,phone,addr_id)
        values(1,'zs','[email protected]','123-456-7890',1);
        insert into tutors(tutor_id,name,email,phone,addr_id)
        values(2,'ls','[email protected]','111-222-3333',2);

        course 表的样例数据如下:
        course_id  name  description  start_date   end_date  tutor_id 
            1    JavaSE    JavaSE      2015-09-10  2016-02-10   1 
            2    JavaEE    JavaEE      2015-09-10  2016-03-10   2 
            3    MyBatis   MyBatis     2015-09-10  2016-02-20   2 
        
        insert into
        courses(course_id,name,description,start_date,end_date,tutor_id)
        values(1,'JavaSE','JavaSE',to_date('2015-09-10','yyyy-mm-dd'),to_date('2016-02-10','yyyy-mm-dd'),1);

        insert into
        courses(course_id,name,description,start_date,end_date,tutor_id)
        values(2,'JavaEE','JavaEE',to_date('2015-09-10','yyyy-mm-dd'),to_date('2016-03-10','yyyy-mm-dd'),2);

        insert into
        courses(course_id,name,description,start_date,end_date,tutor_id)
        values(3,'MyBatis','MyBatis',to_date('2015-09-10','yyyy-mm-dd'),to_date('2016-02-20','yyyy-mm-dd'),1);


        在上述的表数据中,zs 讲师教授一个课程,而 ls 讲师教授两个课程

        java代码:
        public class Tutor{
            private Integer tutorId; 
            private String name; 
            private String email; 
            private PhoneNumber phone;
            private Address address; 
            private List courses;

            get/set
        }

        public class Course{
            private Integer courseId; 
            private String name; 
            private String description; 
            private Date startDate; 
            private Date endDate; 

            get/set
        }

        元素被用来将多行课程结果映射成一个课程Course对象的一个集合。和一对一映射一样,我们可以使用【嵌套结果ResultMap】和【嵌套查询Select】语句两种方式映射实现一对多映射。
 
            
        3.5.1 使用内嵌结果 ResultMap 实现一对多映射
        我们可以使用嵌套结果resultMap方式获得讲师及其课程信息,代码如下:
         
           
           
           
           
           
           
        
         
           
           
           
           
           
         
         
           
           
           
           
          
           
         
        
         

        这里我们使用了一个简单的使用了JOINS连接的Select语句获取讲师及其所教课程信息。元素的resultMap属性设置成了CourseResult,CourseResult包含了Course对象属性与表列名之间的映射。
        如果同时也要查询到Address相关信息,可以按照上面一对一的方式,在配置中加入即可


        3.5.2 使用嵌套Select语句实现一对多映射
        我们可以使用嵌套Select语句方式获得讲师及其课程信息,代码如下:
         
           
           
           
           
           
           
        
         
           
           
           
           
           
        

         
           
           
           
          
          
           
         
        
        
         
        
        在这种方式中,元素的select属性被设置为id为findCourseByTutor的语句,用来触发单独的SQL查询加载课程信息。tutor_id这一列值将会作为输入参数传递给 findCouresByTutor语句。
 
        mapper接口代码:
        public interface TutorMapper{ 
            Tutor findTutorById(int tutorId); 
        } 
        
        //方法调用
        TutorMapper mapper = sqlSession.getMapper(TutorMapper.class); 
        Tutor tutor = mapper.findTutorById(tutor Id); 
        System.out.println(tutor); 
        List courses = tutor.getCourses(); 
        for (Course course : courses){ 
            System.out.println(course); 
        } 

        【注意】嵌套查询Select语句查询会导致1+N选择问题。首先,主查询将会执行(1 次),对于主查询返回的每一行,另外一个查询将会被执行(主查询 N 行,则此查询 N 次)。对于大量数据而言,这会导致很差的性能问题。

你可能感兴趣的:(Mybatis 一对一,一对多)