一 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 configuration
PUBLIC "-//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 mapper
PUBLIC "-//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的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
//2. 获取SqlSession对象,用他来执行sql
SqlSession 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。注意。resuorces文件夹建Directory要用"/"分隔文件夹,不是"."。
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. 获取SqlSessionFactory
InputStream 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">
<!--mybatis的核心配置文件
核心配置文件中的子标签,必须按照以下的顺序进行配置,否则报错
"(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,
objectWrapperFactory?,reflectorFactory?,plugins?,environments?,
databaseIdProvider?,mappers?)"
-->
<configuration>
<!-- 引入properties形式的文件:resource属性用于指定文件的路径-->
<properties resource="jdbc.properties"/>
<!-- 开启Mybatis的日志组件功能,可以打印sql语句-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 用于给实体类起别名的 type 具体的实体类名称,
alias: 别名 不区分大小写, 可以不写,如果不写则使用类名作为别名
-->
<typeAliases>
<!-- <typeAlias type="com.mybatis.pojo.StudentCard"/>-->
<!-- <typeAlias type="com.mybatis.pojo.Student" alias="Student"/>-->
<!-- 使用扫描包的方式,来给实体类起别名,默认自己类名,也不区分大小写-->
<package name="com.mybatis.pojo"/>
</typeAliases>
<!-- environments:用来配置各种数据源
default用于指定使用哪一个数据源,通过书写environment子标记的id(唯一标识符)来确定
里面可以放入多对environment子标记-->
<environments default="development">
<!-- environment子标记: 用于指定数据源的配置信息:
属性: id 数据源的唯一标识符
-->
<environment id="development">
<!-- 指定mybatis的事务处理方式:JDBC|MANAGED
JDBC: Mybatis使用JDBC的原生事务处理方法,即使用JDBC的commit()、rollback()方法进行手动调用
MANAGED: Mybatis自己不处理事务,交给其他容器来管理mybatis事务
-->
<transactionManager type="JDBC"/>
<!-- type: 数据源的类型,有三个值: POOLED|UNPOOLED|JANI
POOLED:使用连接池技术,Connection对象从连接池中回去,不用的时候归还给连接池
UNPOOLED: 不使用连接池技术
JANI: 过时了
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 用于指定所有的Sql映射文件-->
<!-- 注册Sql映射文件-->
<mappers>
<!--
mapper: 用于指定一个具体的SQL映射文件,resource属性用于指定该文件的路径
如果是多层路径,必须使用斜杠隔开,相对的是resources文件夹来说的
-->
<!-- <mapper resource="com/mybatis/mapper/StudentMapper.xml"/>-->
<!-- <mapper resource="com/mybatis/mapper/StudentCardMapper.xml"/>-->
<!--
如果mapper的映射配置越来越多,我们可以使用扫描包的功能来配置
-->
<package name="com.mybatis.mapper"/>
</mappers>
</configuration>
3.2 Sql映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.EmployeeMapper">
<!--
为什么要使用映射
定义java实体类时,有自己的命名规范,比如属性名不建议使用下划线,多个单词时,使用驼峰命名法
定义表时,表的字段有自己的命名规范,比如列名是不区分大小写的,多个单词使用下划线连接。
有的时候,字段名称和属性名称如果相同,可以自动映射成功,进行赋值。即字段的值,赋值给属性。
但是有的时候,名称不一致,则不能映射成功。此时,我们可以自己定义映射关系
<resultMap> 用于自定义映射关系的
id: 这个映射关系的唯一标识
type: 用于指定具体的实体类型
小贴士: 如果不想编写映射关系,书写sql语句时,可以使用列别名,列别名必须和实体类的属性名相同。
-->
<resultMap id="resultMap1" type="Employee">
<!-- id子标签,专门用于主键映射
column: 指定数据库表中的字段名
property: 指定实体类中的属性名
-->
<id property="id" column="empno"/>
<result property="name" column="ename"/>
<result property="job" column="job"/>
<result property="mgr" column="mgr"/>
<result property="hireDate" column="hiredate"/>
<result property="sal" column="sal"/>
<result property="bonus" column="comm"/>
<result property="deptId" column="deptno"/>
</resultMap>
<!-- <resultMap> 用于指定使用哪一个映射关系,书写映射关系的id值
List<Employee> findAll(): 方法返回的是集合类型,resultType书写集合的元素类型即可。
-->
<select id="findAll" resultType="Employee" resultMap="resultMap1">
select * from emps
</select>
<!--
Employee findById(Integer id); 方法的定义,用于通过一个唯一标识来查询数据,返回一条。resultType就直接写返回值类型即可
#{}: 在底层转义时,会被翻译成?形式。与PreparedStatement的用法一样。传值时,?会被值所代替。
字符串形式的实际参数,在传过来后,会自动带上单引号。而且没有sql注入风险。
${}: 就是一个普通的拼接,如果需要单引号,需要自己拼接。有SQL注入风险
-->
<select id="findById" resultType="Employee" resultMap="resultMap1">
select * from emps where empno = #{id}
</select>
<select id="findByName" resultType="Employee" resultMap="resultMap1">
select * from emps where ename like #{name}
</select>
<!--
parameterType: 用于指定参数的类型,也可以书写别名
Integer类型的别名: int integer
int类型的别名: Int _int _integer
Map类型的别名: map
HashMap的别名: hashmap
List的别名: list
ArrayList的别名: arraylist
String的别名: string
Date的别名: date
Object的别名: object
-->
<delete id="delEmployee" parameterType="Integer">
delete from emps where empno = #{id}
</delete>
<!-- 接口里的方法带有参数,在此处就应该指定parameterType:
如果参数是实体类,那么占位符的名字必须与实体类的属性名相同-->
<insert id="addEmployee" parameterType="Employee">
insert into emps values(null,#{name},#{job},#{mgr},#{hireDate},#{sal},#{bonus},#{deptId})
</insert>
<update id="updateEmployee" parameterType="Employee">
update emps set ename = #{name},job = #{job},mgr = #{mgr},hiredate = #{hireDate},sal = #{sal},comm = #{bonus},deptno = #{deptId} where empno = #{id}
</update>
</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;
-- 切换到mybatis_db数据库
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 根据表映射实体类
package com.mybatis.pojo;
import java.sql.Date;
import java.util.Objects;
public class Employee {
private Integer id;
private String name;
private String job;
private Integer mgr;
private Date hireDate;
private Double sal;
private Double bonus;
private Integer deptId;
public Employee(){}
public Employee(Integer id, String name, String job, Integer mgr, Date hireDate, Double sal, Double bonus, Integer deptId) {
this.id = id;
this.name = name;
this.job = job;
this.mgr = mgr;
this.hireDate = hireDate;
this.sal = sal;
this.bonus = bonus;
this.deptId = deptId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Integer getMgr() {
return mgr;
}
public void setMgr(Integer mgr) {
this.mgr = mgr;
}
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
public Double getBonus() {
return bonus;
}
public void setBonus(Double bonus) {
this.bonus = bonus;
}
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
@Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
Employee employee = (Employee) object;
return Objects.equals(id, employee.id) && Objects.equals(name, employee.name) && Objects.equals(job, employee.job) && Objects.equals(mgr, employee.mgr) && Objects.equals(hireDate, employee.hireDate) && Objects.equals(sal, employee.sal) && Objects.equals(bonus, employee.bonus) && Objects.equals(deptId, employee.deptId);
}
@Override
public int hashCode() {
return Objects.hash(id, name, job, mgr, hireDate, sal, bonus, deptId);
}
@Override
public String toString() {
return id+","+name+","+job+","+mgr+","+hireDate+","+sal+","+bonus+","+deptId;
}
}
4.2.3 根据实体类或者表映射Mapper接口
package com.mybatis.mapper;
/*
实体类Employee对应的DAO/Mapper接口
*/
import com.mybatis.pojo.Employee;
import java.util.List;
public interface EmployeeMapper {
List<Employee> findAll();
Employee findById(Integer id);
Employee findByName(String name);
void delEmployee(Integer id);
void addEmployee(Employee employee);
void updateEmployee(Employee employee);
}
4.2.4 根据Mapper接口创建SQL映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.EmployeeMapper">
<resultMap id="resultMap1" type="Employee">
<!-- id子标签,专门用于主键映射
column: 指定数据库表中的字段名
property: 指定实体类中的属性名
-->
<id property="id" column="empno"/>
<result property="name" column="ename"/>
<result property="job" column="job"/>
<result property="mgr" column="mgr"/>
<result property="hireDate" column="hiredate"/>
<result property="sal" column="sal"/>
<result property="bonus" column="comm"/>
<result property="deptId" column="deptno"/>
</resultMap>
<select id="findAll" resultType="Employee" resultMap="resultMap1">
select * from emps
</select>
<select id="findById" resultType="Employee" resultMap="resultMap1">
select * from emps where empno = #{id}
</select>
<select id="findByName" resultType="Employee" resultMap="resultMap1">
select * from emps where ename like #{name}
</select>
<delete id="delEmployee" parameterType="Integer">
delete from emps where empno = #{id}
</delete>
<!-- 接口里的方法带有参数,在此处就应该指定parameterType:
如果参数是实体类,那么占位符的名字必须与实体类的属性名相同-->
<insert id="addEmployee" parameterType="Employee">
insert into emps values(null,#{name},#{job},#{mgr},#{hireDate},#{sal},#{bonus},#{deptId})
</insert>
<update id="updateEmployee" parameterType="Employee">
update emps set ename = #{name},job = #{job},mgr = #{mgr},hiredate = #{hireDate},sal = #{sal},comm = #{bonus},deptno = #{deptId} where empno = #{id}
</update>
</mapper>
4.3 CRUD的R
4.3.1 CRUD的R1
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="改成自己的接口的全限定名">
</mapper>
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=?
如果传入的是一个字符串,比如String name = "zhangsan", ?则会被zhangsan这个字符串替换。替换后,会自动转成数据库中的字符串形式: ....wehre name = 'zhangsan'。
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)测试
@Test
public 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事务
<transactionManager type="JDBC"/>
在核心配置文件中,我们配置了数据源的事务管理方式,要么是JDBC,要么是MANAGED。
JDBC: 即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())等。
MANAGED: MyBatis自身不会去实现事务管理,而是让程序的容器如(SPRING)来实现对事务的管理。
MyBatis在进行数据库的增删改(CUD)操作时,就涉及到了事务这个概念。
openSession(): 默认开启事务,进行增删改操作后需要使用sqlSession.commit(); 手动提交事务。(推荐使用)
openSession(true): 向方法中传入true,表示设置自动提交事务。(不推荐)
4.4.2 CRUD的D
1)在Mapper接口里添加修改方法
void updateEmployee(Employee e);
2)在Sql映射文件中添加对应的update配置
<!--修改员工信息-->
<update id="updateStudent" parameterType="student">
update student set
name = #{name},
age = #{age},
gender = #{gender},
id_card = #{idcard},
address = #{address}
where id = #{id}
</update>
3)测试
@Test
public 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();
}