• MyBatis注解应用之动态SQL语句


    有时候,我们需要在输入的标准下,创建动态的查的语言。MyBatis提供了多个注解如:@InsertProvider,@UpdateProvider,@DeleteProvider和@SelectProvider,这些都是建立动态语言和让MyBatis执行这些语言。

    现在让我们来看一下如何使用@ SelectProvider来创建简单的SELECT映射的例子。创建一个TutorDynaSqlProvider.java类,带有findTutorByIdSql()的方法。

    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.

    @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方法可以包含下面的任一参数:

    1)        没有参数

    2)        与同类型的接口方法的参数一样

    3)        java.util.Map

    如果SQL的查询不能够提供所依赖的参数,你可以使用无参的SQL方法。

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

    这里我们并没有在我们的方法中定义参数,所以是一个无参的方法。

    如果一个映射的接口方法只有一个参数,我们可以如下定义SQL的方法:

    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的类型,并且带有param1、param2等作为key的值,而输入的参数是value的值。你也可以输入的参数为0,1,2,3等作为key值。

    @SelectProvider(type=TutorDynaSqlProvider.class,
    method="findTutorByNameAndEmailSql")
    Tutor findTutorByNameAndEmail(String name, String email);
    public String findTutorByNameAndEmailSql(Map 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.

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    使用这个动态的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);
    }
    

    4.总结

    在前面的几个章节中,笔者主要向大家介绍是如何使用注解的方法来处理MyBatis的映射。所以这些知道其实是建立地XML的基础上的,只你理解了XML的使用,我们注解的使用不没的多大问题的。好的,到现在为止,MyBatis的基础用法基本上都已经介绍好的,下一章节,我们将会学习如何将MyBatis与Spring联合使用。源码下载:https://github.com/owenwilliam/mybatis.com.git


     

  • 相关阅读:
    zabbix6.0 部署配置
    关于 Data Lake 的概念、架构与应用场景介绍
    讲讲项目里的仪表盘编辑器(二)
    Redis分布式系统: 主从复制
    flutter 二维数组赋值问题
    Linux platform子系统【2】-PLATFORM注册(struct device)platform_bus
    CSS基础笔记
    基于Java毕业设计蛋糕店会员系统的设计与实现源码+系统+mysql+lw文档+部署软件
    大阳能充电新技术---Powerfoyle
    Mysql全局优化总结
  • 原文地址:https://blog.csdn.net/cqn2bd2b/article/details/126809167