Mybatis常用工具类-SQL类

Posted zhixuChen200

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis常用工具类-SQL类相关的知识,希望对你有一定的参考价值。

文章目录


前言

从本章开始将会从Mybatis源码分析,一步一步分析Mybatis,坐到深入浅出。
注:本系列文章主要参考书籍《Mybatis3源码深度解析》
源码地址:https://github.com/jiangrongbo/mybatis-book


一、JDBC

MyBatis框架对JDBC做了轻量级的封装,作为Java开发人员,我们对JDBC肯定不会陌生,但是要看懂MyBatis的源码,还需要熟练掌握JDBC API的使用。

使用JDBC操作数据源大致需要以下几个步骤:
(1)与数据源建立连接。
(2)执行SQL语句。
(3)检索SQL执行结果。
(4)关闭连接。

1.Connection

一个Connection对象表示通过JDBC驱动与数据源建立的连接,这里的数据源可以是关系型数据库管理系统(DBMS)、文件系统或者其他通过JDBC驱动访问的数据。使用JDBC API的应用程序可能需要维护多个Connection对象,一个Connection对象可能访问多个数据源,也可能访问单个数据源。

接下来看看两个例子:
例子一是通过DriverManager对象获取连接

public class Example01 
    @Test
    public void testJdbc() 
        // 初始化数据
        DbUtils.initData();
        try 
            // 加载驱动
            Class.forName("org.hsqldb.jdbcDriver");
            // 获取Connection对象
            Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis",
                    "sa", "");
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("select * from user");
            // 遍历ResultSet
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columCount = metaData.getColumnCount();
            while (resultSet.next()) 
                for (int i = 1; i <= columCount; i++) 
                    String columName = metaData.getColumnName(i);
                    String columVal = resultSet.getString(columName);
                    System.out.println(columName + ":" + columVal);
                
                System.out.println("--------------------------------------");
            
            // 关闭连接
            IOUtils.closeQuietly(statement);
            IOUtils.closeQuietly(connection);
         catch (Exception e) 
            e.printStackTrace();
        
    

例子二通过DataSource对象获取连接

public class Example03 
    @Test
    public void testJdbc() 
        // 初始化数据
        DbUtils.initData();
        try 
            // 创建DataSource实例
            DataSourceFactory dsf = new UnpooledDataSourceFactory();
            Properties properties = new Properties();
            InputStream configStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("database.properties");
            properties.load(configStream);
            dsf.setProperties(properties);
            DataSource dataSource = dsf.getDataSource();
            // 获取Connection对象
            Connection connection = dataSource.getConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery("select * from user");
            // 遍历ResultSet
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columCount = metaData.getColumnCount();
            while (resultSet.next()) 
                for (int i = 1; i <= columCount; i++) 
                    String columName = metaData.getColumnName(i);
                    String columVal = resultSet.getString(columName);
                    System.out.println(columName + ":" + columVal);
                
                System.out.println("----------------------------------------");
            
            // 关闭连接
            IOUtils.closeQuietly(statement);
            IOUtils.closeQuietly(connection);
         catch (Exception e) 
            e.printStackTrace();
        
    

区别就是:DataSource对象是从配置文件中读取数据库信息,这样若是数据库的信息发生变化,就无需改动代码。

2.Statement类

Statement接口中定义了执行SQL语句的方法,这些方法不支持参数输入,PreparedStatement接口中增加了设置SQL参数的方法,CallableStatement接口继承自PreparedStatement,在此基础上增加了调用存储过程以及检索存储过程调用结果的方法。

Statement的主要作用是与数据库进行交互,该接口中定义了一些数据库操作以及检索SQL执行结果相关的方法,具体如下:


例子:

