MyBatis SQL註解 動態SQL語句

MyBatis提供了多個註解如:@InsertProvider,@UpdateProvider,@DeleteProvider和@SelectProvider,這些都是創建動態語言和讓MyBatis執行這些語言。html

如今讓咱們來看一下如何使用@ SelectProvider來建立簡單的SELECT映射的例子。建立一個TutorDynaSqlProvider.java類,帶有findTutorByIdSql()的方法。java

PS:  mysql數據進行batch處理的時候,數據庫連接必定要修改增長rewriteBatchedStatements=truemysql

package com.owen.mybatis.sqlproviders;  
import org.apache.ibatis.jdbc.SQL;  

public class TutorDynaSqlProvider  {  
  
  public String findTutorByIdSql(int tutorId)  {  
        return "SELECT TUTOR_ID AS tutorId, NAME, EMAIL FROM TUTORS  WHERE TUTOR_ID="+tutorId;  
  } 
}  

 

建立接口類TutorMapper.java.sql

@SelectProvider(type=TutorDynaSqlProvider.class, method="findTutorByIdSql")  
Tutor findTutorById(int tutorId);  

這裏咱們聲明瞭@ SelectProvider去聲明類和方法名,這個將會在SQL聲明中執行。可是會用String來構造查詢語句時,是困難的,也是容易出錯了。因此MyBatis提供了SQL公用方法構造方法,不須要寫出完整的String語句。讓咱們來看一下如何使用org.apache.ibatis.jdbc.SQL的公用方法。數據庫

package com.owen.mybatis.sqlproviders;  
import org.apache.ibatis.jdbc.SQL;  
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方法能夠包含下面的任一參數:apache

1)        沒有參數mybatis

2)        與同類型的接口方法的參數同樣app

3)        java.util.Mapide

若是SQL的查詢不可以提供所依賴的參數,你可使用無參的SQL方法。函數

public String findTutorByIdSql()  
{  
    return new SQL() {{  
        SELECT("tutor_id as tutorId, name, email");  
        FROM("tutors");  
        WHERE("tutor_id = #{tutorId}");  
    }}.toString();  
}  

這裏咱們並無在咱們的方法中定義參數,因此是一個無參的方法。

若是一個映射的接口方法只有一個參數,咱們能夠以下定義SQL的方法:

  1. Tutor findTutorById(int tutorId);  

這裏的findTutorById(int)的方法擁有一個輸入的參數是int的類型。咱們能夠把findTutorBySql(int)方法做爲SQL提供的方法。

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的參數類型做爲SQL方法提供。因此全部輸入的參數都必須是map的類型,而且帶有param一、param2等做爲key的值,而輸入的參數是value的值。你也能夠輸入的參數爲0,1,2,3等做爲key值。

@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的例子:

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.owen.mybatis.mappers.TutorMapper.TutorResult")  
    Tutor selectTutorById(int tutorId);  
}

這裏並無使用一對多的註解,咱們能夠基於XML來配置<resultMap>和映射@ResultMap.

<mapper namespace="com.owen.mybatis.mappers.TutorMapper">  
    <resultMap type="Address" id="AddressResult">  
        <id property="id" 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="id"/>  
        <result column="course_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="id"/>  
        <result column="tutor_name" property="name"/>  
        <result column="email" property="email"/>  
        <association property="address" resultMap="AddressResult"/>  
        <collection property="courses" resultMap="CourseResult"></collection>  
    </resultMap>  
</mapper>  

使用這個動態的SQL語句,將會查找到教師的信息連帶着教師的地址和教授的課程信息。

1. @InserProvider

咱們能夠建立動態的INSERT查詢,使用@Insertprovider.

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

2. @UpdateProvider

     咱們能夠建立動態的UPDATE語句使用@UpdateProvider。

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

3. @DeleteProvider

咱們能夠建立DELETEf動態語句,使用@DeleProvider

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

==========================分割線================================

mybatis中enum類型數據註解的處理方式

1、使用參數構造器的方式來解決

@ConstructorArgs({
        @Arg(column="id",javaType=Integer.class),
        @Arg(column="name",javaType=String.class),
        @Arg(column="enum1",javaType= enum1.class,typeHandler=EnumOrdinalTypeHandler.class)
    })
    @Select(value="select id,name,enum1 from test1 where id=#{id}")
    Zhyonk queryTest(int id);

2、使用結果集映射註解來解決

@Results({ @Result(property = "enum1", column = "enum1", typeHandler = EnumOrdinalTypeHandler.class) })
    @Select(value = "select id,name,enum1 from test1 where id=#{id}")
    Zhyonk queryTest2(int id);

3、採用@TypeDiscriminator類型鑑別器

@TypeDiscriminator(
            column = "enum1",javaType = enum1.class,typeHandler=EnumOrdinalTypeHandler.class,
            cases={
                    @Case(value="zhyonk",type=Zhyonk.class,results={@Result(property="enum1",column="enum1",typeHandler=EnumOrdinalTypeHandler.class)})
                    ,@Case(value="success",type=Success.class,results={@Result(property="enum1",column="enum1",typeHandler=EnumOrdinalTypeHandler.class)})
            })
    @Select(value="select id,name,enum1 from test1 where id=#{id}")
    Zhyonk queryTest3(int id);

摘自:mybatis -typeHandler 使用

相關文章
相關標籤/搜索