动态SQL
1、动态SQL中的元素
1)、作用:无需手动拼装SQL,MyBatis已提供的对SQL语句动态组装的功能,使得数据库开发效率大大提高!
2)、动态SQL是MyBatis的强大特性之一,MyBatis3采用了功能强大的基于OGNL的表达式来完成动态SQL。动态SQL主要元素如下表所示:
2、<if>元素
1)、在MyBatis中,<if>元素是最常用的判断语句,它类似于Java中的if语句,主要用于实现某些简单的条件选择。其基本使用示例如下:使用<if>元素对username和jobs进行非空判断,并动态组装SQL。
1 select * from t_customer where 1=1 2 <if test="username !=null and username !=''"> 3 and username like concat('%',#{username}, '%') 4 </if> 5 <if test="jobs !=null and jobs !=''"> 6 and jobs= #{jobs} 7 </if>
2)、本章项目文件结构
①配置文件:src->mybatis-config.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 4 5 <configuration> 6 <!-- 宏定义 --> 7 <properties resource="db.properties" /> 8 9 <!--1.配置环境 ,默认的环境id为mysql --> 10 <environments default="mysql"> 11 12 <!--1.2.配置id为mysql的数据库环境 --> 13 <environment id="mysql"> 14 15 <!-- 使用JDBC的事务管理 --> 16 <transactionManager type="JDBC" /> 17 18 <!--数据库连接池 --> 19 <dataSource type="POOLED"> 20 21 <!-- 数据库驱动 --> 22 <property name="driver" value="${jdbc.driver}" /> 23 24 <!-- 连接数据库的url --> 25 <property name="url" value="${jdbc.url}" /> 26 27 <!-- 连接数据库的用户名 --> 28 <property name="username" value="${jdbc.username}" /> 29 30 <!-- 连接数据库的密码 --> 31 <property name="password" value="${jdbc.password}" /> 32 33 </dataSource> 34 35 </environment> 36 37 </environments> 38 39 <!--2.配置Mapper的位置 --> 40 <mappers> 41 <mapper resource="com/itheima/mapper/CustomerMapper.xml" /> 42 </mappers> 43 </configuration>
②src->db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=******#密码自己设置
③由于MyBatis默认使用log4j输出日志信息,所以如果要查看控制台的输出SQL语句,那么就需要在classpath路径下配置其日志文件。在项目的src目录下创建log4j.properties文件。
# Global logging configuration,全局的日志配置,Mybatis的日志配置和控制台输出,其中Mybatis的日志配置用于将com.itheima包下所有类的日志记录级别设置为DEBUG
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.itheima=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
④修改映射文件:CustomerMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 5 <mapper namespace="com.itheima.mapper.CustomerMapper"> 6 <!-- <if>元素使用, 7 test属性多用于条件判断语句中,用于判断真假,大部分进行非空判断 8 若传入的查询条件非空就进行动态SQL组装,也就是条件成立时执行查询语句,注意用and连接查询语句 9 --> 10 <select id="findCustomerByNameAndJobsID" parameterType="com.itheima.po.Customer" 11 resultType="com.itheima.po.Customer"> 12 select * from t_customer where 1=1 13 <if test="username !=null and username !=''"> 14 and username like concat('%',#{username},'%') 15 </if> 16 17 <if test="jobs !=null and jobs !=''"> 18 and jobs= #{jobs} 19 </if> 20 </select> 21 </mapper>
⑤单元测试:
1 /** 2 * 根据客户姓名和职业组合条件查询客户信息列表 3 */ 4 @Test 5 public void findCustomerByNameAndJobsTest(){ 6 7 // 1、通过工具类生成SqlSession对象 8 SqlSession session = MybatisUtils.getSession(); 9 10 // 2、创建Customer对象,封装需要组合查询的条件 11 Customer customer = new Customer(); 12 customer.setUsername("jack"); 13 customer.setJobs("teacher"); 14 15 // 3、执行SqlSession的查询方法,返回结果集 16 List<Customer> customers = session.selectList("com.itheima.mapper.CustomerMapper.findCustomerByNameAndJobsID",customer); 17 18 // 4、输出查询结果信息 19 for (Customer customer2 : customers) { 20 // 打印输出结果 21 System.out.println(customer2); 22 } 23 24 // 5、关闭SqlSession 25 session.close(); 26 }
⑥运行结果:
⑦若注释掉封装对象中的jack和teacher的2行代码,则执行结果为查询整张表:
3、<choose>、<when>、<otherwise>元素
1)、这三个元素的组合相当于java语言中的switch...case...default语句,其XML文件一般为以下格式:使用<choose>及其子元素依次对条件进行非空判断,并动态组装SQL。
select * from t_customer where 1=1 <choose> <when test="username !=null and username !=''"> and username like concat('%',#{username}, '%') </when> <when test="jobs !=null and jobs !=''"> and jobs= #{jobs} </when> <otherwise> and phone is not null </otherwise> </choose>
①修改映射文件:CustomerMapper.xml
1 <!--<choose>(<when>、<otherwise>)元素使用 --> 2 <select id="findCustomerByNameOrJobsID" parameterType="com.itheima.po.Customer" 3 resultType="com.itheima.po.Customer"> 4 select * from t_customer where 1=1 5 <choose> 6 <!--<choose>元素相当于switch, <when>元素相当于case语句 7 语法和switch...case...default一样 8 --> 9 <when test="username !=null and username !=''"> 10 and username like concat('%',#{username}, '%') 11 </when> 12 13 <when test="jobs !=null and jobs !=''"> 14 and jobs= #{jobs} 15 </when> 16 17 <!-- <otherwise>元素相当于default关键字,若前面的条件都不成立,默认执行下面这一条件 --> 18 <otherwise> 19 and phone is not null 20 </otherwise> 21 22 </choose> 23 </select>
②单元测试:
1 /** 2 * 根据客户姓名或职业查询客户信息列表 3 */ 4 @Test 5 public void findCustomerByNameOrJobsTest(){ 6 7 // 1、通过工具类生成SqlSession对象 8 SqlSession session = MybatisUtils.getSession(); 9 10 // 2、创建Customer对象,封装需要组合查询的条件 11 Customer customer = new Customer(); 12 customer.setUsername("jack"); 13 customer.setJobs("teacher"); 14 15 // 3、执行SqlSession的查询方法,返回结果集 16 List<Customer> customers = session.selectList("com.itheima.mapper.CustomerMapper.findCustomerByNameOrJobsID",customer); 17 18 // 4、输出查询结果信息 19 for (Customer customer2 : customers) { 20 // 打印输出结果 21 System.out.println(customer2); 22 } 23 24 // 5、关闭SqlSession 25 session.close(); 26 }
③运行结果:(注意当前查询语句)
④若注释掉customer.setUsername("jack");则执行结果如下:(注意当前查询语句)
⑤若再注释掉customer.setJobs("teacher");则执行结果如下:(执行XML中<otherwise>元素块)