public class Example06 
    @Before
    public void initData() throws  Exception 
        // 初始化数据
        Class.forName("org.hsqldb.jdbcDriver");
        // 获取Connection对象
        Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis",
                "sa", "");
        // 使用Mybatis的ScriptRunner工具类执行数据库脚本
        ScriptRunner scriptRunner = new ScriptRunner(conn);
        // 不输出sql日志
        scriptRunner.setLogWriter(null);
        scriptRunner.runScript(Resources.getResourceAsReader("create-table.sql"));
        System.out.println("----------------------");
    

    @Test
    public void testJdbc() 
        try 
            // 创建DataSource实例
            DataSourceFactory dsf = new UnpooledDataSourceFactory();
            Properties properties = new Properties();
            InputStream configStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("database.properties");
            properties.load(configStream);
            dsf.setProperties(properties);
            DataSource dataSource = dsf.getDataSource();
            // 获取Connection对象
            Connection connection = dataSource.getConnection();
            PreparedStatement stmt = connection.prepareStatement("insert into  " +
                    "user(create_time, name, password, phone, nick_name) " +
                    "values(?,?,?,?,?);");
            stmt.setString(1,"2010-10-24 10:20:30");
            stmt.setString(2,"User1");
            stmt.setString(3,"test");
            stmt.setString(4,"18700001111");
            stmt.setString(5,"User1");
            ParameterMetaData pmd = stmt.getParameterMetaData();
            for(int i = 1; i <= pmd.getParameterCount(); i++) 
                String typeName = pmd.getParameterTypeName(i);
                String className = pmd.getParameterClassName(i);
                System.out.println("第" + i + "个参数," + "typeName:" + typeName + ", className:" + className);
            
            stmt.execute();
            // 关闭连接
            IOUtils.closeQuietly(stmt);
            IOUtils.closeQuietly(connection);
         catch (Exception e) 
            e.printStackTrace();
        
    

3.ResultSet类

ResultSet接口是JDBC API中另一个比较重要的组件,提供了检索和操作SQL执行结果相关的方法。

ResultSet对象的类型主要体现在两个方面:
(1)游标可操作的方式。
(2)ResultSet对象的修改对数据库的影响。

ResultSet有3种不同的类型,分别说明如下:

  • TYPE_FORWARD_ONLY:这种类型的ResultSet不可滚动,游标只能向前移动,从第一行到最后一行,不允许向后移动,即只能使用ResultSet接口的next()方法,而不能使用previous()方法,否则会产生错误。
  • TYPE_SCROLL_INSENSITIVE:这种类型的ResultSet是可滚动的,它的游标可以相对于当前位置向前或向后移动,也可以移动到绝对位置。当ResultSet没有关闭时,ResultSet的修改对数据库不敏感,也就是说对ResultSet对象的修改不会影响对应的数据库中的记录。
  • TYPE_SCROLL_SENSITIVE:这种类型的ResultSet是可滚动的,它的游标可以相对于当前位置向前或向后移动,也可以移动到绝对位置。当ResultSet没有关闭时,对ResultSet对象的修改会直接影响数据库中的记录。

4.DatabaseMetaData类

DatabaseMetaData接口是由JDBC驱动程序实现的,用于提供底层数据源相关的信息。该接口主要用于为应用程序或工具确定如何与底层数据源交互。应用程序也可以使用DatabaseMetaData接口提供的方法获取数据源信息。
DatabaseMetaData接口中包含超过150个方法,根据这些方法的类型可以分为以下几类:
(1)获取数据源信息。
(2)确定数据源是否支持某一特性或功能。
(3)获取数据源的限制。
(4)确定数据源包含哪些SQL对象以及这些对象的属性。
(5)获取数据源对事务的支持。

例子:

