A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

MyBatis中的注解    之前都是在映射器MapperXML配置文件中配置映射语句的。除此之外MyBatis也支持使用注解来配置映射语句。当我们使用基于注解的映射器接口时,我们不再需要在XML配置文件中配置了。如果你愿意,你也可以同时使用基于XML和基于注解的映射语句。
    使用Person进行测试
    drop table person;
    create table person(
        id number primary key,
        name varchar2(15),
        age number
    );
    public class Person{
        private Integer id;
        private String name;
        private Integer age;

        get/set
    }      
    5.1 在映射器Mapper接口上使用注解
        MyBatis对于大部分的基于XML的映射器元素(包括<select>,<update>)提供了对应的基于注解的配置项。然而在某些情况下,基于注解配置还不能支持基于XML的一些元素。     
    5.2 映射语句
        MyBatis提供了多种注解来支持不同类型的语句如:SELECT,INSERT,UPDATE,DELETE。         
        5.2.1 @Insert  
        我们可以使用 @Insert注解来定义一个INSERT映射语句:           
        package com.briup.mappers;  
        public interface StudentMapper{   
            @Insert("insert into students(stud_id,name,email,addr_id, phone) values(#{studId},#{name},#{email},#{address.addrId},#{phone})")  
            int insertStudent(Student student);   
        }   
        自动生成主键  
        可以使用 @Options注解的userGeneratedKeys和keyProperty属性让数据库产生 auto_increment(自增长)列的值,然后将生成的值设置到输入参数对象的属性中。
        @Insert("insert into students(name,email,addr_id, phone)  
                values(#{name},#{email},#{address.addr Id},#{phone})")  
        @Options(useGeneratedKeys = true, keyProperty = "studId")  
        int insertStudent(Student student);   
        这里STUD_ID列值将会通过MySQL数据库自动生成。并且生成的值将会被设置到student对象的studId属性中。
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);  
        mapper.insertStudent(student);  
        int studentId = student.getStudId();           
        有一些数据库如Oracle,并不支持AUTO_INCREMENT列属性,它使用序列(SEQUENCE)来产生主键的值。
        我们可以使用 @SelectKey注解来为任意SQL语句来指定主键值,作为主键列的值。假设我们有一个名为STUD_ID_SEQ的序列来生成STUD_ID主键值。         
        @Insert("insert into students(stud_id,name,email,addr_id,phone) values(#{studId},#{name},#{email},#{address.addrId},#{phone})")  
        @SelectKey(statement="select my_seq.nextval from dual", keyProperty="studId", resultType=int.class, before=true)  
        int insertStudent(Student student);   
        这里我们使用了 @SelectKey来生成主键值,并且存储到了student对象的studId属性上。由于我们设置了before=true,该语句将会在执行INSERT语句之前执行.
        @Insert("insert into students(name,email,addr_id, phone)   
        values(#{name},#{email},#{address.addrId},#{phone})")  
        @SelectKey(statement="select my_seq.currval from dual",   
        keyProperty="studId", resultType=int.class, before=false)  
        int insertStudent(Student student);      
        5.2.2 @Update  
        我们可以使用 @Update注解来定义一个UPDATE映射语句,如下所示:
        @Update("update students set name=#{name}, email=#{email},   
        phone=#{phone} where stud_id=#{studId}")  
        int updateStudent(Student student);   
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);  
        int noOfRowsUpdated = mapper.updateStudent(student);     
        5.2.3 @Delete  
        我们可以使用 @Delete注解来定义一个DELETE映射语句,如下所示:
        @Delete("delete from students where stud_id=#{studId}")  
        int deleteStudent(int studId);   
        5.2.4 @Select
        我们可以使用 @Select注解来定义一个SELECT映射语句。           
        package com.itheima.mappers;  
        public interface StudentMapper{  
            @Select("select stud_id as studid, name, email, phone from  
                    students where stud_id=#{studId}")  
            Student findStudentById(Integer studId);  
        }  
        为了将列名和对象中属性名匹配,我们为stud_id起了一个studId的别名。如果返回了多行结果,将抛出TooManyResultsException异常。   
    5.3 结果映射
        我们可以将查询结果通过别名或者是 @Results注解与JavaBean属性映射起来。           
        package com.itheima.mappers;  
        public interface StudentMapper{  
            @Select("select * from students")  
            @Results(  
            {  
                @Result(id = true, column = "stud_id", property = "studId"),  
                @Result(column = "name", property = "name"),  
                @Result(column = "email", property = "email"),  
                @Result(column = "addr_id", property = "address.addrId")  
            })  
            List<Student> findAllStudents();  
        }           
        注意:
        @Results注解和映射器XML配置文件元素<resultMap> 对应。然而,My Batis3.2.2不能为 @Results注解赋予一个ID。所以,不像<resultMap>元素,我们不应在不同的映射语句中重用 @Results声明。这意味着即使 @Results注解完全相同,我们也需要(在不同的映射接口中)重复 @Results声明。         
        例如,看下面的 findStudentById()和 findAllStudents()方法:   
        @Select("select * from students where stud_id=#{studId}")  
        @Results(  
        {  
            @Result(id = true, column = "stud_id", property = "studId"),  
            @Result(column = "name", property = "name"),  
            @Result(column = "email", property = "email"),  
            @Result(column = "addr_id", property = "address.addrId")  
        })  
        Student findStudentById(int studId);  
        @Select("select * from students")  
        @Results(  
        {  
            @Result(id = true, column = "stud_id", property = "studId"),  
            @Result(column = "name", property = "name"),  
            @Result(column = "email", property = "email"),  
            @Result(column = "addr_id", property = "address.addrId")  
        })  
        List<Student> findAllStudents();            
        这里两个语句的 @Results配置完全相同,但是必须得重复它。这里有一个解决方法。我们可以创建一个映射器Mapper配置文件,然后配置<resultMap>元素,然后使用 @ResultMap注解引用此<resultMap>。 在StudentMapper.xml中定义一个ID为StudentResult的<resultMap>。         
        xml配置:           
        <mapper namespace="com.itheima.mappers.StudentMapper">  
          <resultMap type="Student" id="StudentResult">  
            <id property="studId" column="stud_id" />  
            <result property="name" column="name" />  
            <result property="email" column="email" />  
            <result property="phone" column="phone" />  
          </resultMap>  
        </mapper>   
        在StudentMapper.java中,使用 @Result Map引用名为StudentResult的resultMap:           
        public interface StudentMapper{  
            @Select("select * from students where stud_id=#{studId}")  
            @ResultMap("com.itheima.mappers.StudentMapper.StudentResult")  
            Student findStudentById(int studId);   
            @Select("select * from students")  
            @ResultMap("com.itheima.mappers.StudentMapper.StudentResult")  
            List<Student> findAllStudents();  
        }                     
    5.4 一对一映射
        MyBatis提供了 @One注解来使用嵌套select语句(Nested-Select)加载一对一关联查询数据。让我们看看怎样使用 @One注解获取学生及其地址信息         
        public interface StudentMapper{  
            @Select("select addr_id as addrId, street, city, state, zip, country from addresses where addr_id=#{id}")  
            Address findAddressById(int id);   
            @Select("select * from students where stud_id=#{studId} ")  
            @Results(  
            {  
                @Result(id = true, column = "stud_id", property = "studId"),  
                @Result(column = "name", property = "name"),  
                @Result(column = "email", property = "email"),  
                @Result(property = "address", column = "addr_id",  
                one = @One(select = "com.itheima.mappers.Student Mapper.findAddressById"))  
            })  
            Student selectStudentWithAddress(int studId);  
        }           
        这里我们使用了 @One注解的select属性来指定一个使用了完全限定名的方法上,该方法会返回一个Address对象。使用column=”addr_id”,则STUEDNTS表中列addr_id的值将会作为输入参数传递给find Address By Id()方法。如果 @One SELECT查询返回了多行结果,则会抛出TooManyResultsException异常。

        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());  

        我们可以通过基于XML的映射器配置,使用嵌套结果ResultMap来加载一对一关联的查询。而MyBatis3.2.2 版本,并没有对应的注解支持。但是我们可以在映射器Mapper配置文件中配置<resultMap>并且使用 @ResultMap注解来引用它。
        在StudentMapper.xml中配置<resultMap>,如下所示:
        <mapper namespace="com.itheima.mappers.StudentMapper">  
          <resultMap type="Address" id="AddressResult">  
            <id property="addrId" column="addr_id" />  
            <result property="street" column="street" />  
            <result property="city" column="city" />  
            <result property="state" column="state" />  
            <result property="zip" column="zip" />  
            <result property="country" column="country" />  
          </resultMap>  
          <resultMap type="Student" id="StudentWithAddressResult">  
            <id property="studId" column="stud_id" />  
            <result property="name" column="name" />  
            <result property="email" column="email" />  
            <association property="address" resultMap="AddressResult" />  
          </resultMap>  
        </mapper>  
         
        public interface StudentMapper{  
            @Select("select stud_id, name, email, a.addr_id, street, city, state, zip, country" + " FROM students s left outer join addresses a on s.addr_id=a.addr_id" + " where stud_id=#{studId} ")  
            @ResultMap("com.itheima.mappers.StudentMapper.StudentWithAddressResult")  
            Student selectStudentWithAddress(int id);  
        }        
    5.5 一对多映射
    MyBatis提供了 @Many注解,用来使用嵌套Select语句加载一对多关联查询。现在让我们看一下如何使用 @Many注解获取一个讲师及其教授课程列表信息:      
    public interface TutorMapper{  
        @Select("select addr_id as addrId, street, city, state, zip,  country from addresses where addr_id=#{id}")  
        Address findAddressById(int id);   
        @Select("select * from courses where tutor_id=#{tutorId}")  
        @Results(  
        {  
            @Result(id = true, column = "course_id", property = "courseId"),  
            @Result(column = "name", property = "name"),  
            @Result(column = "description", property = "description"),  
            @Result(column = "start_date" property = "startDate"),  
            @Result(column = "end_date" property = "endDate")  
        })  
        List<Course> findCoursesByTutorId(int tutorId);   
        @Select("SELECT tutor_id, name as tutor_name, email, addr_id  
                FROM tutors where tutor_id=#{tutorId}")  
        @Results(  
        {  
            @Result(id = true, column = "tutor_id", property = "tutorId"),  
            @Result(column = "tutor_name", property = "name"),  
            @Result(column = "email", property = "email"),  
            @Result(property = "address", column = "addr_id",  
            one = @One(select = "com.itheima.mappers.Tutor Mapper.findAddressById")),  
            @Result(property = "courses", column = "tutor_id",  
            many = @Many(select = "com.itheima.mappers.Tutor Mapper.findCoursesByTutorId"))  
        })  
        Tutor findTutorById(int tutorId);  
    }   
    这里我们使用了 @Many注解的select属性来指向一个完全限定名称的方法,该方法将返回一个 List<Course>对象。使用column=”tutor_id”,TUTORS表中的tutor_id列值将会作为输入参数传递给find Courses By Tutor Id()方法。  
    之前我们使用过嵌套结果ResultMap来加载一对多关联的查询。而MyBatis3.2.2版本,并没有对应的注解支持。但是我们可以在映射器Mapper配置文件中配置<result Map>并且使用 @ResultMap注解来引用它。  
    在TutorMapper.xml中配置<resultMap>,如下所示:
    <mapper namespace="com.itheima.mappers.Tutor Mapper">  
      <resultMap type="Address" id="AddressResult">  
        <id property="addrId" column="addr_id" />  
        <result property="street" column="street" />  
        <result property="city" column="city" />  
        <result property="state" column="state" />  
        <result property="zip" column="zip" />  
        <result property="country" column="country" />  
      </resultMap>  
      <resultMap type="Course" id="CourseResult">  
        <id column="course_id" property="course Id" />  
        <result column="name" property="name" />  
        <result column="description" property="description" />  
        <result column="start_date" property="startDate" />  
        <result column="end_date" property="endDate" />  
      </resultMap>  
      <resultMap type="Tutor" id="TutorResult">  
        <id column="tutor_id" property="tutorId" />  
        <result column="tutor_name" property="name" />  
        <result column="email" property="email" />  
        <association property="address" result Map="AddressResult" />  
        <collection property="courses" result Map="CourseResult" />  
      </resultMap>  
    </mapper>  

      
    public interface TutorMapper{  
        @Select("select t.tutor_id, t.name as tutor_name,email,a.addr_id, street, city, state, zip, country, course_id, c.name,description, start_date, end_date  from tutors t left outer join addresses a on t.addr_id=a.addr_id left outer join courses c on t.tutor_id=c.tutor_id where t.tutor_id=#{tutorId}")  
        @Result Map("com.itheima.mappers.TutorMapper.TutorResult")  
        Tutor selectTutorById(int tutorId);  
    }  

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马