Mybatis

1.Mybatis入门

1.1 Mybatis定义

  • MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。

  • MyBatis本是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

  • 官网:https://mybatis.org/mybatis-3/zh/index.html

在上面我们提到了两个词:一个是持久层,另一个是框架

  • 持久层:指的是就是数据访问层(dao),是用来操作数据库的
image-20231223160804125
  • 框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展

1.2 入门程序分析

现在使用Mybatis操作数据库,就是在Mybatis中编写SQL查询代码,发送给数据库执行,数据库执行后返回结果

image-20231223161034687

Mybatis会把数据库执行的查询结果,使用实体类封装起来(一行记录对应一个实体类对象)

image-20231223161114930

1.3 入门程序实现步骤

  1. 准备工作(创建springboot工程、数据库表user、实体类User)
  2. 在pom.xml中引入Mybatis的相关依赖,
  3. yml文件中配置Mybatis(数据库连接信息)
  4. mapper层编写SQL语句(注解/XML)

1.3 解决mapper层编写sql语句不提醒

image-20231223161415812

1.4 JDBC

1.4.1 介绍

通过Mybatis可以很方便的进行数据库的访问操作。但是大家要明白,其实java语言操作数据库呢,只能通过一种方式:使用sun公司提供的 JDBC 规范

Mybatis框架,就是对原始的JDBC程序(Java语言操作关系型数据库的一套API)的封装

image-20231223161912481

本质:

  • sun公司官方定义的一套操作所有关系型数据库的规范,即接口。

  • 各个数据库厂商去实现这套接口,提供数据库驱动jar包。

  • 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。

1.4.2 代码

下面我们看看原始的JDBC程序是如何操作数据库的。操作步骤如下:

  1. 注册驱动
  2. 获取连接对象
  3. 执行SQL语句,返回执行结果
  4. 处理执行结果
  5. 释放资源

在pom.xml文件中已引入MySQL驱动依赖,我们直接编写JDBC代码即可

JDBC具体代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import com.itheima.pojo.User;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class JdbcTest {
@Test
public void testJdbc() throws Exception {
//1. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");

//2. 获取数据库连接
String url="jdbc:mysql://127.0.0.1:3306/mybatis";
String username = "root";
String password = "1234";
Connection connection = DriverManager.getConnection(url, username, password);

//3. 执行SQL
Statement statement = connection.createStatement(); //操作SQL的对象
String sql="select id,name,age,gender,phone from user";
ResultSet rs = statement.executeQuery(sql);//SQL查询结果会封装在ResultSet对象中

List<User> userList = new ArrayList<>();//集合对象(用于存储User对象)
//4. 处理SQL执行结果
while (rs.next()){
//取出一行记录中id、name、age、gender、phone下的数据
int id = rs.getInt("id");
String name = rs.getString("name");
short age = rs.getShort("age");
short gender = rs.getShort("gender");
String phone = rs.getString("phone");
//把一行记录中的数据,封装到User对象中
User user = new User(id,name,age,gender,phone);
userList.add(user);//User对象添加到集合
}
//5. 释放资源
statement.close();
connection.close();
rs.close();

//遍历集合
for (User user : userList) {
System.out.println(user);
}
}
}

DriverManager(类):数据库驱动管理类。

  • 作用:

    1. 注册驱动

    2. 创建java代码和数据库之间的连接,即获取Connection对象

Connection(接口):建立数据库连接的对象

  • 作用:用于建立java程序和数据库之间的连接

Statement(接口): 数据库操作对象(执行SQL语句的对象)。

  • 作用:用于向数据库发送sql语句

ResultSet(接口):结果集对象(一张虚拟表)

  • 作用:sql查询语句的执行结果会封装在ResultSet中

通过上述代码,我们看到直接基于JDBC程序来操作数据库,代码实现非常繁琐,所以在项目开发中,我们很少使用。 在项目开发中,通常会使用Mybatis这类的高级技术来操作数据库,从而简化数据库操作、提高开发效率