public class Example08 

    @Test
    public void testDbMetaData() 
        try 
            Class.forName("org.hsqldb.jdbcDriver");
            // 获取Connection对象
            Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis",
                    "sa", "");
            DatabaseMetaData dmd = conn.getMetaData();
            System.out.println("数据库URL:" + dmd.getURL());
            System.out.println("数据库用户名:" + dmd.getUserName());
            System.out.println("数据库产品名:" + dmd.getDatabaseProductName());
            System.out.println("数据库产品版本:" + dmd.getDatabaseProductVersion());
            System.out.println("驱动主版本:" + dmd.getDriverMajorVersion());
            System.out.println("驱动副版本:" + dmd.getDriverMinorVersion());
            System.out.println("数据库供应商用于schema的首选术语:" + dmd.getSchemaTerm());
            System.out.println("数据库供应商用于catalog的首选术语:" + dmd.getCatalogTerm());
            System.out.println("数据库供应商用于procedure的首选术语:" + dmd.getProcedureTerm());
            System.out.println("null值是否高排序:" + dmd.nullsAreSortedHigh());
            System.out.println("null值是否低排序:" + dmd.nullsAreSortedLow());
            System.out.println("数据库是否将表存储在本地文件中:" + dmd.usesLocalFiles());
            System.out.println("数据库是否为每个表使用一个文件:" + dmd.usesLocalFilePerTable());
            System.out.println("数据库SQL关键字:" + dmd.getSQLKeywords());
            IOUtils.closeQuietly(conn);
         catch (Exception e) 
            e.printStackTrace();
        
    

5.JDBC事务

学这个之前可以先看一下我的这个文章:Mysql事务

Connection对象的autoCommit属性决定什么时候结束一个事务。启用自动提交后,会在每个SQL语句执行完毕后自动提交事务。当Connection对象创建时,默认情况下,事务自动提交是开启的。Connection接口中提供了一个setAutoCommit()方法,可以禁用事务自动提交。此时,需要显式地调用Connection接口提供commit()方法提交事务,或者调用rollback()方法回滚事务。禁用事务自动提交适用于需要将多个SQL语句作为一个事务提交或者事务由应用服务器管理。

例子:

public class Example09 

    @Before
    public void initData() throws  Exception 
        // 初始化数据
        Class.forName("org.hsqldb.jdbcDriver");
        // 获取Connection对象
        Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis",
                "sa", "");
        // 使用Mybatis的ScriptRunner工具类执行数据库脚本
        ScriptRunner scriptRunner = new ScriptRunner(conn);
        // 不输出sql日志
        scriptRunner.setLogWriter(null);
        scriptRunner.runScript(Resources.getResourceAsReader("create-table.sql"));
        System.out.println("------------------------");
    

    @Test
    public void testSavePoint() 
        try 
            Class.forName("org.hsqldb.jdbcDriver");
            // 获取Connection对象
            Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:mybatis",
                    "sa", "");
            String sql1 = "insert into user(create_time, name, password, phone, nick_name) " +
                    "values('2010-10-24 10:20:30','User1','test','18700001111','User1')";
            String sql2 = "insert into user(create_time, name, password, phone, nick_name) " +
                    "values('2010-10-24 10:20:30','User2','test','18700001111','User2')";
            conn.setAutoCommit(false);
            Statement stmt = conn.createStatement();
            stmt.executeUpdate(sql1);
            // 创建保存点
            Savepoint savepoint = conn.setSavepoint("SP1");
            stmt.executeUpdate(sql2);
            // 回滚到保存点
            conn.rollback(savepoint);
            conn.commit();
            ResultSet rs  = conn.createStatement().executeQuery("select * from user ");
            DbUtils.dumpRS(rs);
            IOUtils.closeQuietly(stmt);
            IOUtils.closeQuietly(conn);
         catch (Exception e) 
            e.printStackTrace();
        
    

二、使用SQL类生成语句

MyBatis中提供了一个SQL工具类。使用这个工具类,我们可以很方便地在Java代码中动态构建SQL语句。

1.无工具类写SQL语句

