[一步是咫尺,一步即天涯]

前面我们花费很多篇幅来介绍核心元素<resultMap>的使用,在日常开发中,基本的静态的查询情况已经足够对付。但有些时候,我们想寻求一个能够根据参数自动调整SQL查询的方法。如,学校教导主任发现一个学生违反校纪校规,但是并没有当场抓住该学生,于是,他通过已经掌握的学生信息如【性别】,【年纪】,【身高】等信息来查询符合条件的学生。但是,这些信息的数量每次得到的数量都是不同的。换句话说,我们在设计系统时,无法确定传入参数的数量。也没有获得一个足以唯一确定这个对象的主键【如学号】。接下来我们就来演示,如何通过Mybatis的<if>元素来实现我们动态查询的需求。

准备工作:

44.jpg

a.操作系统 :win7 x64

b.基本软件:MySQL,Mybatis,Spring,SQLyog

-------------------------------------------------------------------------------------------------------------------------------------

为了方便各位看官学习,我们把本例所有的文件再复述一次,如果已经有前文工程的读者,可以只修改差异的部分即可。】

1.作为演示,我们就不再设计新的数据库,及模型。建议复制上文中使用的工程,创建为Mybatis06,工程修改之后的目录结构如下:


2.pom文件的内容如下:

[plain] view plain copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  

  3.     <modelVersion>4.0.0</modelVersion>  

  4.   

  5.     <groupId>com.java.mybatis</groupId>  

  6.     <artifactId>mybatis01</artifactId>  

  7.     <version>0.0.1-SNAPSHOT</version>  

  8.     <packaging>jar</packaging>  

  9.   

  10.     <name>mybatis01</name>  

  11.     <url>http://maven.apache.org</url>  

  12.   

  13.     <properties>  

  14.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  

  15.     </properties>  

  16.   

  17.     <dependencies>  

  18.         <dependency>  

  19.             <groupId>junit</groupId>  

  20.             <artifactId>junit</artifactId>  

  21.             <version>4.12</version>  

  22.             <scope>test</scope>  

  23.         </dependency>  

  24.         <dependency>  

  25.             <groupId>org.mybatis</groupId>  

  26.             <artifactId>mybatis</artifactId>  

  27.             <version>3.3.1</version>  

  28.         </dependency>  

  29.         <dependency>  

  30.             <groupId>mysql</groupId>  

  31.             <artifactId>mysql-connector-java</artifactId>  

  32.             <version>5.1.26</version>  

  33.         </dependency>  

  34.         <dependency>  

  35.             <groupId>log4j</groupId>  

  36.             <artifactId>log4j</artifactId>  

  37.             <version>1.2.17</version>  

  38.         </dependency>  

  39.     </dependencies>  

  40. </project>  

3.UserInfo.java文件的内容如下:


[java] view plain copy
  1. package com.csdn.ingo.entity;  

  2.   

  3. import java.io.Serializable;  

  4.   

  5. /** 

  6. *@author 作者 E-mail:ingo 

  7. *@version 创建时间:2016年4月20日下午7:19:18 

  8. *类说明 

  9. */  

  10. @SuppressWarnings("serial")  

  11. public class UserInfo implements Serializable {  

  12.       

  13.     private String userid;  

  14.     private String department;  

  15.     private String position;  

  16.     private String mobile;  

  17.     private String gender;  

  18.     private String email;  

  19.       

  20.     //set,get,构造函数,toString。就麻烦各位看官自己生成吧  

  21. }  

4.UserInfoDao.java文件的内容如下:


[java] view plain copy
  1. package com.csdn.ingo.dao;  

  2.   

  3. import java.util.List;  

  4. import java.util.Map;  

  5.   

  6. import com.csdn.ingo.entity.UserInfo;  

  7.   

  8. /** 

  9. *@author 作者 E-mail:ingo 

  10. *@version 创建时间:2016年4月20日下午8:13:13 

  11. *类说明 

  12. */  

  13. public interface UserInfoDao {  

  14.     List<UserInfo> findUserInfoByParams(Map<String,Object> map);  

  15. }  

