MyBatis的动态SQL与日志Log4J、SQL语句构造器

一、MyBatis动态SQL

  • 动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

  • 使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

  • 如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

    if

    • 使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:
      
      
    • 这条语句提供了可选的查找文本功能。如果不传入 “title”,那么所有处于 “ACTIVE” 状态的 BLOG 都会返回;如果传入了 “title” 参数,那么就会对 “title” 一列进行模糊查找并返回对应的 BLOG 结果。
    • 通过 “title” 和 “author” 两个参数进行可选搜索,只需要加入另一个条件即可。
      
      

    choose、when、otherwise

    • MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG。
      
      

    trim、where、set

    • 将 “state = ‘ACTIVE’” 设置成动态条件。
      
      
    • 如果没有匹配的条件,最终这条 SQL 会变成这样:SELECT * FROM BLOG WHERE,这会导致查询失败。如果匹配的只是第二个条件,这条 SQL 会是这样:
      SELECT * FROM BLOG WHERE AND title like ‘someTitle’,这个查询也会失败。
    • MyBatis 有一个简单且适合大多数场景的解决办法。而在其他场景中,可以对其进行自定义以符合需求。
      
      
    • where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。
       ... 
      
    • prefixOverrides 属性会忽略通过管道符分隔的文本序列。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
      
        update Author
        
           username=#{username}, 
           password=#{password}, 
           email=#{email}, 
           bio=#{bio} 
        
        where id=#{id}
      
      
    • 与 set 元素等价的自定义 trim 元素
       ... 
      

    foreach

    • 动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。
      
      
    • foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。

    script

    • 要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素。
       @Update({""}) 
      void updateAuthorValues(Author author);
      

    bind

    • bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。
      
      

    多数据库支持

    • 如果配置了 databaseIdProvider,你就可以在动态代码中使用名为 “_databaseId” 的变量来为不同的数据库构建特定的语句。
      
        
          
            select seq_users.nextval from dual
          
          
            select nextval for seq_users from sysibm.sysdummy1"
          
        
          insert into users values (#{id}, #{name})
      
      

    动态 SQL 中的插入脚本语言

    • MyBatis 从 3.2 版本开始支持插入脚本语言,这允许你插入一种语言驱动,并基于这种语言来编写动态 SQL 查询语句。
      public  interface  LanguageDriver  {
          ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject,  BoundSql boundSql); 
          SqlSource createSqlSource(Configuration configuration,  XNode script,  Class parameterType); 
          SqlSource createSqlSource(Configuration configuration,  String script,  Class parameterType);  
      }
      
    • 实现自定义语言驱动后,你就可以在 mybatis-config.xml 文件中将它设置为默认语言:
      
        
      
      
        
      
      
    • 你也可以使用 lang 属性为特定的语句指定语言:
      
      
    • 在你的 mapper 接口上添加 @Lang 注解:
      public  interface  Mapper  {
          @Lang(MyLanguageDriver.class)
          @Select("SELECT * FROM BLOG")
          List selectBlog();
      }
      

二、MyBatis缓存

  • 默认情况下,只启用了本地的会话缓存(SqlSession),它仅仅对一个会话中的数据进行缓存,会话缓存也称为一级缓存。二级缓存是全局缓存(SqlSessionFactory),需要手动开启:在SQL映射文件中添加一行:

  • 缓存的清除策略:

    • LRU(Least Recently Uses):最近最少使用,移除最长时间不被使用的对象
    • FIFO(First In First Out):先进先出,按照对象进入缓存的顺序来移除他们。这也是数据结构中队列(Queue)的元素存取方式。
    • SOFT:软引用,基于来及回收器状态和软引用规则移除对象
    • WEAK:弱引用,更积极地基于垃圾收集器状态和弱引用规则来移除对象
  • 默认的清除策略是LRU