使用JDBC API开发过项目的读者应该知道,当我们需要使用Statement对象执行SQL时,SQL语句会嵌入Java代码中。SQL语句比较复杂时,我们可能会在代码中对SQL语句进行拼接,查询条件不固定时,还需要根据不同条件拼接不同的SQL语句,拼接语句时不要忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。这个过程对于开发人员来说简直就是一场噩梦,而且代码可维护性级低,例如:

 String orgSql = "SELECT P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME, P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON\\n" +
                        "FROM PERSON P, ACCOUNT A\\n" +
                        "INNER JOIN DEPARTMENT D on D.ID = P.DEPARTMENT_ID\\n" +
                        "INNER JOIN COMPANY C on D.COMPANY_ID = C.ID\\n" +
                        "WHERE (P.ID = A.ID AND P.FIRST_NAME like ?) \\n" +
                        "OR (P.LAST_NAME like ?)\\n" +
                        "GROUP BY P.ID\\n" +
                        "HAVING (P.LAST_NAME like ?) \\n" +
                        "OR (P.FIRST_NAME like ?)\\n" +
                        "ORDER BY P.ID, P.FULL_NAME";

2.使用工具类

public class SQLExample 

    @Test
    public void testSelectSQL() 
        String orgSql = "SELECT P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME, P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON\\n" +
                        "FROM PERSON P, ACCOUNT A\\n" +
                        "INNER JOIN DEPARTMENT D on D.ID = P.DEPARTMENT_ID\\n" +
                        "INNER JOIN COMPANY C on D.COMPANY_ID = C.ID\\n" +
                        "WHERE (P.ID = A.ID AND P.FIRST_NAME like ?) \\n" +
                        "OR (P.LAST_NAME like ?)\\n" +
                        "GROUP BY P.ID\\n" +
                        "HAVING (P.LAST_NAME like ?) \\n" +
                        "OR (P.FIRST_NAME like ?)\\n" +
                        "ORDER BY P.ID, P.FULL_NAME";

        String newSql =  new SQL().
                    SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME").
                    SELECT("P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON").
                    FROM("PERSON P").
                    FROM("ACCOUNT A").
                    INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID").
                    INNER_JOIN("COMPANY C on D.COMPANY_ID = C.ID").
                    WHERE("P.ID = A.ID").
                    WHERE("P.FIRST_NAME like ?").
                    OR().
                    WHERE("P.LAST_NAME like ?").
                    GROUP_BY("P.ID").
                    HAVING("P.LAST_NAME like ?").
                    OR().
                    HAVING("P.FIRST_NAME like ?").
                    ORDER_BY("P.ID").
                    ORDER_BY("P.FULL_NAME").toString();
        assertEquals(orgSql, newSql);
    

    Mybatis常用工具类(一)-- SQL

SQL介绍

SQL(org.apache.ibatis.jdbc.SQL) 是mybatis 自带 sql 构造对象。

表1:SQL的方法及作用介绍

