Can I use MyBatis to generate Dynamic SQL without executing it?

Although MyBatis was designed to execute the query after it builds it, you can make use of it‘s configuration and a little bit of "inside knowledge" to get to what you need.

MyBatis is a very nice framework, unfortunately it lacks on the documentations side so the source code is you friend. If you dig around you should bump into these classes: org.apache.ibatis.mapping.MappedStatement and org.apache.ibatis.mapping.BoundSql which are key players into building the dynamic SQL. Here is a basic usage example:

MySQL table user with this data in it:

name    login
-----   -----
Andy    a
Barry   b
Cris    c

User class:

package pack.test;
public class User {
    private String name;
    private String login;
    // getters and setters ommited
}

UserService interface:

package pack.test;
public interface UserService {
    // using a different sort of parameter to show some dynamic SQL
    public User getUser(int loginNumber);
}

UserService.xml mapper file:

<mapper namespace="pack.test.UserService">
    <select id="getUser" resultType="pack.test.User" parameterType="int">
       <!-- dynamic change of parameter from int index to login string -->
       select * from user where login = <choose>
                                           <when test="_parameter == 1">‘a‘</when>
                                           <when test="_parameter == 2">‘b‘</when>
                                           <otherwise>‘c‘</otherwise>
                                        </choose>
    </select>
</mapper>

sqlmap-config.file:

<configuration>
    <settings>
        <setting name="lazyLoadingEnabled" value="false" />
    </settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost/test"/>
                <property name="username" value="..."/>
                <property name="password" value="..."/>
            </dataSource>
        </environment>
      </environments>
    <mappers>
        <mapper resource="pack/test/UserService.xml"/>
    </mappers>
</configuration>

AppTester to show the result:

package pack.test;

import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class AppTester {
    private static String CONFIGURATION_FILE = "sqlmap-config.xml";

    public static void main(String[] args) throws Exception {
        Reader reader = null;
        SqlSession session = null;
        try {

            reader = Resources.getResourceAsReader(CONFIGURATION_FILE);
            session = new SqlSessionFactoryBuilder().build(reader).openSession();
            UserService userService = session.getMapper(UserService.class);

            // three users retreived from index
            for (int i = 1; i <= 3; i++) {
                User user = userService.getUser(i);
                System.out.println("Retreived user: " + user.getName() + " " + user.getLogin());

                // must mimic the internal statement key for the mapper and method you are calling
                MappedStatement ms = session.getConfiguration().getMappedStatement(UserService.class.getName() + ".getUser");
                BoundSql boundSql = ms.getBoundSql(i); // parameter for the SQL statement
                System.out.println("SQL used: " + boundSql.getSql());
                System.out.println();
            }

        } finally {
            if (reader != null) {
                reader.close();
            }
            if (session != null) {
                session.close();
            }
        }
    }
}

And the result:

Retreived user: Andy a
SQL used: select * from user where login =  ‘a‘

Retreived user: Barry b
SQL used: select * from user where login =  ‘b‘

Retreived user: Cris c
SQL used: select * from user where login =  ‘c‘

http://stackoverflow.com/questions/13195144/can-i-use-mybatis-to-generate-dynamic-sql-without-executing-it

https://my.oschina.net/lichhao/blog/114311

时间: 2024-10-12 21:08:36

Can I use MyBatis to generate Dynamic SQL without executing it?的相关文章

IDEA+SpringBoot MyBatis Dynamic SQL的初体验(一)

ybatis generator在2017年12月发布了version 1.3.6,在该版本添加了新的TargetRuntime: MyBatis Dynamic SQL(mybatis 动态SQL)    Mybatis Dynamic Sql与以前TargetRuntime相比较: 移除了XXXExamle类和xml文件,代价是不兼容其他的TargetRuntime java版本限制,生成器将需要运行Java 8,低版本可能会出现错误 代码逻辑相对以前,使用了 lambda表达式,是的较容易

IDEA+SpringBoot MyBatis Dynamic SQL的初体验(二)

在上节IDEA+SpringBoot MyBatis Dynamic SQL的初体验(一)中,讲解了Mybatis Dynamic SQL数据库生成https://www.cnblogs.com/hjm0928/p/9955228.html 现在那看一下怎么使用 先看一下项目结构 可以看到实体类,Mapper文件和DynamicSqlSupport文件都生成成功了 第一步 修改application.properties修改为application.yml  内容如下 spring: datas

ABAP动态生成经典应用之Dynamic SQL Excute 程序

[转自http://blog.csdn.net/mysingle/article/details/678598]开发说明:在SAP的系统维护过程中,有时我们需要修改一些Table中的数据,可是很多Table又不能直接在Tcode:SE16中修改,使用的SAP ID又没有调试数据修改权限,这时我们应该怎么样修改数据呢?思路--> ABAP程序中的SQL 更新语句谁都有权限执行,只要我们能动态生成修改该Table字段的ABAP CODE动态执行即可! 开发技术: 1.SQL代码编写技术 1.动态程序

MyBatis中的动态SQL

动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号.利用动态 SQL 这一特性可以彻底摆脱这种痛苦. 虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形. 动态 SQL 元素和 JSTL 或基于类似 XML 的文本处

使用Log4jdbc-log4j2监听MyBatis中运行的SQL和Connection

引言: 在项目中使用了MyBatis,一个比较苦恼的问题是无法看到执行的SQL的具体情况,所以,就找到了Log4jdbc-log4j2.这个是一个基于jdbc层面的监听工具,可以监听对于数据库的主要操作,从而完美的查看到其中执行的操作. 1. Log4jdbc-log4j2版本选择 log4jdbc-log4j2-jdbc3.jar for JDBC 3 support in JDK 1.5 log4jdbc-log4j2-jdbc4.jar for JDBC 4 support in JDK

Mybatis使用之动态SQL语句

Mybatis使用之动态SQL语句 一:简介 Mybatis动态SQL语句可帮助我们根据需要动态拼接SQL语句.主要在配置文件中使用<where> <if><choose><when><otherwise> <set> <trim><foreach>标签来实现. 二:具体使用方式 2.1 where 2.1.1 功能 语句的作用主要是简化SQL语句中where中的条件判断,where元素的作用是会在写入wher

mybatis中的java.sql.SQLException: ORA-00942: 表或视图不存在

java.sql.SQLException: ORA-00942: 表或视图不存在这个问题花了我长时间 首先说明这个是在oracle数据库中使用mybatis操作数据库的 导致这个错误的原因的可能是 1.你的sql语句有错,将你的sql语句放到命令行下执行,用户名和密码需要与配置文件中的一致: 2.检查你的权限是否满足: 3.如果你的sql语句在pl/sql中能够运行,但是你的命令行中不能运行,则是你的访问权限问题,必须保证你的配置文件的用户名和密码在你的命令行中一致才能访问同样的表,plsql

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

mybatis结合log4j打印SQL日志

1.Maven引用jar包 默认的mybatis不能打印出SQL日志,不便于查看调试,须要结合log4jdbc-log4j2就能够完整的输入SQL的调试信息. pom.xml 配置maven.注意以下3个都须要 <dependency> <groupId>org.bgee.log4jdbc-log4j2</groupId> <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId> <version&g