三、日志 log4j

  • Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:
    • SLF4J
    • Apache Commons Logging
    • Log4j 2
    • Log4j
    • JDK logging
  • MyBatis 内置日志工厂会基于运行时检测信息选择日志委托实现。它会(按上面罗列的顺序)使用第一个查找到的实现。当没有找到这些实现时,将会禁用日志功能。
  • 可以在mybatis配置文件中设置日志选项,可选的值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING,或者是实现了 org.apache.ibatis.logging.Log 接口,且构造方法以字符串为参数的类完全限定名。
  • 全局日志配置可以配置打印的日志级别,日志的输出对象。日志的四个级别:error、warn、info、debug,优先级从高到低;如果设置为error,只打印error信息,如果设置为debug,所有级别的信息都会打印;只会打印大于等于这个级别的日志。stdout是标准输出:打印在控制台。还可以将日志输出到文件,最后一行指定了最小输出宽度以及对齐方式。
  • MyBatis日志配置设置了跟踪的包、类或方法,对特定包下的类、特定类、特定方法才会打印日志。

四、测试动态SQL和日志log4j

  • 添加junit,mysql,mybatis 以及 log4j 的依赖到 pom.xml 中

    
    
        4.0.0
        com
        MyBatisSQL
        1.0-SNAPSHOT
        
            
                junit
                junit
                4.12
            
            
                mysql
                mysql-connector-java
                8.0.19
            
            
                org.mybatis
                mybatis
                3.4.6
            
            
                org.projectlombok
                lombok
                1.18.6
            
            
                log4j
                log4j
                1.2.17
            
        
    
    
  • Mybatis.xml

    
    
    
        
        
        
            
        
        
            
        
        
            
                
                
                    
                    
                    
                    
                
            
        
            
            
        
    
    
  • db.properties

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3307/mysqls?serverTimezone=UTC
    user=root
    pass=123456
    
  • log4j.properties

    log4j.rootLogger=debug, stdout, F
    # MyBatis 日志配置
    log4j.logger.com.qfedu=TRACE
    # 控制台输出
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%6p [%t] - %m%n
    log4j.appender.F = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.F.File =myproj.log
    log4j.appender.F.Append = true
    log4j.appender.F.Threshold = DEBUG
    log4j.appender.F.layout=org.apache.log4j.PatternLayout
    log4j.appender.F.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss}-[%p %F\:%L]  %m%n
    
  • User.java

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
        private int uid;
        private String username;
        private String password;
        private int age;
        private String addr;
    }
    
  • IUserDao.java

    public interface IUserDao {
        @Select("select * from user")
        List getAll();
    }
    
  • IUserDao.xml

    
    
    
        
            select * from user
        
        
        
        
        
    
    
  • SessionUtils.java

    public class SessionUtils {
        private static SqlSession mSession = null;
        private static SqlSessionFactory mFactory = null;
        static {
            try {
                mFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
            } catch (IOException e) {
                  e.printStackTrace();
            }
        }
        /**
         * 获取SqlSession对象
         * @return
         */
        public static SqlSession getSession(){
            mSession = mFactory.openSession(true);
            return mSession;
        }
        /**
         * 关闭SqlSession对象
         * @param session 要关闭的SqlSession对象
         */
        public static void closeSession(SqlSession session){
            if(session != null){
                session.close();
                session = null;
            }
        }
    }
    
  • TestLog.java

    public class TestLog {
        private SqlSession session = null;
        @Before
        public void setUp() {
            session = SessionUtils.getSession();
        }
        @After
        public void tearDown() {
            SessionUtils.closeSession(session);
        }
        @Test
        public void testLog(){
            IUserDao userDao = session.getMapper(IUserDao.class);
            List list = userDao.getAll();
            for (User u : list) {
                System.out.println(u);
            }
        }
    }
    
  • 测试结果

     DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
     DEBUG [main] - Class not found: org.jboss.vfs.VFS
     DEBUG [main] - JBoss 6 VFS API is not available in this environment.
     DEBUG [main] - Class not found: org.jboss.vfs.VirtualFile
     DEBUG [main] - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
     DEBUG [main] - Using VFS adapter org.apache.ibatis.io.DefaultVFS
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Reader entry: IUserDao.class
     DEBUG [main] - Reader entry: User.class
     DEBUG [main] - Listing file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Reader entry: ����   4 �� 
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Reader entry: ����   4 n   � Q     � R     � S     � T     � U� V
     DEBUG [main] - Checking to see if class com.pojo.IUserDao matches criteria [is assignable to Object]
     DEBUG [main] - Checking to see if class com.pojo.User matches criteria [is assignable to Object]
     DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Reader entry: IUserDao.class
     DEBUG [main] - Reader entry: User.class
     DEBUG [main] - Listing file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Reader entry: ����   4 �� 
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Reader entry: ����   4 n   � Q     � R     � S     � T     � U� V
     DEBUG [main] - Checking to see if class com.pojo.IUserDao matches criteria [is assignable to Object]
     DEBUG [main] - Checking to see if class com.pojo.User matches criteria [is assignable to Object]
     DEBUG [main] - Opening JDBC Connection
     DEBUG [main] - Created connection 2030538903.
     DEBUG [main] - ==>  Preparing: select * from user 
     DEBUG [main] - ==> Parameters: 
     DEBUG [main] - <==      Total: 13
      User(uid=1, username=aaa, password=111111, age=10, addr=aaaa)
      User(uid=2, username=bbb, password=222222, age=11, addr=aaaa)
      User(uid=3, username=ccc, password=333333, age=12, addr=aaaa)
      User(uid=4, username=ddd, password=444444, age=13, addr=aaaa)
      User(uid=5, username=eee, password=555555, age=14, addr=aaaa)
      User(uid=6, username=fff, password=666666, age=15, addr=aaaa)
      User(uid=7, username=ggg, password=777777, age=16, addr=aaaa)
      User(uid=8, username=hhh, password=888888, age=17, addr=aaaa)
      User(uid=9, username=iii, password=999999, age=18, addr=aaaa)
      User(uid=10, username=jjj, password=000000, age=19, addr=aaaa)
      User(uid=11, username=kkk, password=000000, age=20, addr=aaaa)
      User(uid=12, username=lkt, password=888888, age=20, addr=suzhou)
      User(uid=15, username=ABC, password=111111, age=20, addr=南京)
     DEBUG [main] - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@79079097]
     DEBUG [main] - Returned connection 2030538903 to pool.
    
  • TestUserSQL.java

    public class TestUserSQL {
        private SqlSession session = null;
        @Before
        public void setUp() { session = SessionUtils.getSession(); }
        @After
        public void tearDown() { SessionUtils.closeSession(session); }
        @Test
        public void testGetAllUsers() {
            List list = session.selectList("com.pojo.IUserDao.selectAll");
            for (User u : list) {
                System.out.println(u);
            }
        }
        @Test
        public void testGetAllUsersByUid() {
            User u = session.selectOne("com.pojo.IUserDao.selectUserByUid", 1);
            System.out.println(u);
        }
        @Test
        public void testGetUserByIf(){
            Map map = new HashMap<>();
            map.put("password", "333333");
            List list = session.selectList("com.pojo.IUserDao.selectIf", map);
            for (User u : list) {
              System.out.println(u);
            }
        }
        @Test
        public void testGetUsersByIn(){
            List ids = new ArrayList<>();
            Collections.addAll(ids, 1, 2, 3, 4, 100);
            System.out.println(ids);
            Map map = new HashMap<>();
            map.put("ids", ids);
            List list = session.selectList("com.pojo.IUserDao.selectIn", map);
            for (User u : list) {
                System.out.println(u);
            }
        }
    }
    
  • 测试结果

     DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
     DEBUG [main] - Class not found: org.jboss.vfs.VFS
     DEBUG [main] - JBoss 6 VFS API is not available in this environment.
     DEBUG [main] - Class not found: org.jboss.vfs.VirtualFile
     DEBUG [main] - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
     DEBUG [main] - Using VFS adapter org.apache.ibatis.io.DefaultVFS
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Reader entry: IUserDao.class
     DEBUG [main] - Reader entry: IUserDao.xml
     DEBUG [main] - Reader entry: User.class
     DEBUG [main] - Listing file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Reader entry: ����   4 �� 
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.xml
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.xml
     DEBUG [main] - Reader entry: 
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Reader entry: ����   4 n   � Q     � R     � S     � T     � U� V
     DEBUG [main] - Checking to see if class com.pojo.IUserDao matches criteria [is assignable to Object]
     DEBUG [main] - Checking to see if class com.pojo.User matches criteria [is assignable to Object]
     DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Reader entry: IUserDao.class
     DEBUG [main] - Reader entry: IUserDao.xml
     DEBUG [main] - Reader entry: User.class
     DEBUG [main] - Listing file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.class
     DEBUG [main] - Reader entry: ����   4 �� 
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.xml
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/IUserDao.xml
     DEBUG [main] - Reader entry: 
     DEBUG [main] - Find JAR URL: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Not a JAR: file:/F:/IDEA-Work/MyBatisSQLAndLog4J/target/classes/com/pojo/User.class
     DEBUG [main] - Reader entry: ����   4 n   � Q     � R     � S     � T     � U� V
     DEBUG [main] - Checking to see if class com.pojo.IUserDao matches criteria [is assignable to Object]
     DEBUG [main] - Checking to see if class com.pojo.User matches criteria [is assignable to Object]
     DEBUG [main] - Opening JDBC Connection
     DEBUG [main] - Created connection 515715487.
     DEBUG [main] - ==>  Preparing: select * from user 
     DEBUG [main] - ==> Parameters: 
     DEBUG [main] - <==      Total: 13
      User(uid=1, username=aaa, password=111111, age=10, addr=aaaa)
      User(uid=2, username=bbb, password=222222, age=11, addr=aaaa)
      User(uid=3, username=ccc, password=333333, age=12, addr=aaaa)
      User(uid=4, username=ddd, password=444444, age=13, addr=aaaa)
      User(uid=5, username=eee, password=555555, age=14, addr=aaaa)
      User(uid=6, username=fff, password=666666, age=15, addr=aaaa)
      User(uid=7, username=ggg, password=777777, age=16, addr=aaaa)
      User(uid=8, username=hhh, password=888888, age=17, addr=aaaa)
      User(uid=9, username=iii, password=999999, age=18, addr=aaaa)
      User(uid=10, username=jjj, password=000000, age=19, addr=aaaa)
      User(uid=11, username=kkk, password=000000, age=20, addr=aaaa)
      User(uid=12, username=lkt, password=888888, age=20, addr=suzhou)
      User(uid=15, username=ABC, password=111111, age=20, addr=南京)
     DEBUG [main] - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1ebd319f]
     DEBUG [main] - Returned connection 515715487 to pool.
     DEBUG [main] - Opening JDBC Connection
     DEBUG [main] - Checked out connection 515715487 from pool.
     DEBUG [main] - ==>  Preparing: select * from user where uid = ? 
     DEBUG [main] - ==> Parameters: 1(Integer)
     DEBUG [main] - <==      Total: 1
      User(uid=1, username=aaa, password=111111, age=10, addr=aaaa)
     DEBUG [main] - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1ebd319f]
     DEBUG [main] - Returned connection 515715487 to pool.
     DEBUG [main] - Opening JDBC Connection
     DEBUG [main] - Checked out connection 515715487 from pool.
     DEBUG [main] - ==>  Preparing: select * from user WHERE password = ? 
     DEBUG [main] - ==> Parameters: 333333(String)
     DEBUG [main] - <==      Total: 1
      User(uid=3, username=ccc, password=333333, age=12, addr=aaaa)
     DEBUG [main] - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1ebd319f]
     DEBUG [main] - Returned connection 515715487 to pool.
      [1, 2, 3, 4, 100]
     DEBUG [main] - Opening JDBC Connection
     DEBUG [main] - Checked out connection 515715487 from pool.
     DEBUG [main] - ==>  Preparing: select * from user WHERE uid in ( ? , ? , ? , ? , ? ) 
     DEBUG [main] - ==> Parameters: 1(Integer), 2(Integer), 3(Integer), 4(Integer), 100(Integer)
     DEBUG [main] - <==      Total: 4
      User(uid=1, username=aaa, password=111111, age=10, addr=aaaa)
      User(uid=2, username=bbb, password=222222, age=11, addr=aaaa)
      User(uid=3, username=ccc, password=333333, age=12, addr=aaaa)
      User(uid=4, username=ddd, password=444444, age=13, addr=aaaa)
     DEBUG [main] - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1ebd319f]
     DEBUG [main] - Returned connection 515715487 to pool.
    