方法 作用
SELECT(String)
SELECT(String...)
开始一个 SELECT 字句或将内容追加到 SELECT 字句。方法可以被多次调用,参数也会添加到 SELECT 字句。参数通常是使用 "," 分割的列名或列的别名列表,也可以是数据库驱动程序接收的任意关键字。
SELECT_DISTINCT(String)
SELECT_DISTINCT(String...)
开始一个 SELECT 字句或将内容追加到 SELECT 字句。同时可以追加 DISTINCT 关键字到SELECT 语句中。方法可以被多次调用,参数也会添加到 SELECT 字句。参数通常是使用 ”,“ 分割的列名或列的别名列表,也可以是数据库驱动程序接收的任意关键字。
FROM(String)
FROM(String...)
开始或追加 FROM 字句。方法可以被多次调用,参数会添加到 FROM 字句。参数通常是表名或别名,也可以是数据库驱动程序接收的任意关键字。
JOIN(String)
JOIN(String...)
INNER_JOIN(String)
INNER_JOIN(String...)
LEFT_OUTER_JOIN(String)
LEFT_OUTER_JOIN(String...)
RIGHT_OUTER_JOIN(String)
RIGHT_OUTER_JOIN(String...)
根据不同的方法添加到对应类型的 JOIN 字句, 例如 INNER_JOIN() 方法添加 INNER JOIN 字句, LEFT_OUTER_JOIN()方法增加 LEFT OUTER JOIN 字句。参数可以包含又列名和 JOIN ON 条件组合成的标准 JOIN。
WHERE(String)
WHERE(String...)
追加新的 WHERE 字句条件,并通过 AND 关键字连接。方法可以多次被调用,每次都由 AND 来连接新的条件。使用 OR() 方法可以追加 OR 关键字。
OR() 使用 OR 来分割当前的 WHERE 或 HAVING 字句条件。可以被多次调用,但在同一行中,多次调用,可能会生成错误的 SQL 语句。
AND() 使用 AND 来分割当前的 WHERE 或 HAVING 字句条件。可以被多次调用,但在同一行中,多次调用,可能会生成错误的 SQL 语句。 这个方法使用比较少,因为 WHERE() 和 HAVING() 方法都会自动追加 AND,只有必要时才会额外调用 AND() 方法。
GROUP_BY(String)
GROUP_BY(String...)
追加新的 GROUP BY 字句,通过 "," 连接。方法可以被多次调用,每次都会使用 "," 连接新的条件。
HAVING(String)
HAVING(String...)
追加新的 HAVING 字句条件。由 AND 关键字连接。方法可以被多次调用,每次都由 AND 连接新的条件。使用 OR() 方法可以追加 OR 关键字。
ORDER_BY(String)
ORDER_BY(String...)
追加新的 ORDER BY 字句元素,由 "," 连接。可以多次被调用,每次都由 "," 连接新的条件。
DELETE_FROM(String) 开始一个 DELETE 语句并指定表名。通常它后面都会跟着 WHERE 语句。
INSERT_INTO(String) 开始一个 INSERT 语句并指定表名,后面都会跟着一个或者多个VALUES(),或 INTO_COLUMNS()和 INTO_VALUES()。
SET(String)
SET(String...)
针对 UPDATE 语句,追加 SET 字句。
UPDATE(String) 开始一个 UPDATE 语句并制定需要更新的表名。后面都会跟着一个或者多个 SET() 方法,通常会有一个或多个 WHERE()方法。
VALUES(String, String) 追加 INSERT 语句中,第一个参数是要追加的列名,第二个参数则是列的值。
INTO_COLUMNS(String...) 追加列到 INSERT 语句中,必须和 INTO_VALUES() 联合使用。
INTO_VALUES(String...) 追加列的值到 INSERT 语句中,必须和 INTO_COLUMNS() 联合使用。

续表(3.5.2版本之后)

方法 作用
LIMIT(String)
LIMIT(int)
追加 LIMIT 语句。 该方法与 SELECT(),UPDATE(),DELETE()一起使用时有效。并且该方法设计在使用 SELECT() 时与 OFFSET() 一起使用。
OFFSET(String)
OFFSET(long)
追加 OFFSET 语句. 该方法与 SELECT() 一起使用时有效. 并且该方法设计在使用 SELECT() 时与 LIMIT() 一起使用。
OFFSET_ROWS(String)
OFFSET_ROWS(long)
追加 OFFSET n ROWS 语句. 该方法与 SELECT() 一起使用时有效。 该方法设计与 FETCH_FIRST_ROWS_ONLY() 一起使用。
FETCH_FIRST_ROWS_ONLY(String)
FETCH_FIRST_ROWS_ONLY(int)
追加 FETCH FIRST n ROWS ONLY 语句. 该方法与 SELECT() 一起使用时有效。 该方法设计与 OFFSET_ROWS() 一起使用。
ADD_ROW() 为批量追加增加新行。

SQL示例

查询