1.4.3 问题分析

原始的JDBC程序,存在以下几点问题:

  1. 数据库链接的四要素(驱动、链接、用户名、密码)全部硬编码在java代码中
  2. 查询结果的解析及封装非常繁琐
  3. 每一次查询数据库都需要获取连接,操作完毕后释放连接, 资源浪费, 性能降低
image-20231223162511117

1.4.4 mybatis优化点

分析了JDBC的缺点之后,我们再来看一下在mybatis中,是如何解决这些问题的:

  1. 数据库连接四要素(驱动、链接、用户名、密码),都配置在springboot默认的配置文件 application.properties中

  2. 查询结果的解析及封装,由mybatis自动完成映射封装,我们无需关注

  3. 在mybatis中使用了数据库连接池(Springboot默认Hikari追光者)技术,从而避免了频繁的创建连接、销毁连接而带来的资源浪费。

image-20231223162830839

1.5 数据库连接池(四种)

1.5.1 介绍

image-20231223163023536

没有使用数据库连接池:

  • 客户端执行SQL语句:要先创建一个新的连接对象,然后执行SQL语句,SQL语句执行后又需要关闭连接对象从而释放资源,每次执行SQL时都需要创建连接、销毁链接,这种频繁的重复创建销毁的过程是比较耗费计算机的性能。
image-20231223163123510
  • 程序在启动时,会在数据库连接池(容器)中,创建一定数量的Connection对象

允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个

  • 客户端在执行SQL时,先从连接池中获取一个Connection对象,然后在执行SQL语句,SQL语句执行完之后,释放Connection时就会把Connection对象归还给连接池(Connection对象可以复用)

释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏

  • 客户端获取到Connection对象了,但是Connection对象并没有去访问数据库(处于空闲),数据库连接池发现Connection对象的空闲时间 > 连接池中预设的最大空闲时间,此时数据库连接池就会自动释放掉这个连接对象

数据库连接池的好处:

  1. 资源重用
  2. 提升系统响应速度
  3. 避免数据库连接遗漏

1.5.2 四种连接池

常见的数据库连接池:

  • C3P0
  • DBCP
  • Druid
  • Hikari (springboot默认)

现在使用更多的是:Hikari、Druid (性能更优越)

  • Hikari(追光者) [默认的连接池]

    image-20231223163247807

  • Druid(德鲁伊)

​ Druid连接池是阿里巴巴开源的数据库连接池项目

​ 功能强大,性能优秀,是Java语言最好的数据库连接池之一

1.5.3 更换连接池

把默认的数据库连接池切换为Druid数据库连接池,只需要完成以下两步操作即可:

参考官方地址:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

1.在pom.xml文件中引入依赖

1
2
3
4
5
6
<dependency>
<!-- Druid连接池依赖 -->
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>

2.在配置文件中引入数据库连接配置(2种方式)

1
2
3
4
5
6
7
8
9
10
11
方式1:(datasource后面加druid)
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.druid.username=root
spring.datasource.druid.password=1234

方式2:(原始方式)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.username=root
spring.datasource.password=1234

1.6 lombok(编译阶段)

1.6.1 介绍

Lombok是一个实用的Java类库,可以通过简单的注解来简化和消除一些必须有但显得很臃肿的Java代码

image-20231223163915779

通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率

注解 作用
@Getter/@Setter 为所有的属性提供get/set方法
@ToString 为类自动生成易阅读的 toString 方法
@EqualsAndHashCode 为类提供拥有的非静态字段自动重写 equals 方法和 hashCode 方法
@Data 提供了更综合的生成代码功能(@Getter + @Setter + @ToString + @EqualsAndHashCode) 集成了前四个注解
@NoArgsConstructor 为实体类生成无参的构造器方法
@AllArgsConstructor 为实体类生成除了static修饰的字段之外带有各参数的构造器方法。

1.6.2 使用步骤

第1步:在pom.xml文件中引入依赖

