Mybatis学习 - 注解方式使用讲解

[源]https://blog.csdn.net/elricboa/article/details/78840733

MyBatis注解

MyBatis可以利用SQL映射文件来配置,也可以利用Annotation来设置。MyBatis提供的一些基本注解如下表所示。


注解


目标


相应的XML


描述


@CacheNamespace



<cache>  


为给定的命名空间(比如类)配置缓存。属性:

implemetation,eviction,

flushInterval , size 和 readWrite 。


@CacheNamespaceRef



<cacheRef>


参照另外一个命名空间的缓存来使用。

属性:value,也就是类的完全限定名。


@ConstructorArgs


方法


<constructor>


收集一组结果传递给对象构造方法。

属性:value,是形式参数的数组


@Arg


方法


<arg>

<idArg>

 


单独的构造方法参数,是ConstructorArgs  集合的一部分。属性:id,column,javaType,typeHandler。

id属性是布尔值,来标识用于比较的属性,和<idArg>XML 元素相似


@TypeDiscriminator


方法


<discriminator>


一组实例值被用来决定结果映射的表

现。属性:Column, javaType ,  jdbcType typeHandler,cases。

cases属性就是实例的数组。


@Case


方法


<case>


单独实例的值和它对应的映射。属性:value  ,type ,results 。

Results 属性是结果数组,因此这个注解和实际的ResultMap 很相似,由下面的  Results注解指定


@Results


方法


<resultMap>


结果映射的列表,包含了一个特别结果

列如何被映射到属性或字段的详情。

属性:value ,是Result注解的数组


@Result


方法


<result>

<id>


在列和属性或字段之间的单独结果映

射。属性:id ,column , property ,

javaType ,jdbcType ,type Handler ,

one,many。id 属性是一个布尔值,表

示了应该被用于比较的属性。one 属性是单独的联系,和 <association> 相似,而many 属性是对集合而言的,和

<collection>相似。


@One


方法


<association>  


复杂类型的单独属性值映射。属性:

select,已映射语句(也就是映射器方

法)的完全限定名,它可以加载合适类

型的实例。注意:联合映射在注解 API

中是不支持的。


@Many


方法


<collection>


复杂类型的集合属性映射。属性:

select,是映射器方法的完全限定名,它可加载合适类型的一组实例。注意:联合映射在 Java注解中是不支持的。


@Options


方法


映射语句的属性


这个注解提供访问交换和配置选项的宽广范围,它们通常在映射语句上作为属性出现。而不是将每条语句注解变复杂,Options 注解提供连贯清晰的方式来访问它们。属性:useCache=true,

flushCache=false,

resultSetType=FORWARD_ONLY,

statementType=PREPARED,

fetchSize= -1,timeout=-1 ,

useGeneratedKeys=false ,

keyProperty=”id“。

理解Java 注解是很重要的,因为没有办法来指定“null ”作为值。因此,一旦你使用了 Options注解,语句就受所有默认值的支配。要注意什么样的默认值来避免不期望的行为


@Insert

@Update

@Delete


方法


<insert>

<update>

<delete>


这些注解中的每一个代表了执行的真实 SQL。它们每一个都使用字符串数组(或单独的字符串)。如果传递的是字符串数组,它们由每个分隔它们的单独空间串联起来。属性:value,这是字符串数组用来组成单独的SQL语句


@InsertProvider

@UpdateProvider

@DeleteProvider

@SelectProvider


方法


<insert>

<update>

<delete>

<select>

允许创建动态

SQL。


这些可选的SQL注解允许你指定一个

类名和一个方法在执行时来返回运行

的SQL。基于执行的映射语句, MyBatis

会实例化这个类,然后执行由 provider

指定的方法. 这个方法可以选择性的接

受参数对象作为它的唯一参数,但是必

须只指定该参数或者没有参数。属性:

type,method。type 属性是类的完全限定名。method  是该类中的那个方法名。


@Param


参数


N/A


当映射器方法需多个参数,这个注解可以被应用于映射器方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名。比如

#{1},#{2} 等,这是默认的。

使用@Param(“person”),SQL中参数应该被命名为#{person}。

 

这些注解都是运用到传统意义上映射器接口中的方法、类或者方法参数中的。

