一 Mybatis概述
1.1 简介
MyBatis(官网:mybatis – MyBatis 3 | 简介 )是一款优秀的开源的 持久层 框架,用于简化JDBC的开发。是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis的特点
-
MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。
-
MyBatis封装了几乎所有的JDBC代码和参数的手工设置以及结果集的检索;
-
MyBatis使用简单的XML或注解做配置和定义映射关系,将Java的POJO(Plain Old Java Objects)映射成数据库中的记录。
持久层:指的是就是数据访问层(dao),是用来操作数据库的。
框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展。
1.2 MyBatis快速入门
1.2.1 准备数据
在mybatis_db库里维护Student表,添加数据
-- 创建数据库mybatis_db, 设置编码集 UTF8
create database if not exists mybatis_db character set utf8;
-- 切换到mybatis_db数据库
use mybatis_db;-- 创建学生信息表
create table `student`(
`id` int primary key auto_increment comment '学生ID,学生证ID',
`name` varchar(20) not null comment '学生名称',
`gender` char(1) not null comment '学生性别',
`age` int not null comment '学生年龄',
`address` varchar(50) not null comment '家庭地址'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='学生信息表';-- 插入数据
insert into student values
(1001,'刘备','m',40,'江南'),
(1002,'关羽','m',35,'上海'),
(1003,'虞姬','f',26,'北京'),
(1004,'赵云','m',27,'长春'),
(1005,'甄姬','f',26,'广州');select * from student;
1.2.2 创建模块,导入坐标
<dependencies>
<!--mybatis的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!--junit 测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
1.2.3 编写Mybatis核心配置文件
替换连接信息,解决硬编码问题 文件名:mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--连接信息--><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/edu_mybatis?useSSL=false&serverTimezone=Asia/Shanghai&useTimezone=true"/><property name="username" value="root"/><property name="password" value="mmforu"/></dataSource></environment></environments><mappers><!--配置相应的实体接口映射文件 resource属性里是文件的路径--><mapper resource="UserMapper.xml"/></mappers> </configuration>
1.2.4 编写sql映射文件
统一管理sql语句,解决硬编码问题 文件名:UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 属性 namespace:名称空间 建议:写相应实体接口的全名 --> <mapper namespace="test"><select id="findAll" resultType="com.shuilidianli.pojo.User">select * from tb_user;</select> </mapper>
1.2.5 编写代码
① 根据数据库表,定义pojo类
② 加载核心配置文件,获取SqlSessionFactory对象
③ 获取SqlSession对象,执行sql语句
④ 释放资源
public static void main(String[] args) throws IOException {// 1. 加载mybatis的核心配置文件,获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream); //2. 获取SqlSession对象,用他来执行sqlSqlSession sqlSession = sqlSessionFactory.openSession(); //3. 执行sql 调用selectList方法,传参 namespace.id,来指定要执行的sql语句List<User> users = sqlSession.selectList("test.findAll");System.out.println(users); //4. 释放资源sqlSession.close(); }
二 Mapper代理开发
2.1 目的
解决原生方式中的硬编码,简化后期执行的SQL
原生写法
//3 执行sql namespace.id List<User> users = sqlSession.selectList("test.findAll");
代理写法
//3 获取UserMapper接口的代理对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> users = mapper.findAll();
2.2 步骤
使用Mapper代理方式完成入门案例
1) 定义与SQL映射文件同名的Mapper接口
public interface UserMapper {// ...抽象的增删改查等方法 }
2)将SQL映射文件放置在resources下的与Mapper接口同名的路径里。 注意创建的是Directory,不是package
3)设置SQL映射文件的namespace属性为Mapper接口全限定名
<mapper namespace="com.sldl.mapper.UserMapper"> </mapper>
4)在Mapper接口中定义方法,方法名就是SQL映射文件中SQL语法的id,并保持参数类型和返回值类型一致
package com.sldl.mapper; import com.sldl.pojo.User; import java.util.List; public interface UserMapper {/*查询所有的用户信息*/List<User> findAll(); }
5)编码
- 通过SqlSession的getMapper方法获取Mapper接口的代理对象 - 调用对应方法完成sql的执行
@Test public void test2() throws IOException {//1. 获取SqlSessionFactoryInputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream); //2. 获取SqlSession对象SqlSession sqlSession = factory.openSession(); //3. 调用getMapper方法UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> users = mapper.findAll();for (User user : users) {System.out.println(user);} //4. 关闭会话sqlSession.close(); }
细节:如果Mapper接口名称与SQL映射文件名称相同,并且在同一个目录下,则可以使用包扫描的方式简化sql映射文件的加载
<mappers><mapper resource=/><package namne="com.sldl.mapper"/> </mappers>
三 Mybatis配置文件解析
3.1 核心配置文件解析
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd"><!--configuration: mybatis核心配置文件的根元素-->
<configuration><!--用于给pojo实体类起别名,起别名-->
<typeAliases>
<package name="com.sldl.pojo"/>
</typeAliases><!--environments: 设置连接数据库的环境,可以配置多个环境environment
属性default: 表示要连接哪一个environment, 值为environment的id-->
<environments default="development"><!-- 环境设置: id作为唯一标识符,-->
<environment id="development">
<!--配置事务管理方式:JDBC/MANAGED
JDBC:使用JDBC的事务管理方式,需要手动的提交或者回滚
MANAGED:将事务交给别的容器来管理:比如Spring....-->
<transactionManager type="JDBC"/>
<!--dataSource: 数据源的设置 JNDI/POOLED/UNPOOLED
JNDI:使用上下文中的数据源,已过时
POOLED:使用连接池(推荐)
UNPOOLED:不使用连接池-->
<dataSource type="POOLED">
<!--连接mysql的驱动-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<!--连接mysql的url路径-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_db?useSSL=false&serverTimezone=Asia/Shanghai&useTimezone=true"/>
<!--连接mysql的用户名-->
<!--连接mysql的密码-->
<property name="username" value="root"/>
<property name="password" value="mmforu"/>
</dataSource>
</environment><environment id="wangcm">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--连接mysql的驱动-->
<property name="driver" value="oracle"/>
<!--连接mysql的url路径-->
<property name="url" value="oracle"/>
<property name="username" value="oracle"/>
<property name="password" value="oracle"/>
</dataSource>
</environment>
</environments><!--加载sql映射文件-->
<mappers>
<!--resource: 用于书写映射文件的具体路径,注意:斜杠'/'作为分隔符-->
<!--<mapper resource="com/sldl/mapper/UserMapper.xml"/>--><!--如果文件路径较多, 可以使用路径扫描方式-->
<package name="com.sldl.mapper"/>
</mappers></configuration>
3.2 Sql映射文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--Sql映射文件:namespace: 命名空间,可以理解为mapper的唯一标识命名特点: 尽量使用Sql映射文件对应的接口的全限定名。 从src下的第一个包名开始写 mapper里配置的是各种与数据库交互的增删改查等操作标签 --> <mapper namespace="com.sldl.mapper.UserMapper"><!--select: 表示查询,*id 对应的是操作方法*resultType:返回的类型, 如果核心配置文件里配置了typeAliases,则可以写短名,大小写不敏感--><select id="findAll" resultType="user">select * from user</select> </mapper>
四 Mybatis完成CURD
4.1 MyBatisX插件
4.1.1 主要功能
① 智能补全与提示
MyBatisX 可以智能地提示和补全 SQL 语句中的关键字、表名、列名等信息,从而显著提高开发效率
② 代码生成器
- 虽然 MyBatisX 本身可能不直接提供一个完整的、独立的代码生成器,但它可能集成了或支持与其他代码生成工具(如 MyBatis Generator)的配合使用,以简化 Mapper 接口、Mapper XML 文件和 Java 实体类的生成过程。 - 通过 MyBatisX 的 GUI 界面,开发者可以根据数据库表结构快速生成所需的代码,减少重复劳动和降低出错率。
③ XML 校验器
MyBatisX 可以根据 XSD Schema 对 Mapper XML 文件进行验证,帮助开发者及时发现和解决 XML 文件中的语法错误。
④ 参数映射
MyBatisX 可以自动将 Java 方法参数与 Mapper XML 文件中的 SQL 语句参数进行映射,减少手动编写参数映射代码的需要
⑤ 快速导航与跳转
MyBatisX 支持在 Mapper 接口和 Mapper XML 文件之间快速导航和跳转,方便开发者在接口和 SQL 实现之间切换
⑥ 一键运行
MyBatisX 提供了一键运行的功能,允许开发者直接在编辑器中运行 SQL 语句,并查看执行结果和日志输出,方便调试和排错
4.1.2 安装与使用
① 安装插件
打开 IntelliJ IDEA,进入 File -> Settings -> Plugins -> Marketplace,搜索 “mybatisx” 并点击安装。注意,使用的 IDEA 版本需要与 MyBatisX 插件版本相兼容。
② 配置数据源
在 IDEA 中配置好数据库数据源,以便 MyBatisX 能够连接到数据库并根据数据库表结构生成代码。
③ 使用代码生成器
连接好数据源后,右键需要生成代码的表名,选择 MyBatisX 提供的代码生成器选项(如 MybatisX-Generator),然后按照提示填写相应信息并生成代码。
4.2 准备工作
4.2.1 数据库的表
-- 创建数据库mybatis_db, 设置编码集 UTF8
create database if not exists mybatis_db character set utf8;
-- 切换到mydb数据库
use mybatis_db;
-- 删除emp表结构
drop table if exists emp;
-- 创建emp表结构
CREATE TABLE `emp` (
`EMPNO` int primary key auto_increment COMMENT '员工编号',
`ENAME` varchar(10) DEFAULT NULL COMMENT '员工姓名',
`JOB` varchar(9) DEFAULT NULL COMMENT '员工职位',
`MGR` int DEFAULT NULL COMMENT '员工的直属领导编号,注意,领导也是员工,领导的信息也在这个表中',
`HIREDATE` date DEFAULT NULL COMMENT '入职日期',
`SAL` int DEFAULT NULL COMMENT '员工工资',
`COMM` int DEFAULT NULL COMMENT '员工奖金',
`DEPTNO` int DEFAULT NULL COMMENT '员工所在部门编号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='员工信息表'
-- 插入数据
insert into emp values
(7369,'SMITH','CLERK',7902,'1980-12-17',800,null,20),
(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30),
(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30),
(7566,'JONES','MANAGER',7839,'1981-04-02',2975,null,20),
(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30),
(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,null,30),
(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,null,10),
(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,null,20),
(7839,'KING','PRESIDENT',null,'1981-11-17',5000,null,10),
(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30),
(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,null,20),
(7900,'JAMES','CLERK',7698,'1981-12-03',950,null,30),
(7902,'FORD','ANALYST',7566,'1981-12-02',3000,null,20),
(7934,'MILLER','CLERK',7782,'1982-01-23',1300,null,10);
-- 查询表记录
select * from emp;
4.2.2 根据表映射实体类
4.2.3 根据实体类或者表映射Mapper接口
4.2.4 根据Mapper接口创建SQL映射文件
4.3 CURD的R
4.3.1 CRUD的R1
1)在Mapper接口里添加findAll方法
public interface EmployeeMapper {List<Employee> findAll(); }
2)在SQL映射文件中添加对应的配置
<select id="findAll" resultType="student">select * from emp </select>
3)执行方法,测试
@Test public void test3() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> students = mapper.findAll();for (Student student : students) {System.out.println(student);} sqlSession.close(); }
4.3.2 MyBatis获取参数的方式
如果接口里的方法带有参数,那么Mybatis的Sql语句是如何获取参数的呢?Mybatis提供了两种参数占位符,分别是 #{}
和 ${}
1)#{}:
相当于JDBC中的问号(?)占位符,是为SQL语句中的参数值进行占位,大部分情况下都是使用#{}
占位符;并且当#{}
占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号);
在mapper文件中: select * from employee where name=#{name} 在程序执行时替换成: select * from employee where name=?
2)${}
:
是为SQL片段(字符串)进行占位,将传过来的SQL片段直接拼接在 ${}
占位符所在的位置,不会进行任何的转义处理。(由于是直接将参数拼接在SQL语句中,因此可能会引发SQL注入攻击问题)
需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!mybatis3.5.x后可以不封装。
4.3.3 CRUD的R2
1)在接口里添加findById方法
Student findById(int id);
2)在Sql映射文件中添加对应的配置
<select id="findById" resultType="com.sldl.pojo.Student" resultMap="a">select * from student where id = #{id} </select>
3)测试
@Testpublic void test4() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream); SqlSession sqlSession = factory.openSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Student student = mapper.findById(1);System.out.println(student); sqlSession.close();}
4.4 CRUD的CUD
4.4.1 MyBatis事务
在核心配置文件中,我们配置了数据源的事务管理方式,要么是JDBC,要么是MANAGED。
-
JDBC: 即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())等。
-
MANAGED: MyBatis自身不会去实现事务管理,而是让程序的容器如(SPRING)来实现对事务的管理。
MyBatis在进行数据库的增删改(CUD)操作时,就涉及到了事务这个概念。
-
openSession(): 默认开启事务,进行增删改操作后需要使用sqlSession.commit(); 手动提交事务。(推荐使用)
-
openSession(true): 向方法中传入true,表示设置自动提交事务。(不推荐)
4.4.2 CRUD的U
1)在Mapper接口里添加修改方法
void updateEmployee(Employee e);
2)在Sql映射文件中添加对应的update配置
<!--修改员工信息--><update id="updateStudent" parameterType="student">update student setname = #{name},age = #{age},gender = #{gender},id_card = #{idcard},address = #{address}where id = #{id}</update>
3)测试
@Testpublic void test5() throws IOException { InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); //新创建一个Student类型Student s =new Student(1,"张三一",22,"女","220102000011112222", "北京"); mapper.updateStudent(s); //提交操作sqlSession.commit();//关闭sqlSession.close();}
4.4.3 CRUD的C
1)在StudentMapper.java里添加如下方法
void addStudent(Student s);
2)在StudentMapper.xml里添加对应的insert配置
<!--添加学生功能--> <insert id="addStudent" parameterType="student">insert into student values (null, #{name},#{age},#{gender},#{idcard},#{address}) </insert>
3)测试
@Test public void test6() throws IOException { InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); //新创建一个Student类型Student s =new Student("老七",22,"女","220102000011113333", "深圳"); mapper.addStudent(s); //提交操作sqlSession.commit();//关闭sqlSession.close(); }
4.4.4 CRUD的D
1)在接口StudentMapper.java里添加如下方法
void delStudent(int id)
2)在映射文件StudentMapper.xml里完善delete标签
<delete id="delStudent">delete from student where id = #{id} </delete>
3)测试
@Test public void test7() throws IOException {//获取SqlSession对象InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession(); //获取代理对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); //调用删除方法 删除id为1的记录mapper.delStudent(1); //增删改的事务会自动开启,因此需要手动提交sqlSession.commit();sqlSession.close(); }
4.5 多条件CRUD
上面的案例中,接口里方法的形参个数都是1个;如果方法形参是两个或者两个以上时,MyBatis又该如何获取获取参数呢?
Mybatis提供了好几种方式,可以获取多个参数的值
第一种: 使用arg0,arg1…或者param1,param2…来按照参数顺序获取对应的值
//2个或者2个以上的参数 Employee findByCondition1(String username,String password)
接口里的方法与Sql映射文件中的语句进行映射后,并且在调用方法期间,Mybatis会默认将所有传入到方法中的实际参数封装到一个Map对象中,实际参数作为value,按照从左到右的顺序,分别绑定到key名为arg0,arg1…或者param1,param2…上。
因此我们在获取参数时,可以这样写
select...from...where username = #{arg0} and password = #{arg1} ..... 或者 select...from...where username = #{param1} and password = #{param2} .....
第二种:Map作为参数
map 集合:只需要保证 SQL 中的参数名和 map 集合的键的名称对应上,即可设置成功
List<Student> findByCondition2(Map<String,Object> map);
第三种:实体类作为参数
实体类封装参数:只需要保证 SQL 中的参数名和实体类属性名对应上,即可设置成功
List<Student> findByCondition1(Student student);
第四种:使用@Param注解命名参数
散装参数:需要使用 @Param (" SQL 中的参数占位符名称")
List<Student> findByCondition1(@Param("id") int id, @Param("name") String name, @Param("address") String address);
2)在StudentMapper.xml里添加对应的select配置
<select id="findByCondition1" resultType="com.shuilidianli.pojo.Student">select * from student where id=#{id} and name=#{name} and address=#{address} </select>
3)测试
@Testpublic void test1() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // List<Student> byCondition1 = mapper.findByCondition1(1, "张三一", "北京");Student student = new Student(1,"张三一",-1,null,null,"北京"); // List<Student> byCondition1 = mapper.findByCondition1(student);Map<String,Object> map = new HashMap<>();//map.put("id",1);map.put("name","张三一");map.put("address","北京");List<Student> byCondition1 = mapper.findByCondition1(map);System.out.println(byCondition1);}
4.6 动态SQL
SQL语句会随着用户的输入和外部条件的变化而变化,我们称之为动态SQL。MyBatis对动态SQL有很强大的支持。
4.6.1 where/if标签
if标签,是根据test属性
中的布尔表达式的值,从而决定是否执行包含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果结果为false,则不执行其中的SQL片段
存在的问题:第一个条件不需要逻辑运算符。
案例演示:
在接口StudentMapper.java里添加如下方法
List<Student> findByCondition(Map map);
在映射文件StudentMapper.xml里配置如下
第一种方案:使用恒等式让所有条件格式都一样
<select id="findByCondition1" >select *from studentwhere 1 = 1<if test="id != null">and id = #{id}</if><if test="name != null and name != '' ">and name = #{name}</if><if test="address != null and address != '' ">and address = #{address}</if></select>
第二种方案:使用<where>
标签替换where关键字。 注意:where标签会将第一个条件之前的连接符自动去掉
<select id="findByCondition1" >select *from student/* where 1 = 1*/<where><if test="id != null">and id = #{id}</if><if test="name != null and name != '' ">and name = #{name}</if><if test="address != null and address != '' ">and address = #{address}</if></where> </select>
4.6.2 choose/when标签
choose(when,otherwise):类似于java的switch-case-default, 只要满足一个when,choose就结束了,如果都不满足,就会执行otherwise。
1)在接口StudentMapper里添加如下方法
List<Student> findByCondition1(Map map);
2)在sql映射文件StudentMapper.xml里添加如下内容
<select id="findByCondition1" >select *from studentwhere<choose><!-- 类似于switch--><when test=" id != null"><!-- 类似于case-->id = #{id}</when><when test=" name != null and name != '' ">name = #{name}</when><when test=" address != null and address != ''">address = #{address}</when><otherwise><!-- 类似于default-->1 = 1</otherwise></choose> </select>
3)测试
@Test public void test9() throws IOException {//获取SqlSession对象InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession(); //获取代理对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); //创建一个map对象Map<String,Object> map = new HashMap<>();// map.put("id",2);// map.put("name","小明");// map.put("address","长春朝阳区"); /*选择map中的一个条件进行查询,*/List<Student> students = mapper.findByCondition1(map); for (Student student : students) {System.out.println(student);} sqlSession.close(); }
4.6.3 set/if标签
当进行修改时,有些字段可能有选择的进行修改,这时我们就可以使用<set>
标签 配合<if>
标签来完成操作。set标签会自动将最后一个条件的逗号去掉。
1)在接口StudentMapper里添加如下方法
//修改学生信息 void modifyStudent(Map map);
2)在StudentMapper.xml里添加如下内容
<update id="modifyStudent">update student<set><if test="name !=null and name != ''">name = #{name},</if><if test="age != null and age != '' ">age = #{age},</if><if test="gender != null and gender != '' ">gender = #{gender},</if><if test="idcard != null and idcard != '' ">idcard = #{idcard},</if><if test="address != null and address != '' ">address = #{address},</if></set>where id = #{id} </update>
3)测试
@Test public void test10() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Map<String,Object> info = new HashMap<>();//存储id为2的信息info.put("id",2);info.put("name","王小二");info.put("gender","女");info.put("age",23);info.put("address","净月区"); mapper.modifyStudent(info); sqlSession.commit();sqlSession.close(); }
4.6.4 foreach标签
<foreach>
标签的使用, 比如进行集合查询等操作
1)在接口StudentMapper里添加如下方法
List<Student> findByIds(List list);
2)在StudentMapper.xml里添加如下内容
<select id="findByIds" resultType="com.sldl.pojo.Student">select *from studentwhere id in<foreach collection="list" separator="," open="(" close=")" item="id">#{id}</foreach> </select>
3)测试
@Test public void test11() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Integer> ids = new ArrayList<>();ids.add(1);ids.add(2);ids.add(3);ids.add(4);ids.add(5); List<Student> byIds = mapper.findByIds(ids);for (Student byId : byIds) {System.out.println(byId);} sqlSession.close(); }