1
2
3
4
5
<!-- 在springboot的父工程中,已经集成了lombok并指定了版本号,故当前引入依赖时不需要指定version -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

第2步:在实体类上添加注解

1
2
3
4
5
6
7
8
9
10
11
12
import lombok.Data;

@Data //getter方法、setter方法、toString方法、hashCode方法、equals方法
@NoArgsConstructor //无参构造
@AllArgsConstructor//全参构造
public class User {
private Integer id;
private String name;
private Short age;
private Short gender;
private String phone;
}

2.Mybatis基础操作

2.1 新增(@Insert)

2.2 删除(@Delete)

2.3 查询(@Selete)

2.4 修改(@Update)

3.Mybatis两种书写sql语句的形式

3.1 mapper层注解

image-20231224213236692

3.2 xml映射文件

image-20231224213254184

3.2.1 创建xml文件

  • 整体图
image-20231224213633587

创建位置:必须要和mapper层保持同一个包级别和同名(==同包同名==)

image-20231224213417001

命名规则:要保证mapper的namespacce和mapper同全路径名,四大类语句的id要和方法名一致,resultType要和方法返回值(最里面的)一致

image-20231224213458370

4.动态sql(在xml映射文件)

4.1 if

4.1.1 作用

用于判断条件是否成立 –如果条件为true就拼接sql

4.1.2 使用位置

image-20231224214251931

4.2 where

4.2.1 作用

1.在子元素有内容的情况下插入where子句
2.自动去除子句开头的and/or

4.2.2 使用位置

image-20231224214332923

4.3 set

4.3.1 作用

1.动态的在行首插入set关键字
2.自动去除额外的逗号

4.3.2 使用位置

image-20231224214629066

4.4 foreach

4.4.1 作用

循环的时候批量处理一部分数据

4.4.2 使用位置

image-20231224214910899

4.5 sql和include

4.5.1 作用

将一些固定的(重复的/相同的)sql提取出来

4.5.2 使用位置

image-20231224214941397

4.6 choose-when-otherwise

4.6.1 作用

类似于Java的Switch语句,可以实现选择

4.6.2 使用位置

image-20240407133356683

4.7 trim

4.7.1 作用

生成sql语句的时候,在前后添加自定义的字符串

4.7.2 使用位置

prefix:加前缀

prefixOverrides:要覆盖的前缀

suffix:加后缀

suffixOverrides:要覆盖的后缀

image-20240407133446397

4.8 bind

4.8.1 作用

可以将表达式结果/特定内容绑定到一个变量,这个变量可以在sql语句中使用【类似于参数宏定义】

4.8.2 使用位置

image-20240407133530203

5.mybatis日志输出

在Mybatis当中我们可以借助日志,查看到sql语句的执行、执行传递的参数以及执行结果。具体操作如下:

  1. 打开application.properties文件
  2. 开启mybatis的日志,并指定输出到控制台
1
2
#指定mybatis输出日志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

开启日志之后,我们再次运行单元测试,可以看到在控制台中,输出了以下的SQL语句信息:

image-20231224221349185

但是我们发现输出的SQL语句:delete from emp where id = ?,我们输入的参数16并没有在后面拼接,id的值是使用?进行占位。那这种SQL语句我们称为预编译SQL

6.预编译SQL

mybatis中mapper层的写法就是预编译sql,传入参数放入的形式

image-20231224221537386

预编译SQL有两个优势:

  1. 性能更高

    image-20231224221640562

  2. 更安全(防止SQL注入)

image-20231224221649839

7.参数占位符

image-20231224221713753

如果mapper接口方法形参只有一个普通类型的参数,#{…} 里面的属性名可以随便写

8.数据封装(mysql列名和实体类属性名不一致)

8.1 出现场景

image-20231224221958093 image-20231224222223153

8.2 三种解决方案

image-20231224222522754

1. mapper层sql语句内起别名

image-20231224222245625

2.mapper层方法上添加@Results和@Result注解手动映射

image-20231224222316757