5.SqlSessionFactoryUtil.java文件的内容如下:


[java] view plain copy
  1. package com.csdn.ingo.util;  

  2.   

  3. import java.io.InputStream;  

  4.   

  5. import org.apache.ibatis.io.Resources;  

  6. import org.apache.ibatis.session.SqlSession;  

  7. import org.apache.ibatis.session.SqlSessionFactory;  

  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;  

  9.   

  10. public class SqlSessionFactoryUtil {  

  11.   

  12.     private static SqlSessionFactory sqlSessionFactory;  

  13.       

  14.     public static SqlSessionFactory getSqlSessionFactory(){  

  15.         if(sqlSessionFactory==null){  

  16.             InputStream inputStream=null;  

  17.             try{  

  18.                 inputStream=Resources.getResourceAsStream("mybatis-config.xml");  

  19.                 sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);  

  20.             }catch(Exception e){  

  21.                 e.printStackTrace();  

  22.             }  

  23.         }  

  24.         return sqlSessionFactory;  

  25.     }  

  26.       

  27.     public static SqlSession openSession(){  

  28.         return getSqlSessionFactory().openSession();  

  29.     }  

  30. }  

6.UserInfoMapper.xml文件内容如下:


[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE mapper  

  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  

  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

  5. <mapper namespace="com.csdn.ingo.dao.UserInfoDao">  

  6.     <resultMap type="userInfo" id="UserInfoResult">  

  7.         <id property="userid" column="userid" />  

  8.         <result property="department" column="department" />  

  9.         <result property="position" column="position" />  

  10.         <result property="mobile" column="mobile" />  

  11.         <result property="gender" column="gender" />  

  12.         <result property="email" column="email" />  

  13.     </resultMap>  

  14.     <select id="findUserInfoByParams" parameterType="Map" resultMap="UserInfoResult">  

  15.         select * from userinfo   

  16.         where department=#{department}  

  17.         <if test="gender!=null">  

  18.             and gender = #{gender}  

  19.         </if>  

  20.         <if test="position!=null">  

  21.             and position like #{position}  

  22.         </if>  

  23.     </select>    

  24. </mapper>   

【注意】


这里的where之后至少有一个department条件。而gender,position条件会动态的判断。这里的处理逻辑就是:

1.假设,没有传入动态参数,那么只会按照department条件查询

2.如果,传入了动态的参数,则就在department条件上,在加入动态参数查询。

具体的查询结果,请继续跟着我们完善工程中的其他文件后,运行单元测试来观察实际结果吧。

7.jdbc.properties文件内容如下:

[plain] view plain copy
  1. jdbc.driverClassName=com.mysql.jdbc.Driver  

  2. jdbc.url=jdbc:mysql://localhost:3306/mybatis  

  3. jdbc.username=root  

  4. jdbc.password=1234  

8.log4j.properties文件内容如下:


[plain] view plain copy
  1. log4j.rootLogger=debug,stdout  

  2. log4j.appender.stdout=org.apache.log4j.ConsoleAppender  

  3. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  

  4. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n  

9.mybatis-config.xml文件内容如下:


[plain] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE configuration  

  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  

  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">  

  5. <configuration>  

  6.     <properties resource="jdbc.properties"/>  

  7.     <settings>  

  8.         <setting name="logImpl" value="LOG4J"/>  

  9.     </settings>  

  10.     <typeAliases>  

  11.         <package name="com.csdn.ingo.entity"/>  

  12.     </typeAliases>  

  13.     <environments default="development">  

  14.         <environment id="development">  

  15.             <transactionManager type="JDBC" />  

  16.             <dataSource type="POOLED">  

  17.                 <property name="driver" value="${jdbc.driverClassName}" />  

  18.                 <property name="url" value="${jdbc.url}" />  

  19.                 <property name="username" value="${jdbc.username}" />  

  20.                 <property name="password" value="${jdbc.password}" />  

  21.             </dataSource>  

  22.         </environment>  

  23.     </environments>  

  24.     <mappers>  

  25.         <mapper resource="mappers/UserInfoMapper.xml" />  

  26.     </mappers>  

  27. </configuration>  

10.单元测试方法如下:


[java] view plain copy
  1. public class UserTest {  

  2.     private static Logger log = Logger.getLogger(UserTest.class);  

  3.       

  4.     private SqlSession sqlSession = null;  

  5.       

  6.     @Before  

  7.     public void setUp() throws Exception {  

  8.         log.info("方法执行前调用");  

  9.         sqlSession = SqlSessionFactoryUtil.openSession();  

  10.     }  

  11.   

  12.     @After  

  13.     public void tearDown() throws Exception {  

  14.         log.info("方法执行后调用");  

  15.         sqlSession.close();  

  16.     }  

  17.   

  18.     @Test  

  19.     public void testSelet() {  

  20.         Map<String,Object> map=new HashMap<String,Object>();  

  21.         map.put("department""2");  

  22.         map.put("gender""1");  

  23.         map.put("position""%售%");  

  24.         UserInfoDao userInfo = sqlSession.getMapper(UserInfoDao.class);  

  25.         List<UserInfo> UIList= userInfo.findUserInfoByParams(map);  

  26.         for(UserInfo ui:UIList){  

  27.             System.out.println(ui.toString());  

  28.         }  

  29.     }  

  30. }  

11.运行测试方法,我们给出一个示例输出,更多参数内容还请读者自行设计:



=============================================================================

至此,<if>元素的基本用法结束,下面我们来看看更加灵活的用法!

=============================================================================



回顾一下,如果读者有看过前面两篇例子的话,一定还记的<association>这个标签,并且应该还记得我们如何通过<association>实现集合查询。

1.首先,我们先来现实看看如何根据集合属性中的值来查询条目。举个例子,我们想查询某个部门中的,爱好有篮球的人。这里的爱好是一个集合属性。当然,这里我们只是说明问题,并不再创建这张表出来,各位读者不要太在意这个细节,举一反三的能力还是要有的。

2.我们先修改UserInfo.java对象,具体内容如下:

[java] view plain copy
  1. @SuppressWarnings("serial")  

  2. public class UserInfo implements Serializable {  

  3.       

  4.     private String userid;  

  5.     private String department;  

  6.     private String position;  

  7.     private String mobile;  

  8.     private String gender;  

  9.     private String email;  

  10.     private Departments depart;  

  11.   

  12. //set,get,构造函数,toString自行实现  

  13. }  

2.修改UserInfoMapper.xml,具体内容如下:


[html] view plain copy
  1. <select id="findUserInfoByParams" parameterType="Map" resultMap="UserInfoResult">  

  2.         select * from userinfo   

  3.         where gender = #{gender}  

  4.         <if test="position!=null">  

  5.             and position like #{position}  

  6.         </if>  

  7.         <if test="d != null and d.id != null">  

  8.             AND department = #{d.id}  

  9.         </if>  

  10.     </select>    

3.对应的,单元测试的方法,我们也需要更改,如下:


[plain] view plain copy
  1. @Test  

  2.     public void testSelet() {  

  3.         Map<String,Object> map=new HashMap<String,Object>();  

  4.         map.put("gender", "1");  

  5.         map.put("position", "%售%");  

  6.         Departments d = new Departments("1","%售%");  

  7.         UserInfoDao userInfo = sqlSession.getMapper(UserInfoDao.class);  

  8.         List<UserInfo> UIList= userInfo.findUserInfoByParams(map);  

  9.         for(UserInfo ui:UIList){  

  10.             System.out.println(ui.toString());  

  11.         }  

  12.     }  

4.运行单元测试方法,应该能够看到如下输出

这里完整的输出如下:


[plain] view plain copy
  1. UserInfo [userid=customer, department=2, position=售前, mobile=33334444, gender=1, email=customer@email.com, depart=null]  

  2. UserInfo [userid=customer2, department=2, position=售后, mobile=55556666, gender=1, email=customer@email.com, depart=null]  

细心的读者已经发现,我们上面的depart输出为null,如果我们想要在结果集合中再加入部门表的信息。这里就请读者一定先阅读上文的实例代码,并且完整的运行一遍。


接下来,我们就来叙述具体的操作步骤:

1.首先,请读者先创建,或者复制上文的Departments.java,具体内容如下:

[java] view plain copy
  1. @SuppressWarnings("serial")  

  2. public class Departments implements Serializable{  

  3.       

  4.     private String id;  

  5.     private String departmentName;  

  6.   

  7. //set,get,构造函数,toString请读者自行完成  

  8. }  

2.创建,或者创建上文的DepartmentsDao.java,具体内容如下:


[java] view plain copy
  1. public interface DepartmentsDao {  

  2.     Departments findDepartmentById(String id);  

  3. }  

3.复制,或者创建上文的DepartmentsDaoMapper.xml,具体内容如下:【注意,这里要将路径增加到mybatis-config.xml中的mapper配置中,前文我们有叙述过如果使用包名配置,请读者查阅《Mybatis最入门---配置详解(上)》,这里,博主不太喜欢xml与itf混合放置的方式,所以没有使用包路径配置的方式。但是,后续我们将Spring与Mybatis结合时,将会借用Spring的配置,使得xml与接口分离的方式。敬请期待!】


[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  

  2. <!DOCTYPE mapper  

  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  

  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

  5. <mapper namespace="com.csdn.ingo.dao.DepartmentsDao">  

  6.     <resultMap type="Departments" id="DepartmentsResult">  

  7.         <id property="id" column="id" />  

  8.         <result property="departmentName" column="departmentName" />  

  9.     </resultMap>  

  10.     <select id="findDepartmentById" parameterType="String" resultMap="DepartmentsResult">  

  11.         select * from departments where id=#{id}  

  12.     </select>  

  13. </mapper>   

4.修改UserInfoMapper.xml,具体内容如下:


[plain] view plain copy
  1. <resultMap type="userInfo" id="UserInfoResult">  

  2.         <id property="userid" column="userid" />  

  3.         <result property="department" column="department" />  

  4.         <result property="position" column="position" />  

  5.         <result property="mobile" column="mobile" />  

  6.         <result property="gender" column="gender" />  

  7.         <result property="email" column="email" />  

  8.         <association property="depart" column="department"  

  9.             select="com.csdn.ingo.dao.DepartmentsDao.findDepartmentById"></association>  

  10.     </resultMap>  

5.重新单元测试方法,应该可以看到如下内容:


[plain] view plain copy
  1. UserInfo [userid=customer, department=2, position=售前, mobile=33334444, gender=1, email=customer@email.com, depart=Departments [id=2, departmentName=销售部]]  

  2. UserInfo [userid=customer2, department=2, position=售后, mobile=55556666, gender=1, email=customer@email.com, depart=Departments [id=2, departmentName=销售部]]  


-------------------------------------------------------------------------------------------------------------------------------------
至此,Mybatis最入门---动态查询(if)结束



特别备注:

本文演示的if用法按照官方文档中的内容,where之后,至少有一个给出的元素。假如,没有给出department的值,就算两外两个元素中有正确的值,Mybatis也不能够帮我们从数据库中查找出对应的条目,当然,返回数目为零,也不是以错误的形式。



转载的时候记得写明出处哦!红色火线java加油站!http://hongsehuoxian.com
看到这里如果这篇文章真的帮到你了,不妨打赏一下哦!

以上就是红色火线JAVA加油站整理的关于Mybatis最入门---动态查询(if)的文章,
希望可以帮到你,如果你有不同的见解可以留言指正哦,避免让别的java小伙伴在走挫折路。
ajax页面之间传值
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

分享:

支付宝

微信