Mybatis框架学习笔记(未完结)
复习三层架构
Mybatis框架概述
是一个持久层(dao层框架),用java语句编写。封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无须关注注册驱动,创建连接等繁杂过程。它使用了ORM思想实现了结果集的封装。
ORM:object relational mapping对象关系映射。简单地说,就是把数据库表格和java类地属性对应起来,让我们可以操作类就实现操作数据库表格。类的属性名要和数据库表格的字段名称保持一致。
Mybatis入门
1.在mysql中准备好相应的表格
2.创建maven工程,补全main目录下的java,resource目录。
3.配置pom.xml文件,导入需要使用的依赖。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>org.example</groupId> 8 <artifactId>mabatis01</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 <packaging>jar</packaging> 11 12 <dependencies> 13 <dependency> 14 <groupId>org.mybatis</groupId> 15 <artifactId>mybatis</artifactId> 16 <version>3.5.4</version> 17 </dependency> 18 <dependency> 19 <groupId>mysql</groupId> 20 <artifactId>mysql-connector-java</artifactId> 21 <version>5.1.48</version> 22 </dependency> 23 <dependency> 24 <groupId>log4j</groupId> 25 <artifactId>log4j</artifactId> 26 <version>1.2.12</version> 27 </dependency> 28 <dependency> 29 <groupId>junit</groupId> 30 <artifactId>junit</artifactId> 31 <version>4.12</version> 32 <scope>test</scope> 33 </dependency> 34 </dependencies> 35 </project>
4.在main/java目录下创建一个domain包,写一个user类(与mysql表格对应),写好对应的私有属性,并生成getters&setters与toString方法。
1 package domain; 2 3 import java.io.Serializable; 4 import java.util.Date; 5 6 public class user implements Serializable { 7 private Integer id; 8 private String username; 9 private Date birthday; 10 private String sex; 11 private String address; 12 13 public Integer getId() { 14 return id; 15 } 16 17 public void setId(Integer id) { 18 this.id = id; 19 } 20 21 public String getUsername() { 22 return username; 23 } 24 25 public void setUsername(String username) { 26 this.username = username; 27 } 28 29 public Date getBirthday() { 30 return birthday; 31 } 32 33 public void setBirthday(Date birthday) { 34 this.birthday = birthday; 35 } 36 37 public String getSex() { 38 return sex; 39 } 40 41 public void setSex(String sex) { 42 this.sex = sex; 43 } 44 45 public String getAddress() { 46 return address; 47 } 48 49 public void setAddress(String address) { 50 this.address = address; 51 } 52 53 @Override 54 public String toString() { 55 return "user{" + 56 "id=" + id + 57 ", username='" + username + '\'' + 58 ", birthday=" + birthday + 59 ", sex='" + sex + '\'' + 60 ", address='" + address + '\'' + 61 '}'; 62 } 63 }
5.在main/java目录下创建一个dao包,写一个IUserDao接口,其中定义一个findAll方法。(其他地方可能取名为Mapper)
1 package dao; 2 3 import domain.user; 4 5 import java.util.List; 6 7 public interface IUserDao { 8 List <user> findAll(); 9 }
6.主配置文件:在main/resources目录下创建一个sqlMapconfig.xml文件,配置如下:
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 <!--mybatis主配置文件--> 6 <configuration> 7 <!--配置环境--> 8 <environments default="mysql"> 9 <!--配置mysql环境--> 10 <environment id="mysql"> 11 <!--配置事务的类型--> 12 <transactionManager type="JDBC"></transactionManager> 13 <!--配置数据源--> 14 <dataSource type="POOLED"> 15 <!--配置连接数据库的4个信息--> 16 <property name="driver" value="com.mysql.jdbc.Driver"/> 17 <property name="url" value="jdbc:mysql://localhost/mybatis"/> 18 <property name="username" value="root"/> 19 <property name="password" value="0322"/> 20 </dataSource> 21 </environment> 22 </environments> 23 <mappers> 24 <mapper resource="dao/IUserDao.xml"/> 25 </mappers> 26 </configuration>
7.映射配置文件:在main/resources目录下创建一个dao包(与第5步中的dao包一致),再在其中创建一个IUserDao.xml(也可取名为Mapper),注意指定resultType,配置如下:
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="dao.IUserDao"> 6 <!--配置查询所有--> 7 <select id = "findAll" resultType="domain.user"> 8 select * from user 9 </select> 10 </mapper>
8.在main/resources目录下创建一个log4j.properties文件,配置如下:
1 log4j.rootCategory = debug,CONSOLE,LOGFILE 2 3 log4j.logger.org.apache.axis.enterprise=FATAL,CONSOLE 4 5 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 6 log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 7 log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n 8 9 log4j.appender.LOGFILE=org.apache.log4j.FileAppender 10 log4j.appender.LOGFILE.File=\axis.log 11 log4j.appender.LOGFILE.Append=true 12 log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout 13 log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
9.在test/java下创建一个test包,创建一个MybatisTest类,其中代码如下:
1 package test; 2 3 import dao.IUserDao; 4 import domain.user; 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 import java.io.IOException; 10 import java.io.InputStream; 11 import java.util.List; 12 13 public class MybatisTest { 14 public static void main(String[] args) throws IOException { 15 //读取配置文件 16 InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml"); 17 //创建SqlSessionFactory工厂 18 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 19 SqlSessionFactory factory = builder.build(in); 20 //使用工厂生产SqlSession对象 21 SqlSession session = factory.openSession(); 22 //使用SqlSession创建Dao接口的代理对象 23 IUserDao userDao = session.getMapper(IUserDao.class); 24 //使用代理对象执行方法 25 List<user> users = userDao.findAll(); 26 for(user user:users){ 27 System.out.println(user); 28 } 29 //释放资源 30 session.close(); 31 in.close(); 32 } 33 }
10.运行main函数,我们就可以看到mysql中的user表格信息被读取到了控制台中。
这次入门调试太艰辛了!!记录一下需要注意的地方:
1.版本不支持:百度上解决方法很多,按照上面的步骤统一版本即可。我漏了把project structure里的module中的language level勾选成13版本,一直调试不出来。
2.log4j的相关配置出错,首先我修改了log4j配置文件里敲错的部分和IUserDao配置文件里面敲错的部分,然后发现IUserDao配置文件不是xml格式,就重新创建了一下。最后还发现包名domain竟然拼错了。其实出错就按照报错的提示修改就可以。放一个调试成功project的目录:
也可以使用注解:
1.删除映射配置文件IUserDao.xml,包括它所在的main/resources目录下的dao包,一并删除。
2.修改main/java目录下dao中的IUserDao接口,在findAll方法上面一行添加注解@select("select * from user")
3.修改main/resources目录下的主配置文件sqlMapconfig.xml,将mappers中的resource改为class属性,具体如下:
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 <!--mybatis主配置文件--> 6 <configuration> 7 <!--配置环境--> 8 <environments default="mysql"> 9 <!--配置mysql环境--> 10 <environment id="mysql"> 11 <!--配置事务的类型--> 12 <transactionManager type="JDBC"></transactionManager> 13 <!--配置数据源--> 14 <dataSource type="POOLED"> 15 <!--配置连接数据库的4个信息--> 16 <property name="driver" value="com.mysql.jdbc.Driver"/> 17 <property name="url" value="jdbc:mysql://localhost/mybatis"/> 18 <property name="username" value="root"/> 19 <property name="password" value="0322"/> 20 </dataSource> 21 </environment> 22 </environments> 23 <mappers> 24 <mapper class="dao.IUserDao"/> 25 </mappers> 26 </configuration>
设计模式分析
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");把对要造房子的要求写在纸上
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();请来了一支包工队
SqlSessionFactory factory = builder.build(in);把这张写了要求的纸交给包工队,包工队创建一个工厂。创建者模式:隐藏创建细节,直接调用方法得到对象
SqlSession session = factory.openSession();这个工厂开启造房子工程。工厂模式:解耦,降低类之间的依赖关系
IUserDao userDao = session.getMapper(IUserDao.class);在开启工程的基础上,根据传统造房子的方法(接口)创建一个具体的方案(接口的代理对象)代理模式:不修改源码的基础上对已有方法增强
List <user> users = userDao.findAll();正式开始造房
执行sql语句的相关分析
主配置文件包括:连接数据库的信息,指向映射配置文件的信息
映射配置文件包括(本质上存的是键值对map类型数据):
key——>dao接口(或者其实现类),以及其中定义的方法方法findAll()。
value——>存放数据的实体类的全限定类名,执行的sql语句(value的两部分合起来封装成一个对象)
(使用注解,本质上也是包含这些信息!!!)
解析这些配置文件的技术叫做:dom4j技术。
解析完成后的操作(我们称selectList方法)与jdbc基本过程类似,需要注意的是,遍历获得的ResultSet结果集时,需要用到反射的知识:
1.通过反射,将实体类封装为class对象(类名从映射配置文件中获取),一个对象相当于一条的数据
2.由于表格列名与实体类中的属性名一致,因此我们通过反射,将每个私有属性封装成对象,并为其赋值。
自定义Mybatis
核心步骤:
1.创建代理对象
2.代理对象调用selectList方法(连接数据库,执行操作)
具体过程:(过于繁琐,没写代码,了解了下过程)
1.读取配置文件Resources
2.读取后的信息交给SqlSessionFactoryBuilder类
3.写工具类XMLConfigBuilder类,其中会用到:一个configuration类存放连接数据库的4个信息,一个mapper类存放sql语句和全限定实体类名
4.SqlSessionFactoryBuilder类使用工具类XMLConfigBuilder类构建工厂对象SqlSessionFactory
5.创建SqlSession接口与它的实现类DefaultSqlSession,定义一个configuration属性。
6.创建工厂对象SqlSessionFactory的接口,与其实现类DefaultSqlSessionFactory类,其中中定义一个openSession方法,其中返回一个DefaultSqlSession对象,传入configuration参数。
7.在DefaultSqlSession类中负责创建代理对象(即dao实现类)MapperProxy
8.MapperProxy中实现增强,即调用工具类executer
9.工具类executer负责执行sql语句,封装结果集
Mybatis-CRUD
1.添加并保存一条数据
在入门版本的工程基础上,进行如下修改:
main/java/dao中的IUserDao接口文件增加一个saveUser(user u)方法:
1 package dao; 2 import domain.user; 3 import java.util.List; 4 public interface IUserDao { 5 List <user> findAll(); 6 void saveUser(user u); 7 }
main/resources/dao中的IUserDao.xml配置文件增加一个insert标签并指定参数类型为user类的全类名:
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="dao.IUserDao"> 6 <!--配置查询所有--> 7 <select id = "findAll" resultType="domain.user"> 8 select * from user 9 </select> 10 <insert id = "saveUser" parameterType="domain.user"> 11 insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday}); 12 </insert> 13 </mapper>
test/java/test中的MyBatisTest文件中添加testSave()方法,添加@Test,并将初始化代码与释放资源代码独立封装,添加@Before,@After。
特别注意:执行方法后要进行提交事务的操作。
1 package test; 2 3 import dao.IUserDao; 4 import domain.user; 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 import org.junit.After; 10 import org.junit.Before; 11 import org.junit.Test; 12 13 import java.io.IOException; 14 import java.io.InputStream; 15 import java.util.Date; 16 import java.util.List; 17 18 public class MybatisTest { 19 private InputStream in; 20 private SqlSession session; 21 private IUserDao userDao; 22 @Before 23 public void init()throws IOException{ 24 //读取配置文件 25 in = Resources.getResourceAsStream("SqlMapConfig.xml"); 26 //创建SqlSessionFactory工厂 27 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 28 SqlSessionFactory factory = builder.build(in); 29 //使用工厂生产SqlSession对象 30 session = factory.openSession(); 31 //使用SqlSession创建Dao接口的代理对象 32 userDao = session.getMapper(IUserDao.class); 33 34 } 35 @After 36 public void destroy() throws IOException { 37 session.close(); 38 in.close(); 39 40 } 41 @Test 42 public void testFindAll(){ 43 //使用代理对象执行方法 44 List<user> users = userDao.findAll(); 45 for(user user:users){ 46 System.out.println(user); 47 } 48 } 49 @Test 50 public void testSave(){ 51 user u = new user(); 52 u.setUsername("小明"); 53 u.setAddress("北京顺义"); 54 u.setSex("男"); 55 u.setBirthday(new Date()); 56 //执行保存方法 57 userDao.saveUser(u); 58 session.commit(); 59 } 60 61 }
2.修改/删除/查询/模糊查询
与保存数据类似,具体如下:
IUserDao接口文件:
1 package dao; 2 import domain.user; 3 import java.util.List; 4 public interface IUserDao { 5 List <user> findAll(); 6 void saveUser(user u); 7 void updateUser(user u); 8 void deleteUser(Integer userId); 9 user findById(Integer userId); 10 List<user> findByName(String username); 11 int findTotal(); 12 }
IUserDao.xml配置文件:
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="dao.IUserDao"> 6 <!--配置查询所有--> 7 <select id = "findAll" resultType="domain.user"> 8 select * from user 9 </select> 10 <insert id = "saveUser" parameterType="domain.user"> 11 insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday}); 12 </insert> 13 <update id = "updateUser" parameterType="domain.user"> 14 update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}; 15 </update> 16 <delete id = "deleteUser" parameterType="Integer"> 17 delete from user where id=#{uid}; 18 </delete> 19 <select id = "findById" parameterType="Integer" resultType="domain.user"> 20 select * from user where id=#{uid}; 21 </select> 22 <select id = "findByName" parameterType="String" resultType="domain.user"> 23 select * from user where username like #{name}; 24 </select> 25 <select id = "findTotal" resultType="int"> 26 select count(id) from user; 27 </select> 28 </mapper>
MyBatisTest文件:
1 package test; 2 3 import dao.IUserDao; 4 import domain.user; 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 import org.junit.After; 10 import org.junit.Before; 11 import org.junit.Test; 12 13 import java.io.IOException; 14 import java.io.InputStream; 15 import java.util.Date; 16 import java.util.List; 17 18 public class MybatisTest { 19 private InputStream in; 20 private SqlSession session; 21 private IUserDao userDao; 22 @Before 23 public void init()throws IOException{ 24 //读取配置文件 25 in = Resources.getResourceAsStream("SqlMapConfig.xml"); 26 //创建SqlSessionFactory工厂 27 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 28 SqlSessionFactory factory = builder.build(in); 29 //使用工厂生产SqlSession对象 30 session = factory.openSession(); 31 //使用SqlSession创建Dao接口的代理对象 32 userDao = session.getMapper(IUserDao.class); 33 34 } 35 @After 36 public void destroy() throws IOException { 37 session.commit(); 38 session.close(); 39 in.close(); 40 41 } 42 @Test 43 public void testFindAll(){ 44 //使用代理对象执行方法 45 List<user> users = userDao.findAll(); 46 for(user user:users){ 47 System.out.println(user); 48 } 49 } 50 @Test 51 public void testSave(){ 52 user u = new user(); 53 u.setUsername("小明"); 54 u.setAddress("北京顺义"); 55 u.setSex("男"); 56 u.setBirthday(new Date()); 57 //执行保存方法 58 userDao.saveUser(u); 59 60 } 61 62 @Test 63 public void testUpdate(){ 64 user u = new user(); 65 u.setId(49); 66 u.setUsername("Lisa"); 67 u.setAddress("北京顺义"); 68 u.setSex("女"); 69 u.setBirthday(new Date()); 70 //执行保存方法 71 userDao.updateUser(u); 72 } 73 74 @Test 75 public void testDelete(){ 76 userDao.deleteUser(48); 77 } 78 79 @Test 80 public void testFindOne(){ 81 user u = userDao.findById(49); 82 System.out.println(u); 83 } 84 85 @Test 86 public void testFindByName(){ 87 List <user> us = userDao.findByName("%王%"); 88 for(user u:us) { 89 System.out.println(u); 90 } 91 } 92 93 @Test 94 public void testFindTotal(){ 95 int count = userDao.findTotal(); 96 System.out.println(count); 97 } 98 99 }
3.拓展:保存插入的数据后,获取插入数据的id
修改IUserDao.xml配置文件中的insert标签,在其中添加selectKey标签,并添加语句:select last_insert_id(),并进行相关参数设置,具体代码如下:
1 <insert id = "saveUser" parameterType="domain.user"> 2 <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER"> 3 select last_insert_id(); 4 </selectKey> 5 insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday}); 6 </insert>
修改MyBatisTest文件中的testSave()方法:
1 @Test 2 public void testSave(){ 3 user u = new user(); 4 u.setUsername("Lily"); 5 u.setAddress("北京顺义"); 6 u.setSex("女"); 7 u.setBirthday(new Date()); 8 //执行保存方法 9 System.out.println("保存前"+u); 10 userDao.saveUser(u); 11 System.out.println("保存后"+u); 12 13 }
运行结果为:
保存前user{id=null, username='Lily', birthday=Tue Apr 28 13:50:23 CST 2020, sex='女', address='北京顺义'}
保存后user{id=50, username='Lily', birthday=Tue Apr 28 13:50:23 CST 2020, sex='女', address='北京顺义'}
可以看到运行修改后的saveUser()方法后,返回了该插入数据的id
Mybatis参数详解
ParameterType可以传递:
1.简单类型,int,String等
2.pojo对象(即javabean)
使用ognl表达式解析对象字段的值。如:#{pojo属性名称}
OGNL表达式:object graphic navigation language,对象图导航语言。通过对象的取值方法来获取数据,在写法上把get省略了。如:user.username。
3.pojo包装对象
1.main/java/domain中创建一个QueryVo类,定义一个user类的私有属性,并生成getters&setters:
1 package domain; 2 3 public class QueryVo { 4 private user u; 5 6 public user getU() { 7 return u; 8 } 9 10 public void setU(user u) { 11 this.u = u; 12 } 13 }
2.修改IUserDao.xml配置文件,parameterType设置为domain.QueryVo:
1 <select id = "findUserByVo" parameterType="domain.QueryVo" resultType="domain.user"> 2 select * from user where username like #{u.username}; 3 </select>
3.IUserDao接口文件中添加方法:List <user> findUserByVo(QueryVo vo);
4.MyBatisTest文件中添加:
1 //测试使用QueryVo作为查询条件 2 @Test 3 public void testFindByVo(){ 4 QueryVo vo = new QueryVo(); 5 user u = new user(); 6 u.setUsername("%王%"); 7 vo.setU(u); 8 List <user> us = userDao.findUserByVo(vo); 9 for(user x:us) { 10 System.out.println(x); 11 } 12 }
Mybatis连接池
连接池就是用于存储连接的一个容器
容器其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到同一个连接。该集合还必须实现队列的特性:先进先出。
例如:连接池中存放了8个连接,编号0-7。线程1取走了连接0,于是剩下的连接重新编号0-6。线程2取走了当前的连接0(一开始的连接1),剩下的连接重新编号0-5。线程1使用完毕后,归还了连接,此时一开始的连接0放在队列最后,成为连接6,线程2归还连接后则该连接成为连接7。
Mybatis关于连接池的配置在main/resources目录下的主配置文件sqlMapconfig.xml中:
<dataSource type> = "POOLED">
type属性的取值有3种:
1.POOLED(我们用这种):采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。 PooledDataSource
连接池分为空闲池与活动池,若空闲池中没有连接,会从活动池中取最先开始活动的连接。
2.UNPOOLED:采用传统的获取连接的方式,不使用连接池。UnPooledDataSource
3.JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同服务器不同。不是web或maven的war工程,不能使用。
Mybatis中的事务
通过SqlSession中的commit()方法和rollback()方法来实现。
在之前的代码中,SqlSession session = factory.openSession()语句默认参数值为false,意为不自动提交事务,需要手动提交事务。
设置SqlSession session = factory.openSession(true)后,即自动提交事务。
基于xml配置的动态sql语句
1.if标签的使用
IUserDao接口文件中添加方法:List <user> findUserByCondition(user u);
IUserDao.xml配置文件中添加:
1 <select id = "findUserByCondition" resultType="domain.user" parameterType="domain.user"> 2 select * from user where 1=1 3 <if test="username!=null"> 4 and username = #{username} 5 </if> 6 </select>
MyBatisTest测试类中添加:
1 @Test 2 public void testFindByCondition(){ 3 user u = new user(); 4 u.setUsername("老王"); 5 //使用代理对象执行方法 6 List<user> users = userDao.findUserByCondition(u); 7 for(user x:users){ 8 System.out.println(x); 9 } 10 }
2.where标签的使用
在if标签的基础上,修改IUserDao.xml配置文件
存在多个if条件时,可以用where标签包裹起来,并且去掉了where 1 =1
1 <select id = "findUserByCondition" resultType="domain.user" parameterType="domain.user"> 2 select * from user 3 <where> 4 <if test="username!=null"> 5 and username = #{username} 6 </if> 7 <if test="sex!=null"> 8 and sex = #{sex} 9 </if> 10 </where> 11 </select>
3.foreach标签的使用
这里实现的sql语句为:SELECT * FROM USER WHERE id IN(41,42,45);
在java/domain/QueryVo中添加private List<Integer> ids;并生成getters&setters
IUserDao接口文件中添加方法:List <user> findUserInIds(QueryVo vo);(根据QueryVo中提供的ID集合查询用户信息)
修改IUserDao.xml配置文件,注意第一行sql语句user后面不能加任何标点:
1 <select id = "findUserInIds" parameterType="domain.QueryVo" resultType="domain.user"> 2 select * from user //这里不能加分号 因为连着下面的sql语句 3 <where> 4 <if test="ids!=null and ids.size>0"> 5 <foreach collection="ids" open="and id in (" close=")" item="uid" separator=","> 6 #{uid} 7 </foreach> 8 </if> 9 </where> 10 </select>
MyBatisTest测试类中添加:
1 @Test 2 public void testFindInIds(){ 3 QueryVo vo = new QueryVo(); 4 List<Integer> list = new ArrayList<Integer>(); 5 list.add(41); 6 list.add(42); 7 list.add(45); 8 vo.setIds(list); 9 //使用代理对象执行方法 10 List <user> users = userDao.findUserInIds(vo); 11 for(user x:users){ 12 System.out.println(x); 13 } 14 }
4.sql标签的使用
通过在IUserDao.xml配置文件中,由于每一条查询都需要select * from user这条sql语句,因此可以在开头写(不加分号防止后续拼接错误):
<sql id="defaultUser">
select * from user
</sql>
在原来写这条语句的地方,用<include refid="defaultUser"></include>代替即可。