Mybatis之动态构建SQL语句

今天一个新同事问我,我知道如何利用XML的方式来构建动态SQL,可是Mybatis是否能够利用注解完成动态SQL的构建呢?!!答案是肯定的,MyBatis 提供了注解,@InsertProvider,@UpdateProvider,@DeleteProvider 和@SelectProvider,来帮助构建动态 SQL 语句,然后让MyBatis 执行这些 SQL 语句。

1.@InsertProvider
1.1简单示例使用

创建一个 TutorDynaSqlProvider.java 类,以及 findTutorByIdSql()方法

package com.test.myBatisTest;

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 接口中创建一个映射语句

1
2
@SelectProvider(type=TutorDynaSqlProvider.class, method=“findTutorByIdSql”)
Tutor findTutorById(int tutorId);
  1.2动态构建SQL语句
使用SQL类来构建动态SQL如下所示

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 语句。可以接受的参数类型无参数和映射器 Mapper 接口的方法以及同类型的参数 java.util.Map。 如果映射器 Mapper 接口有多个输入参数,我们可以使用参数类型为 java.util.Map 的方法作为 SQL provider 方法。然后映射器 Mapper 接口方法所有的输入参数将会被放到 map 中,以 param1,param2 等等作为 key,将输入参数按

序作为 value。 你也可以使用 0,1,2 等作为 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();
}

1.3 SQL 工具类也提供了其他的方法来表示 JOINS,ORDER_BY,GROUP_BY 等等。

package com.test.myBatisTest;
 
import org.apache.ibatis.jdbc.SQL;
 
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();
    }
}

2 使用@InsertProvider 注解创建动态的 INSERT 语句

package com.test.myBatisTest;
 
import org.apache.ibatis.jdbc.SQL;
 
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

package com.test.myBatisTest;
 
import org.apache.ibatis.jdbc.SQL;
 
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 注解创建动态地 DELETE 语句

package com.test.myBatisTest;
 
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.jdbc.SQL;
 
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);
}

以上就是使用注解的方式来动态的构建SQL,可以说和XML方式有很大的不同,但是功能上面似乎没有XML方式的强大,我个人更喜欢使用XML的方式来构建,同时对参数进行各种操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值