五、Mybatis的SQL语句构造器

  • MyBatis 3 提供了方便的工具类来帮助解决该问题。使用SQL类,简单地创建一个实例来调用方法生成SQL语句。
  • SQL 语句生成器列表
方法 描述
SELECT(字串) SELECT(字符串...) 开始或插入到选择子句。可以被多次调用,参数也会添加到SELECT子句。参数通常使用逗号分隔的列名和别名列表,但也可以是数据库驱动程序接受的任意类型。
SELECT_DISTINCT(字符串) SELECT_DISTINCT(字符串...) 开始或插入到SELECT子句,也可以插入DISTINCT关键字到生成的查询语句中。可以被多次调用,参数也会添加到SELECT子句。参数通常使用逗号分隔的列名和别名列表,但也可以是数据库驱动程序接受的任意类型。
FROM(字符串) FROM(字符串...) 开始或插入到FROM子句。可以被多次调用,参数也会添加到FROM子句。参数通常是表名或别名,也可以是数据库驱动程序接受的任意类型。
JOIN(字符串) JOIN(字符串...) INNER_JOIN(字符串) INNER_JOIN(字符串...) LEFT_OUTER_JOIN(字符串) LEFT_OUTER_JOIN(字符串...) RIGHT_OUTER_JOIN(字符串) RIGHT_OUTER_JOIN(字符串...) 基于调用的方法,添加新的合适类型的JOIN子句。参数可以包含由列命和加入的条件组合成标准的加入。
WHERE(String) WHERE(String...) 插入新的 WHERE子句条件, 由AND链接。可以多次被调用,每次都由AND来链接新条件。使用 OR() 来分隔OR
OR() 使用OR来分隔当前的 WHERE子句条件。 可以被多次调用,但在一行中多次调用或生成不稳定的SQL
AND() 使用AND来分隔当前的 WHERE子句条件。 可以被多次调用,但在一行中多次调用或生成不稳定的SQL。因为 WHEREHAVING 二者都会自动链接 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子句元素, 由逗号连接。可以多次被调用,每次由逗号连接新的条件。
LIMIT(String) LIMIT(int) 附加一个LIMIT子句。与SELECT(),UPDATE()DELETE()一起使用时,此方法有效。并且此方法设计为在使用SELECT()时与OFFSET()一起使用。
OFFSET(String) OFFSET(long) 附加一个OFFSET子句。与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()一起使用。
DELETE_FROM(String) 开始一个delete语句并指定需要从哪个表删除的表名。通常它后面都会跟着WHERE语句
INSERT_INTO(String) 开始一个insert语句并指定需要插入数据的表名。后面都会跟着一个或者多个VALUES() or INTO_COLUMNS() and INTO_VALUES()
SET(String) SET(String...) 针对update语句,插入到"set"列表中
UPDATE(String) 开始一个update语句并指定需要更新的表明。后面都会跟着一个或者多个SET(),通常也会有一个WHERE()
VALUES(String, String) 插入到insert语句中。第一个参数是要插入的列名,第二个参数则是该列的值。
INTO_COLUMNS(String...) 插入语句的形式是:INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
INTO_VALUES(String...) 插入语句的形式是:INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
ADD_ROW() 为批量插入添加新行。

你可能感兴趣的:(MyBatis的动态SQL与日志Log4J、SQL语句构造器)