使用方法

1.insert方法

我们可以使用@Insert注解来定义一个INSERT映射语句:
  1. package com.mybatis3.mappers;    
  2. public interface StudentMapper    
  3. {    
  4.     @Insert(“INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,ADDR_ID, PHONE)    
  5.             VALUES(#{studId},#{name},#{email},#{address.addrId},#{phone})”)    
  6.     int insertStudent(Student student);    
package com.mybatis3.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);  
使用了@Insert注解的方法将返回insert语句执行后影响的行数。

2.自动生成主键

使用@Options注解的userGeneratedKeys 和keyProperty属性让数据库产生auto_increment(自增长)列的值,然后将生成的值设置到输入参数对象的属性中。
  1. @Insert(“INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE)    
  2.         VALUES(#{name},#{email},#{address.addrId},#{phone})”)    
  3. @Options(useGeneratedKeys = true, keyProperty = “studId”)    
  4. int insertStudent(Student student);   
@Insert("INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE)  
        VALUES(#{name},#{email},#{address.addrId},#{phone})")  
@Options(useGeneratedKeys = true, keyProperty = "studId")  
int insertStudent(Student student); 
这里stu_id主键列值将会通过MySQL数据库自动生成。并且生成的值将会被设置到student对象的studId属性中。
  1. mapper.insertStudent(student);    
  2. int studentId = student.getStudId();   
mapper.insertStudent(student);  
int studentId = student.getStudId(); 

3.update方法
可以使用@Update注解来定义一个UPDATE映射语句,如下所示:
  1. @Update(“UPDATE STUDENTS SET NAME=#{name}, EMAIL=#{email},     
  2. PHONE=#{phone} WHERE STUD_ID=#{studId}”)    
  3. int updateStudent(Student student);  
@Update("UPDATE STUDENTS SET NAME=#{name}, EMAIL=#{email},   
PHONE=#{phone} WHERE STUD_ID=#{studId}")  
int updateStudent(Student student);
使用了@Update的方法将会返回执行了update语句后影响的行数。
4.delete方法
可以使用@Delete  注解来定义一个DELETE映射语句,如下所示:
  1. @Delete(“DELETE FROM STUDENTS WHERE STUD_ID=#{studId}”)    
  2. int deleteStudent(int studId);  
@Delete("DELETE FROM STUDENTS WHERE STUD_ID=#{studId}")  
int deleteStudent(int studId);
使用了@Delete的方法将会返回执行了update语句后影响的行数。

5.select方法

可以使用@ Select注解来定义一个SELECT映射语句。
  1. public interface StudentMapper    
  2. {    
  3.     @Select(“SELECT STUD_ID AS STUDID, NAME, EMAIL, PHONE FROM    
  4.             STUDENTS WHERE STUD_ID=#{studId}”)    
  5.     Student findStudentById(Integer studId);    
  6. }   
public interface StudentMapper  
{  
    @Select("SELECT STUD_ID AS STUDID, NAME, EMAIL, PHONE FROM  
            STUDENTS WHERE STUD_ID=#{studId}")  
    Student findStudentById(Integer studId);  
} 
6.结果映射
可以将查询结果通过别名或者是@Results注解与JavaBean属性映射起来。
  1. @Select(“SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}”)    
  2. @Results(    
  3. {    
  4.     @Result(id = true, column = “stud_id”, property = “studId”),    
  5.     @Result(column = “name”, property = “name”),    
  6.     @Result(column = “email”, property = “email”),    
  7.     @Result(column = “addr_id”, property = “address.addrId”)    
  8. })    
  9. Student findStudentById(int studId);  
  10.   
  11. @Select(“SELECT * FROM STUDENTS”)    
  12. @Results(    
  13. {    
  14.     @Result(id = true, column = “stud_id”, property = “studId”),    
  15.     @Result(column = “name”, property = “name”),    
  16.     @Result(column = “email”, property = “email”),    
  17.     @Result(column = “addr_id”, property = “address.addrId”)    
  18. })    
  19. List<Student> 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();
7.ResultMap
6中的两个@Results配置完全相同,但是必须得重复它。这里有一个解决方法。我们可以创建一个映射器Mapper配置文件, 然后配置<resultMap>元素,然后使用@ResultMap注解引用此<resultMap>。
在StudentMapper.xml中定义一个ID为StudentResult的<resultMap>。
  1. <mapper namespace=“com.mybatis3.mappers.StudentMapper”>    
  2.   <resultMap type=”Student” id=“StudentResult”>    
  3.     <id property=”studId” column=“stud_id” />    
  4.     <result property=”name” column=“name” />    
  5.     <result property=”email” column=“email” />    
  6.     <result property=”phone” column=“phone” />    
  7.   </resultMap>    
  8. </mapper>    
<mapper namespace="com.mybatis3.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>  

然后使用@ResultMap引用名为StudentResult的resultMap。
  1. @Select(“SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}”)    
  2. @ResultMap(“com.mybatis3.mappers.StudentMapper.StudentResult”)    
  3. Student findStudentById(int studId);  
  4.    
  5. @Select(“SELECT * FROM STUDENTS”)    
  6. @ResultMap(“com.mybatis3.mappers.StudentMapper.StudentResult”)    
  7. List<Student> findAllStudents();  
@Select("SELECT * FROM STUDENTS WHERE STUD_ID=#{studId}")  
@ResultMap("com.mybatis3.mappers.StudentMapper.StudentResult")  
Student findStudentById(int studId);

@Select("SELECT * FROM STUDENTS")  
@ResultMap("com.mybatis3.mappers.StudentMapper.StudentResult")  
List<Student> findAllStudents();

8.一对一映射
MyBatis提供了@One注解来使用嵌套select语句(Nested-Select)加载一对一关联查询数据。 让我们看看怎样使用@One注解获取学生及其地址信息。
  1. @Select(“SELECT ADDR_ID AS ADDRID, STREET, CITY, STATE, ZIP, COUNTRY    
  2.             FROM ADDRESSES WHERE ADDR_ID=#{id}”)    
  3.     Address findAddressById(int id);    
  4.     @Select(“SELECT * FROM STUDENTS WHERE STUD_ID=#{studId} ”)    
  5.     @Results(    
  6.     {    
  7.         @Result(id = true, column = “stud_id”, property = “studId”),    
  8.         @Result(column = “name”, property = “name”),    
  9.         @Result(column = “email”, property = “email”),    
  10.         @Result(property = “address”, column = “addr_id”,    
  11.         one = @One(select = “com.mybatis3.mappers.StudentMapper.    
  12.         findAddressById”))    
  13.     })    
  14.     Student selectStudentWithAddress(int studId);   
@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.mybatis3.mappers.StudentMapper.  
        findAddressById"))  
    })  
    Student selectStudentWithAddress(int studId); 
这里我们使用了@One注解的select属性来指定一个使用了完全限定名的方法上,该方法会返回一个Address对象。使用column=”addr_id”,则STUEDNTS表中列addr_id的值将会作为输入参数传递给findAddressById()方法。如果@OneSELECT查询返回了多行结果,则会抛出TooManyResultsException异常。

我们可以通过基于XML的映射器配置,使用嵌套结果ResultMap来加载一对一关联的查询。而MyBatis3.2.2版本,并没有对应的注解支持。但是我们可以在映射器Mapper配置文件中配置<resultMap>并且使用@ResultMap注解来引用它。

在StudentMapper.xml中配置<resultMap>,如下所示:
  1. <mapper namespace=“com.mybatis3.mappers.StudentMapper”>    
  2.   <resultMap type=“Address” id=“AddressResult”>    
  3.     <id property=“addrId” column=“addr_id” />    
  4.     <result property=“street” column=“street” />    
  5.     <result property=“city” column=“city” />    
  6.     <result property=“state” column=“state” />    
  7.     <result property=“zip” column=“zip” />    
  8.     <result property=“country” column=“country” />    
  9.   </resultMap>    
  10.   <resultMap type=“Student” id=“StudentWithAddressResult”>    
  11.     <id property=“studId” column=“stud_id” />    
  12.     <result property=“name” column=“name” />    
  13.     <result property=“email” column=“email” />    
  14.     <association property=“address” resultMap=“AddressResult” />    
  15.   </resultMap>    
  16. </mapper>   
<mapper namespace="com.mybatis3.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> 
  1. @Select(“select stud_id, name, email, a.addr_id, street, city,    
 @Select("select stud_id, name, email, a.addr_id, street, city,  
  1.         state, zip, country“ + ” FROM students s left outer join addresses a    
  2.         on s.addr_id=a.addr_id” + ” where stud_id=#{studId} ”)    
  3. @ResultMap(“com.mybatis3.mappers.StudentMapper.    
  4.            StudentWithAddressResult”)    
  5. Student selectStudentWithAddress(int id);  
            state, zip, country" + " FROM students s left outer join addresses a  
            on s.addr_id=a.addr_id" + " where stud_id=#{studId} ")  
    @ResultMap("com.mybatis3.mappers.StudentMapper.  
               StudentWithAddressResult")  
    Student selectStudentWithAddress(int id);

 
     
 
    

9.一对多映射

MyBatis提供了@Many注解,用来使用嵌套Select语句加载一对多关联查询。
  1. @Select(“select addr_id as addrId, street, city, state, zip,    
  2.             country from addresses where addr_id=#{id}”)    
  3.     Address findAddressById(int id);    
  4.     @Select(“select * from courses where tutor_id=#{tutorId}”)    
  5.     @Results(    
  6.     {    
  7.         @Result(id = true, column = “course_id”, property = “courseId”),    
  8.         @Result(column = “name”, property = “name”),    
  9.         @Result(column = “description”, property = “description”),    
  10.         @Result(column = “start_date” property = “startDate”),    
  11.         @Result(column = “end_date” property = “endDate”)    
  12.     })    
  13.   
  14.     List<Course> findCoursesByTutorId(int tutorId);    
  15.     @Select(“SELECT tutor_id, name as tutor_name, email, addr_id    
  16.             FROM tutors where tutor_id=#{tutorId}”)    
  17.     @Results(    
  18.     {    
  19.         @Result(id = true, column = “tutor_id”, property = “tutorId”),    
  20.         @Result(column = “tutor_name”, property = “name”),    
  21.         @Result(column = “email”, property = “email”),    
  22.         @Result(property = “address”, column = “addr_id”,    
  23.         one = @One(select = ” com.mybatis3.    
  24.         mappers.TutorMapper.findAddressById”)),    
  25.         @Result(property = “courses”, column = “tutor_id”,    
  26.         many = @Many(select = “com.mybatis3.mappers.TutorMapper.    
  27.         findCoursesByTutorId”))    
  28.     })    
  29.     Tutor findTutorById(int tutorId);  
@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.mybatis3.  
        mappers.TutorMapper.findAddressById")),  
        @Result(property = "courses", column = "tutor_id",  
        many = @Many(select = "com.mybatis3.mappers.TutorMapper.  
        findCoursesByTutorId"))  
    })  
    Tutor findTutorById(int tutorId);
这里我们使用了@Many注解的select属性来指向一个完全限定名称的方法,该方法将返回一个List<Course>对象。使用column=”tutor_id”,TUTORS表中的tutor_id列值将会作为输入参数传递给findCoursesByTutorId()方法。
这里使用了@Many注解的select属性来指向一个完全限定名称的方法,该方法将返回一个List<Course>对象。使用column=”tutor_id”,TUTORS表中的tutor_id列值将会作为输入参数传递给findCoursesByTutorId()方法。
我们可以通过基于XML的映射器配置,使用嵌套结果ResultMap来加载一对多关联的查询。而MyBatis3.2.2版本,并没有对应的注解支持。但是我们可以在映射器Mapper配置文件中配置<resultMap>并且使用@ResultMap注解来引用它。
在TutorMapper.xml中配置<resultMap>,如下所示:
  1. <mapper namespace=“com.mybatis3.mappers.TutorMapper”>    
  2.   <resultMap type=“Address” id=“AddressResult”>    
  3.     <id property=“addrId” column=“addr_id” />    
  4.     <result property=“street” column=“street” />    
  5.     <result property=“city” column=“city” />    
  6.     <result property=“state” column=“state” />    
  7.     <result property=“zip” column=“zip” />    
  8.     <result property=“country” column=“country” />    
  9.   </resultMap>    
  10.   <resultMap type=“Course” id=“CourseResult”>    
  11.     <id column=“course_id” property=“courseId” />    
  12.     <result column=“name” property=“name” />    
  13.     <result column=“description” property=“description” />    
  14.     <result column=“start_date” property=“startDate” />    
  15.     <result column=“end_date” property=“endDate” />    
  16.   </resultMap>    
  17.   <resultMap type=“Tutor” id=“TutorResult”>    
  18.     <id column=“tutor_id” property=“tutorId” />    
  19.     <result column=“tutor_name” property=“name” />    
  20.     <result column=“email” property=“email” />    
  21.     <association property=“address” resultMap=“AddressResult” />    
  22.     <collection property=“courses” resultMap=“CourseResult” />    
  23.   </resultMap>    
  24. </mapper>   
<mapper namespace="com.mybatis3.mappers.TutorMapper">  
  <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="courseId" />  
    <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" resultMap="AddressResult" />  
    <collection property="courses" resultMap="CourseResult" />  
  </resultMap>  
</mapper> 
  1. @Select(“SELECT T.TUTOR_ID, T.NAME AS TUTOR_NAME, EMAIL,    
  2.             A.ADDR_ID, STREET, CITY, STATE, ZIP, COUNTRY, COURSE_ID, C.NAME,    
  3.             DESCRIPTION, START_DATE, END_DATE  FROM TUTORS T LEFT OUTER    
  4.             JOIN ADDRESSES A ON T.ADDR_ID=A.ADDR_ID LEFT OUTER JOIN COURSES    
  5.             C ON T.TUTOR_ID=C.TUTOR_ID WHERE T.TUTOR_ID=#{tutorId}”)    
  6.     @ResultMap(“com.mybatis3.mappers.TutorMapper.TutorResult”)    
  7.     Tutor selectTutorById(int tutorId);    
@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}")  
    @ResultMap("com.mybatis3.mappers.TutorMapper.TutorResult")  
    Tutor selectTutorById(int tutorId);  
动态SQL
有时候我们需要根据输入条件动态地构建SQL语句。MyBatis提供了各种注解如@InsertProvider, @UpdateProvider
@DeleteProvider和@SelectProvider,来帮助构建动态SQL语句,然后让MyBatis执行这些SQL语句。

1.@SelectProvider

现在来看一个使用@SelectProvider注解来创建一个简单的SELECT映射语句的例子。
创建一个TutorDynaSqlProvider.java类,以及findTutorByIdSql()方法,如下所示:
  1. public class TutorDynaSqlProvider    
  2. {    
  3.     public String findTutorByIdSql(int tutorId)    
  4.     {    
  5.         return “SELECT TUTOR_ID AS tutorId, NAME, EMAIL FROM TUTORS    
  6.                WHERE TUTOR_ID=” + tutorId;    
  7.     }    
  8. }  
public class TutorDynaSqlProvider  
{  
    public String findTutorByIdSql(int tutorId)  
    {  
        return "SELECT TUTOR_ID AS tutorId, NAME, EMAIL FROM TUTORS  
               WHERE TUTOR_ID=" + tutorId;  
    }  
}

然后创建一个映射语句
  1. @SelectProvider(type=TutorDynaSqlProvider.class, method=“findTutorByIdSql”)    
  2. Tutor findTutorById(int tutorId);   
@SelectProvider(type=TutorDynaSqlProvider.class, method="findTutorByIdSql")  
Tutor findTutorById(int tutorId); 
这里我们使用了@SelectProvider来指定了一个类,及其内部的方法,用来提供需要执行的SQL语句。
但是使用字符串拼接的方法构建SQL语句是非常困难的,并且容易出错。所以MyBaits提供了一个SQL工具类不使用字符串拼接的方式,简化构造动态SQL语句。

现在,来看看如何使用org.apache.ibatis.jdbc.SQL工具类来准备相同的SQL语句。
  1. public class TutorDynaSqlProvider    
  2. {    
  3.     public String findTutorByIdSql(final int tutorId)    
  4.     {    
  5.         return new SQL()    
  6.         {    
  7.             {    
  8.                 SELECT(”tutor_id as tutorId, name, email”);    
  9.                 FROM(”tutors”);    
  10.                 WHERE(”tutor_id=” + tutorId);    
  11.             }    
  12.         } .toString();    
  13.     }    
  14. }    
public class TutorDynaSqlProvider  
{  
    public String findTutorByIdSql(final int tutorId)  
    {  
        return new SQL()  
        {  
            {  
                SELECT("tutor_id as tutorId, name, email");  
                FROM("tutors");  
                WHERE("tutor_id=" + tutorId);  
            }  
        } .toString();  
    }  
}  
SQL工具类会处理以合适的空格前缀和后缀来构造SQL语句。
动态 SQL provider方法可以接收以下其中一种参数:
  •            无参数
  •            和映射器Mapper接口的方法同类型的参数
  •            java.util.Map 
如果SQL语句的准备不取决于输入参数,你可以使用不带参数的SQL Provider方法。
例如:
  1. public String findTutorByIdSql()    
  2. {    
  3.     return new SQL()    
  4.     {    
  5.         {    
  6.             SELECT(”tutor_id as tutorId, name, email”);    
  7.             FROM(”tutors”);    
  8.             WHERE(”tutor_id = #{tutorId}”);    
  9.         }    
  10.     } .toString();    
  11. }    
public String findTutorByIdSql()  
{  
    return new SQL()  
    {  
        {  
            SELECT("tutor_id as tutorId, name, email");  
            FROM("tutors");  
            WHERE("tutor_id = #{tutorId}");  
        }  
    } .toString();  
}  

这里我们没有使用输入参数构造SQL语句,所以它可以是一个无参方法。

如果映射器Mapper接口方法只有一个参数,那么可以定义SQLProvider方法,它接受一个与Mapper接口方法相同类型的参数。

例如映射器Mapper接口有如下定义:
  1. Tutor findTutorById(int tutorId);  
Tutor findTutorById(int tutorId);

这里findTutorById(int)方法只有一个int类型的参数。我们可以定义findTutorByIdSql(int)方法作为SQL provider方法。


  1. public String findTutorByIdSql(final int tutorId)    
  2. {    
  3.     return new SQL()    
  4.     {    
  5.         {    
  6.             SELECT(”tutor_id as tutorId, name, email”);    
  7.             FROM(”tutors”);    
  8.             WHERE(”tutor_id=” + tutorId);    
  9.         }    
  10.     } .toString();    
  11. }    
public String findTutorByIdSql(final int tutorId)  
{  
    return new SQL()  
    {  
        {  
            SELECT("tutor_id as tutorId, name, email");  
            FROM("tutors");  
            WHERE("tutor_id=" + tutorId);  
        }  
    } .toString();  
}  

如果映射器Mapper接口有多个输入参数,我们可以使用参数类型为java.util.Map的方法作为SQLprovider方法。然后映射器Mapper接口方法所有的输入参数将会被放到map中,以param1,param2等等作为key,将输入参数按序作为value。你也可以使用0,1,2等作为key值来取的输入参数。
  1. @SelectProvider(type = TutorDynaSqlProvider.class,    
  2.                 method = ”findTutorByNameAndEmailSql”)    
  3. Tutor findTutorByNameAndEmail(String name, String email);    
  4. public String findTutorByNameAndEmailSql(Map<String, Object> map)    
  5. {    
  6.     String name = (String) map.get(”param1”);    
  7.     String email = (String) map.get(”param2”);    
  8.     //you can also get those values using 0,1 keys    
  9.     //String name = (String) map.get(“0”);    
  10.     //String email = (String) map.get(“1”);    
  11.     return new SQL()    
  12.     {    
  13.         {    
  14.             SELECT(”tutor_id as tutorId, name, email”);    
  15.             FROM(”tutors”);    
  16.             WHERE(”name=#{name} AND email=#{email}”);    
  17.         }    
  18.     } .toString();    
  19. }    
@SelectProvider(type = TutorDynaSqlProvider.class,  
                method = "findTutorByNameAndEmailSql")  
Tutor findTutorByNameAndEmail(String name, String email);  
public String findTutorByNameAndEmailSql(Map<String, Object> map)  
{  
    String name = (String) map.get("param1");  
    String email = (String) map.get("param2");  
    //you can also get those values using 0,1 keys  
    //String name = (String) map.get("0");  
    //String email = (String) map.get("1");  
    return new SQL()  
    {  
        {  
            SELECT("tutor_id as tutorId, name, email");  
            FROM("tutors");  
            WHERE("name=#{name} AND email=#{email}");  
        }  
    } .toString();  
}  

SQL工具类也提供了其他的方法来表示JOINS,ORDER_BY,GROUP_BY等等。
让我们看一个使用LEFT_OUTER_JOIN的例子:
  1. public class TutorDynaSqlProvider    
  2. {    
  3.     public String selectTutorById()    
  4.     {    
  5.         return new SQL()    
  6.         {    
  7.             {    
  8.                 SELECT(”t.tutor_id, t.name as tutor_name, email”);    
  9.                 SELECT(”a.addr_id, street, city, state, zip, country”);    
  10.                 SELECT(“course_id, c.name as course_name, description,    
  11.                        start_date, end_date”);    
  12.                 FROM(”TUTORS t”);    
  13.                 LEFT_OUTER_JOIN(”addresses a on t.addr_id=a.addr_id”);    
  14.                 LEFT_OUTER_JOIN(”courses c on t.tutor_id=c.tutor_id”);    
  15.                 WHERE(”t.TUTOR_ID = #{id}”);    
  16.             }    
  17.         } .toString();    
  18.     }    
  19. }    
  20.     
  21. public interface TutorMapper    
  22. {    
  23.     @SelectProvider(type = TutorDynaSqlProvider.class,    
  24.                     method = ”selectTutorById”)    
  25.     @ResultMap(“com.mybatis3.mappers.TutorMapper.TutorResult”)    
  26.     Tutor selectTutorById(int tutorId);    
  27. }   
public class TutorDynaSqlProvider  
{  
    public String selectTutorById()  
    {  
        return new SQL()  
        {  
            {  
                SELECT("t.tutor_id, t.name as tutor_name, email");  
                SELECT("a.addr_id, street, city, state, zip, country");  
                SELECT("course_id, c.name as course_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 = #{id}");  
            }  
        } .toString();  
    }  
}  

public interface TutorMapper  
{  
    @SelectProvider(type = TutorDynaSqlProvider.class,  
                    method = "selectTutorById")  
    @ResultMap("com.mybatis3.mappers.TutorMapper.TutorResult")  
    Tutor selectTutorById(int tutorId);  
} 
由于没有支持使用内嵌结果ResultMap的一对多关联映射的注解支持,我们可以使用基于XML的<resultMap>配置,然后与@ResultMap映射。

2.@InsertProvider

可以使用@InsertProvider注解创建动态的INSERT语句,如下所示:
  1. public class TutorDynaSqlProvider    
  2. {    
  3.     public String insertTutor(final Tutor tutor)    
  4.     {    
  5.         return new SQL()    
  6.         {    
  7.             {    
  8.                 INSERT_INTO(”TUTORS”);    
  9.                 if (tutor.getName() != null)    
  10.                 {    
  11.                     VALUES(”NAME”“#{name}”);    
  12.                 }    
  13.                 if (tutor.getEmail() != null)    
  14.                 {    
  15.                     VALUES(”EMAIL”“#{email}”);    
  16.                 }    
  17.             }    
  18.         } .toString();    
  19.     }    
  20. }    
  21. public interface TutorMapper    
  22. {    
  23.     @InsertProvider(type = TutorDynaSqlProvider.class,    
  24.                     method = ”insertTutor”)    
  25.     @Options(useGeneratedKeys = true, keyProperty = “tutorId”)    
  26.     int insertTutor(Tutor tutor);    
  27. }    
public class TutorDynaSqlProvider  
{  
    public String insertTutor(final Tutor tutor)  
    {  
        return new SQL()  
        {  
            {  
                INSERT_INTO("TUTORS");  
                if (tutor.getName() != null)  
                {  
                    VALUES("NAME", "#{name}");  
                }  
                if (tutor.getEmail() != null)  
                {  
                    VALUES("EMAIL", "#{email}");  
                }  
            }  
        } .toString();  
    }  
}  
public interface TutorMapper  
{  
    @InsertProvider(type = TutorDynaSqlProvider.class,  
                    method = "insertTutor")  
    @Options(useGeneratedKeys = true, keyProperty = "tutorId")  
    int insertTutor(Tutor tutor);  
}  


3.@UpdateProvider
可以通过@UpdateProvider注解创建UPDATE语句,如下所示:
  1. public class TutorDynaSqlProvider    
  2. {    
  3.     public String updateTutor(final Tutor tutor)    
  4.     {    
  5.         return new SQL()    
  6.         {    
  7.             {    
  8.                 UPDATE(”TUTORS”);    
  9.                 if (tutor.getName() != null)    
  10.                 {    
  11.                     SET(”NAME = #{name}”);    
  12.                 }    
  13.                 if (tutor.getEmail() != null)    
  14.                 {    
  15.                     SET(”EMAIL = #{email}”);    
  16.                 }    
  17.                 WHERE(”TUTOR_ID = #{tutorId}”);    
  18.             }    
  19.         } .toString();    
  20.     }    
  21. }    
  22. public interface TutorMapper    
  23. {    
  24.     @UpdateProvider(type = TutorDynaSqlProvider.class,    
  25.                     method = ”updateTutor”)    
  26.     int updateTutor(Tutor tutor);    
  27. }    
public class TutorDynaSqlProvider  
{  
    public String updateTutor(final Tutor tutor)  
    {  
        return new SQL()  
        {  
            {  
                UPDATE("TUTORS");  
                if (tutor.getName() != null)  
                {  
                    SET("NAME = #{name}");  
                }  
                if (tutor.getEmail() != null)  
                {  
                    SET("EMAIL = #{email}");  
                }  
                WHERE("TUTOR_ID = #{tutorId}");  
            }  
        } .toString();  
    }  
}  
public interface TutorMapper  
{  
    @UpdateProvider(type = TutorDynaSqlProvider.class,  
                    method = "updateTutor")  
    int updateTutor(Tutor tutor);  
}  


4.DeleteProvider
可以使用@DeleteProvider注解创建动态地DELETE语句,如下所示:
  1. public class TutorDynaSqlProvider    
  2. {    
  3.     public String deleteTutor(int tutorId)    
  4.     {    
  5.         return new SQL()    
  6.         {    
  7.             {    
  8.                 DELETE_FROM(”TUTORS”);    
  9.                 WHERE(”TUTOR_ID = #{tutorId}”);    
  10.             }    
  11.         } .toString();    
  12.     }    
  13. }    
  14. public interface TutorMapper    
  15. {    
  16.     @DeleteProvider(type = TutorDynaSqlProvider.class,    
  17.                     method = ”deleteTutor”)    
  18.     int deleteTutor(int tutorId);    
  19. }    
public class TutorDynaSqlProvider  
{  
    public String deleteTutor(int tutorId)  
    {  
        return new SQL()  
        {  
            {  
                DELETE_FROM("TUTORS");  
                WHERE("TUTOR_ID = #{tutorId}");  
            }  
        } .toString();  
    }  
}  
public interface TutorMapper  
{  
    @DeleteProvider(type = TutorDynaSqlProvider.class,  
                    method = "deleteTutor")  
    int deleteTutor(int tutorId);  
}  


注意事项:


  • 在利用注解配置映射器接口的时候,必须要通过 sqlSessionFactory.getConfiguration().addMapper(IBlogDAO.class);来对给映射器接口注册,如果映射器接口中使用了@ResultMap注解,则由于已经在mybatis-config.xml配置了Mapper,则就不需要再次在代码中添加mapper。


  • 当方法有多个参数的时候,为了与SQL语句中的#{}对应,一般可以使用@Param(“”)来为每个参数命别名,使得该别名与#{}对应。当参数只有一个的时候,不需要别名。


  • 在进行更新删除添加的时候,如果传递的是一个实体对象,则SQL可以直接使用实体的属性。


  • 映射器接口调用SqlBuilder中的方法,都是将参数转换为Map中的key,可以在SqlBuilder的方法中利用Map来获取传递的参数值,进而进行逻辑操作判断。


  • 注解中对于返回多条记录的查询可以直接利用@Results和@Result来配置映射,或者利用@ResultMap来调用SQL配置文件中的ResultMap。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值