// 普通查询
String orgSql = "SELECT P.PERSON_ID, P.PERSON_NAME, P.NICK_NAME, "
        + "P.TITLE, P.AGE, C.COMPANY_NAME, C.CITY
"
        + "FROM PERSON P
"
        + "LEFT OUTER JOIN COMPANY C ON C.COMPANY_ID = P.COMPANY_ID
"
        + "WHERE (P.AGE > ? AND C.CITY = ?) 
"
        + "OR (P.AGE < ?)
"
        + "ORDER BY C.CITY, C.COMPANY_NAME";

String newSql = new SQL()
        .SELECT("P.PERSON_ID", "P.PERSON_NAME", "P.NICK_NAME")
        .SELECT("P.TITLE", "P.AGE", "C.COMPANY_NAME", "C.CITY")
        .FROM("PERSON P")
        .LEFT_OUTER_JOIN("COMPANY C ON C.COMPANY_ID = P.COMPANY_ID")
        .WHERE("P.AGE > ?")
        .WHERE("C.CITY = ?")
        .OR()
        .WHERE("P.AGE < ?")
        .ORDER_BY("C.CITY", "C.COMPANY_NAME")
        .toString();
Assert.assertEquals(orgSql, newSql);

// 聚合函数
orgSql = "SELECT MAX(P.AGE) MAX_AGE, C.COMPANY_NAME, C.CITY
"
        + "FROM PERSON P
"
        + "LEFT OUTER JOIN COMPANY C ON C.COMPANY_ID = P.COMPANY_ID
"
        + "WHERE (C.CITY IN(?, ?))
"
        + "GROUP BY C.COMPANY_NAME, C.CITY
"
        + "HAVING (MAX_AGE > ? AND C.CITY = ?) 
"
        + "OR (MAX_AGE < ?)
"
        + "ORDER BY C.CITY, C.COMPANY_NAME";

newSql = new SQL()
        .SELECT("MAX(P.AGE) MAX_AGE")
        .SELECT("C.COMPANY_NAME", "C.CITY")
        .FROM("PERSON P")
        .LEFT_OUTER_JOIN("COMPANY C ON C.COMPANY_ID = P.COMPANY_ID")
        .WHERE("C.CITY IN(?, ?)")
        .GROUP_BY("C.COMPANY_NAME", "C.CITY")
        .HAVING("MAX_AGE > ?")
        .HAVING("C.CITY = ?")
        .OR()
        .HAVING("MAX_AGE < ?")
        .ORDER_BY("C.CITY", "C.COMPANY_NAME")
        .toString();
Assert.assertEquals(orgSql, newSql);

查询(offset row)

String orgSql = "SELECT P.PERSON_ID, P.PERSON_NAME, P.NICK_NAME, "
        + "P.TITLE, P.AGE, C.COMPANY_NAME, C.CITY
"
        + "FROM PERSON P
"
        + "LEFT OUTER JOIN COMPANY C ON C.COMPANY_ID = P.COMPANY_ID
"
        + "WHERE (P.AGE > ? AND C.CITY = ?) 
"
        + "OR (P.AGE < ?)
"
        + "ORDER BY C.CITY, C.COMPANY_NAME OFFSET 10 ROWS FETCH FIRST 1 ROWS ONLY";

String newSql = new SQL()
        .SELECT("P.PERSON_ID", "P.PERSON_NAME", "P.NICK_NAME")
        .SELECT("P.TITLE", "P.AGE", "C.COMPANY_NAME", "C.CITY")
        .FROM("PERSON P")
        .LEFT_OUTER_JOIN("COMPANY C ON C.COMPANY_ID = P.COMPANY_ID")
        .WHERE("P.AGE > ?")
        .WHERE("C.CITY = ?")
        .OR()
        .WHERE("P.AGE < ?")
        .ORDER_BY("C.CITY", "C.COMPANY_NAME")
        .OFFSET_ROWS(10)
        .FETCH_FIRST_ROWS_ONLY(1)
        .ADD_ROW()
        .toString();