3.yml配置文件打开驼峰命名(推荐)

image-20231224222337724

9.#{}和${}区别

#{}表达式为OGNL表达式

${}表达式为EL表达式

1)相同:都可以获取对象的信息。

(2)#{ }

执行SQL时,会将#{ }替换为?,生成预编译SQL,会自动设置参数值,防止SQL注入
使用时机:参数传递,都使用#{ }
(3)${ }

​ 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题
​ 使用时机:如果对表名、列表进行动态设置时使用【东林微课堂创建每个月赛季表】

(4)#{ } 只能操作跟数据字表字段相关的列值,跟列值无关的只能用${ }

(5)#{ } 底层使用的是PreparedStatement,${ } 底层使用的是 Statement

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 1.Mybatis入门
    1. 1.1. 1.1 Mybatis定义
    2. 1.2. 1.2 入门程序分析
    3. 1.3. 1.3 入门程序实现步骤
    4. 1.4. 1.3 解决mapper层编写sql语句不提醒
    5. 1.5. 1.4 JDBC
      1. 1.5.1. 1.4.1 介绍
      2. 1.5.2. 1.4.2 代码
      3. 1.5.3. 1.4.3 问题分析
      4. 1.5.4. 1.4.4 mybatis优化点
    6. 1.6. 1.5 数据库连接池(四种)
      1. 1.6.1. 1.5.1 介绍
      2. 1.6.2. 1.5.2 四种连接池
      3. 1.6.3. 1.5.3 更换连接池
    7. 1.7. 1.6 lombok(编译阶段)
      1. 1.7.1. 1.6.1 介绍
      2. 1.7.2. 1.6.2 使用步骤
  2. 2. 2.Mybatis基础操作
    1. 2.1. 2.1 新增(@Insert)
    2. 2.2. 2.2 删除(@Delete)
    3. 2.3. 2.3 查询(@Selete)
    4. 2.4. 2.4 修改(@Update)
  3. 3. 3.Mybatis两种书写sql语句的形式
    1. 3.1. 3.1 mapper层注解
    2. 3.2. 3.2 xml映射文件
      1. 3.2.1. 3.2.1 创建xml文件
  4. 4. 4.动态sql(在xml映射文件)
    1. 4.1. 4.1 if
      1. 4.1.1. 4.1.1 作用
      2. 4.1.2. 4.1.2 使用位置
    2. 4.2. 4.2 where
      1. 4.2.1. 4.2.1 作用
      2. 4.2.2. 4.2.2 使用位置
    3. 4.3. 4.3 set
      1. 4.3.1. 4.3.1 作用
      2. 4.3.2. 4.3.2 使用位置
    4. 4.4. 4.4 foreach
      1. 4.4.1. 4.4.1 作用
      2. 4.4.2. 4.4.2 使用位置
    5. 4.5. 4.5 sql和include
      1. 4.5.1. 4.5.1 作用
      2. 4.5.2. 4.5.2 使用位置
    6. 4.6. 4.6 choose-when-otherwise
      1. 4.6.1. 4.6.1 作用
      2. 4.6.2. 4.6.2 使用位置
    7. 4.7. 4.7 trim
      1. 4.7.1. 4.7.1 作用
      2. 4.7.2. 4.7.2 使用位置
    8. 4.8. 4.8 bind
      1. 4.8.1. 4.8.1 作用
      2. 4.8.2. 4.8.2 使用位置
  5. 5. 5.mybatis日志输出
  6. 6. 6.预编译SQL
  7. 7. 7.参数占位符
  8. 8. 8.数据封装(mysql列名和实体类属性名不一致)
    1. 8.1. 8.1 出现场景
    2. 8.2. 8.2 三种解决方案
      1. 8.2.1. 1. mapper层sql语句内起别名
      2. 8.2.2. 2.mapper层方法上添加@Results和@Result注解手动映射
      3. 8.2.3. 3.yml配置文件打开驼峰命名(推荐)
  9. 9. 9.#{}和${}区别
,