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如下所示


1

2

3

4

5

6

7

8

9

10

11

12

13

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 值来取的输入参数。如下所示


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@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 等等。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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 语句


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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 语句


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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的方式来构建,同时对参数进行各种操作。

原文地址:https://www.cnblogs.com/jtlgb/p/10661527.html

时间: 2024-10-19 00:02:11

Mybatis之动态构建SQL语句的相关文章

mybatis LIKE动态参数 sql语句

@Select({ "select id, vedio_name, vedio_path,vedio_duration, vedio_classify_id, crt_user_id, crt_time", "from tbl_vedio_info", "where vedio_name LIKE concat(concat('%',#{keyword}),'%') LIMIT #{pageSize},8"}) 原文地址:https://www.

模拟Hibernate动态生成SQL语句

这里有一个xml配置文件,也就是Hibernate框架中会用到的POJO和数据库的映射文件 1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://www.hibernate.org/dtd/hibernate-

Mybatis中如何在SQL语句表名中使用参数

insert into prefix_${table_name} (a, b, c) values (#{a}, #{b}, #{c}) ${} 表示直接使用字面量(literal value) #{} 表示这个是个参数 如果 table_name 是 "ABC" 则 ${table_name} 是 ABC #{table_name} 是 "ABC" Mybatis中如何在SQL语句表名中使用参数,布布扣,bubuko.com

自定义ORMapping—动态生成SQL语句

概述 之前在自定义ORMapping--关系表转换为实体或实体集合对象中提到过ORMapping的东西,在那片博客中也有ORMapping实现的一个简单思路,当时只实现了关系表转换为实体或实体集合这个功能,没有实现动态生成SQL这个部分,本片博客就是完善之前的那片博客,实现动态生成SQL语句这么一个功能. 实现思路 1.创建两个自定义特性,分别为表特性和字段特性,目的就是给相应的实体类的类名和属性名,打上相应的特性,从而创建类名和表名,属性和表字段名之间的对应关系 2.创建一个特性解析类,用来解

Ibatis,Mybatis利用log4j将SQL语句打印在控制台

在做一个项目Demo的时候,使用MyBatis+Spring,发现写好的SQL查询出来不对劲,但是也没报错, 所以想到用日志把SQL语句打出来.也参考了部分网友的代码,最后总结了一下,发现正常运行. 本人项目为Mybatis+SpringMVC,所有都已配置好,且正常运行. 此过程无需配置,直接在classPath目录创建log4j.properties,文件,并将下列代码粘贴进去即可,此代码部分参考网友. ### set log levels ### log4j.rootLogger = de

java动态拼接sql语句并且执行时给sql语句的参数赋值

问题 在这里举一个例子,比如我要做一个多条件模糊查询,用户输入的时候有可能输入一个条件,也有可能输入两个条件,这时执行查询的sql语句就不确定了,但可以用动态拼接sql语句来解决这个问题. 解决方法 1.就拿我上面的那个多条件模糊查询为例,第一步是拼接sql语句,先定义一个通用的sql语句,String sql = "select * from user where 1 = 1 ";这里添加where 1= 1是一个小技巧,方便后面sql语句的拼接. String sql = &quo

动态拼接SQL语句

1.参考官方文档 ? if:字符判断 ? choose (when, otherwise):分支选择 ? trim (where, set):字符串截取:其中where标签封装查询条件,set标签封装修改条件 ? foreach 2.if案例 1)在EmployeeMapper接口中添加一个方法: //携带了哪个字段,查询条件就带上哪个字段的值 public List<Employee> getEmployeeByConditionIf(Employee employee); 2).如果要写下

MyBatis源码分析-SQL语句执行的完整流程

MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录.如何新建MyBatis源码工程请点击MyBatis源码分析-IDEA新建MyBatis源码工程. MyBatis框架主要完成的是以下2件事情: 根据JD

PL/SQL(五)PL/SQL中动态执行SQL语句

在PL/SQL程序开发中,可以使用DML语句和事务控制语句,但是还有很多语句(比如DDL语句)不能直接在PL/SQL中执行.这些语句可以使用动态SQL来实现. PL/SQL块先编译然后再执行,动态SQL语句在编译时不能确定,只有在程序执行时把SQL语句作为字符串的形式由动态SQL命令来执行.在编译阶段SQL语句作为字符串存在,程序不会对字符串中的内容进行编译,在运行阶段再对字符串中的SQL语句进行编译和执行,动态SQL的语法是: 语法格式:动态SQL EXECUTE IMMEDIATE 动态语句