用来访问操作数据库的一个框架
创建spring boot工程的时候点上mybatis的起步依赖和mysql的驱动包
图示:

准备好对应数据的实体类
在Mybatis中要连接数据库,需要以下4个参数配置:
MySQL驱动类
登录名
密码
数据库连接字符串
那怎么获得这四个参数的值呢?
登录名和密码就是登录数据库的账号和密码
mysql驱动类和mysql数据库连接字符串可以在新建数据库源的界面找到
图示:

得到四个值后直接在springboot项目中的application.properties文件按下面的格式写入就行了
- #驱动类名称
- spring.datasource.driver-class-name=驱动类名称
- #数据库连接字符串
- spring.datasource.url=数据库连接字符串
- #连接数据库的用户名
- spring.datasource.username=连接数据库的用户名
- #连接数据库的密码
- spring.datasource.password=连接数据库的密码
首先在启动类所在包下创建一个mapper包(持久层,代替了Dao),然后在里面创建一个xxxMapper接口(Mybatis的持久层接口规范一般都叫 XxxMapper )
图示:

在接口类名上打上@Mapper注解,在接口里面定义一个个方法用来访问数据,然后在每个方法上打上对应的注解,在注解的属性中写上对应的sql语句,光说可能比较抽象,上图:

如果需要sql语句联想,可以选中sql语句部分-->右击-->显示上下文操作-->语言注入设置-->Mysql


然后就会出现sql语句联想了,如果对应的表名字段名之类的没联想出来,可能是IDEA没有连接该数据库
在实际开发中,大部分情况下sql语句都不应该是写死的,不可变的,而应该是配合变量达到根据要求查询的效果,所以参数占位符便来了:
在Mybatis中提供的参数占位符有两种:${...} 、#{...}
#{...}
执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值
使用时机:参数传递,都使用#{…}
${...}
拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题
使用时机:如果对表名、列表进行动态设置时使用
图示:

如图,根据传入的id值删除部门
在实际开发中,推荐使用#{...}而不是${...},因为#{...}不仅效率更高,还更安全,可以防sql注入
效率高:预编译SQL,编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译。(只是输入的参数不同)
sql注入:假如使用${...},用户可以直接输入譬如 'or'1'='1 之类的密码,拼接之后就会是
select * from emp where username = #{username} and password = '' or '1'='1';
毫无疑问这是非常糟糕的,根本不需要正确的密码直接就登录了
在使用参数占位符时也可以直接对应对象类型的形参的成员属性,比如
- //修改员工信息
- @Update("update emp set username = #{username}, name = #{name}, gender = #{gender}, image = #{image}," +
- " job = #{job},dept_id = #{deptId}, entrydate = #{entrydate}, update_time = #{updateTime} where id = #{id}")
- void update(Emp emp);
前提是有在emp对象中设置对应的属性值
如果在数据添加成功后,需要获取插入数据库数据的主键——
可以在Mapper接口中的方法上添加一个Options注解,并在注解中指定属useGeneratedKeys=true和keyProperty="实体类属性名"
- //修改员工信息
- //会自动将生成的主键值,赋值给emp对象的id属性
- @Options(useGeneratedKeys = true,keyProperty = "id")
- @Update("update emp set username = #{username}, name = #{name}, gender = #{gender}, image = #{image}," +
- " job = #{job},dept_id = #{deptId}, entrydate = #{entrydate}, update_time = #{updateTime} where id = #{id}")
- void update(Emp emp);
一般在java中命名变量名 都是使用驼峰命名法,而在数据库中一般是使用_分隔,例如部门id的属性值在java中可能习惯命名为deptId而在数据库中习惯命名为dept_id,此时就会出现对象属性名与数据库字段名不匹配的情况
可开启驼峰命名 解决
驼峰命名:如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射
驼峰命名规则: abc_xyz => abcXyz
表中字段名:abc_xyz
类中属性名:abcXyz
直接在application.properties中添加如下属性就可以了
mybatis.configuration.map-underscore-to-camel-case=true
要使用驼峰命名前提是 实体类的属性 与 数据库表中的字段名严格遵守驼峰命名
如果要实现比较复杂的sql语句,使用注解就会让代码显得比较臃肿,而且不太方便,此时就可以使用xml来配置映射语句,也就是将sql语句编写在xml配置文件中
在Mybatis中使用XML映射文件方式开发,需要符合一定的规范:
XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在同名的包下(同包同名)
XML映射文件的namespace属性为Mapper接口全限定名一致
XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致
关于第一点(配置文件都是放在resources目录下):

