Mybatis

一 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&amp;serverTimezone=Asia/Shanghai&amp;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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值