Assert.assertEquals(orgSql, newSql);

动态查询

String orgSql = "SELECT P.PERSON_ID, P.PERSON_NAME, P.NICK_NAME, "
        + "P.TITLE, P.AGE, C.COMPANY_NAME, C.CITY
"
        + "FROM PERSON P
"
        + "LEFT OUTER JOIN COMPANY C ON C.COMPANY_ID = P.COMPANY_ID
"
        + "WHERE (P.AGE > #{age} AND C.CITY = #{city})
"
        + "ORDER BY C.CITY, C.COMPANY_NAME";

String newSql = new SQL()
        .SELECT("P.PERSON_ID", "P.PERSON_NAME", "P.NICK_NAME")
        .SELECT("P.TITLE", "P.AGE", "C.COMPANY_NAME", "C.CITY")
        .FROM("PERSON P")
        .LEFT_OUTER_JOIN("COMPANY C ON C.COMPANY_ID = P.COMPANY_ID")
        .WHERE("P.AGE > #{age}")
        .WHERE("C.CITY = #{city}")
        .ORDER_BY("C.CITY", "C.COMPANY_NAME")
        .toString();
Assert.assertEquals(orgSql, newSql);

动态插入

String orgSql = "INSERT INTO PERSON
"
        + " (PERSON_ID, PERSON_NAME, NICK_NAME, TITLE, AGE, COMPANY_ID)
"
        + "VALUES (#{personId}, #{personName}, #{nickName}, #{title}, #{age}, #{companyId})";

String newSql = new SQL()
        .INSERT_INTO("PERSON")
        .INTO_COLUMNS("PERSON_ID", "PERSON_NAME", "NICK_NAME", "TITLE", "AGE", "COMPANY_ID")
        .INTO_VALUES("#{personId}", "#{personName}", "#{nickName}", "#{title}", "#{age}", "#{companyId}")
        .toString();
Assert.assertEquals(orgSql, newSql);

批量插入(多行)

String orgSql = "INSERT INTO PERSON
"
        + " (PERSON_ID, PERSON_NAME, NICK_NAME, TITLE, AGE, COMPANY_ID)
"
        + "VALUES (?, ?, ?, ?, ?, ?)
, (?, ?, ?, ?, ?, ?)";

String newSql = new SQL()
        .INSERT_INTO("PERSON")
        .INTO_COLUMNS("PERSON_ID", "PERSON_NAME", "NICK_NAME", "TITLE", "AGE", "COMPANY_ID")
        .INTO_VALUES("?", "?", "?", "?", "?", "?")
        .ADD_ROW()
        .INTO_VALUES("?", "?", "?", "?", "?", "?")
        .toString();
Assert.assertEquals(orgSql, newSql);

动态删除

String orgSql = "DELETE FROM PERSON
"
        + "WHERE (PERSON_ID = #{personId})";

String newSql = new SQL()
        .DELETE_FROM("PERSON")
        .WHERE("PERSON_ID = #{personId}")
        .toString();
Assert.assertEquals(orgSql, newSql);

动态更新

String orgSql = "UPDATE PERSON
"
        + "SET NICK_NAME = #{nickName}
"
        + "WHERE (PERSON_ID = #{personId})";

String newSql = new SQL()
        .UPDATE("PERSON")
        .SET("NICK_NAME = #{nickName}")
        .WHERE("PERSON_ID = #{personId}").toString();
Assert.assertEquals(orgSql, newSql);

公众号

喜欢我的文章,请关注公众号

技术图片

以上是关于Mybatis常用工具类-SQL类的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis批处理工具类MyBatisBatchHelper.java

Mybatis常用类原理

Mybatis获取Sqlsession的工具类

Mybatis获取Sqlsession的工具类

mybatis之动态SQL

mybatis 怎么使用example类 or使用生成sql