关于第二点:

直接按住ctrl单击接口名就可以得知接口的全限定名
关于第三点:

xml映射文件中上面那一串dtd约束,直接从mybatis官网复制即可
- "1.0" encoding="UTF-8" ?>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="">
-
- mapper>
然后在mapper标签中写上对应标签,在其中写上sql语句就ok了
图示:

譬如上图select查询就是映射的com.zeyu.mapper下的EmpMapper接口中的list方法,其list方法的返回值类型为com.zeyu.pojo下的Emp实体类,通过这三个属性值,就可以将编写的sql定位到一个方法上,而在xml中也有一种特殊的语法,那就是动态sql——
如果test中的表达式为真,则执行if标签中的语句,否则不执行
图示:

聪明的小伙伴肯定发现了,假如第一个if为假,其它if为真,那直接拼接不就成了
select * from emp where and gender = #{gender} and entrydate between #{begin} and #{end} order by update_time desc
where 后面怎么可以直接写and呢?!
所以为了解决这个情况,有了where标签
只会在子元素有内容的情况下才会插入where,且自动去除多余的and或or
图示:
同样的道理,在我们动态执行修改语句时,也可能出现最后多出一个逗号的情况
图示:

聪明的小伙伴肯定又想到了,假如最后一个if没有执行,那where前面就多出了一个逗号
自然而然的,set标签出现了
动态的在SQL语句中插入set关键字,并会删掉多余的逗号
图示:

假如传入的参数是一个数组或列表,比如要根据id批量删除员工,此时就可以使用
图示:

减少重复sql的编写——sql&include

使用sql标签将重复语句打包,id值为该sql片段的名字

使用include引入打包好的sql片段,refid值为要引入的sql片段的名字
什么是JDBC呢?
JDBC: ( Java DataBase Connectivity ),就是使用Java语言操作关系型数据库的一套API
Mybatis框架,就是对原始的JDBC程序的封装

本质:
sun公司官方定义的一套操作所有关系型数据库的规范,即接口。
各个数据库厂商去实现这套接口,提供数据库驱动jar包。
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
原始的JDBC程序是操作数据库的操作步骤如下:
- 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(类):数据库驱动管理类。
作用:
注册驱动
创建java代码和数据库之间的连接,即获取Connection对象
Connection(接口):建立数据库连接的对象
作用:用于建立java程序和数据库之间的连接
Statement(接口): 数据库操作对象(执行SQL语句的对象)。
作用:用于向数据库发送sql语句
ResultSet(接口):结果集对象(一张虚拟表)
作用:sql查询语句的执行结果会封装在ResultSet中
通过上述代码 操作数据库 显然是非常繁琐的,所以在项目开发中很少使用,通常会使用Mybatis这类的高级技术来操作数据库
数据库连接池是个容器,负责分配、管理数据库连接(Connection)
程序在启动时,会在数据库连接池(容器)中,创建一定数量的Connection对象
允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
客户端在执行SQL时,先从连接池中获取一个Connection对象,然后在执行SQL语句,SQL语句执行完之后,释放Connection时就会把Connection对象归还给连接池(Connection对象可以复用)
释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏
客户端获取到Connection对象了,但是Connection对象并没有去访问数据库(处于空闲),数据库连接池发现Connection对象的空闲时间 > 连接池中预设的最大空闲时间,此时数据库连接池就会自动释放掉这个连接对象
数据库连接池的好处:
资源重用
提升系统响应速度
避免数据库连接遗漏
现在使用更多的数据库连接池是:Hikari(追光者) [默认的连接池] 、Druid (德鲁伊)
如果想把默认的数据库连接池切换为Druid数据库连接池,只需要完成以下两步操作即可:
在pom.xml文件中引入依赖
- <dependency>
- <!-- Druid连接池依赖 -->
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>1.2.8</version>
- </dependency>
在application.properties中引入数据库连接配置
- 方式1:
- 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