【Java Web】009 -- MyBatis(入门 增删改查 动态SQL)
目录
前言
什么是MyBatis?
一、MyBatis 入门
1、快速入门
①、案例介绍
②、实现过程
③、小结
④、扩展:配置SQL提示
2、JDBC介绍
①、本质
②、JDBC操作数据库代码示例
③、原始JDBC存在的问题
④、MyBatis是如何解决原始JDBC存在的问题的?
⑤、小结
3、数据库连接池
①、有无数据库连接池的对比
②、数据库连接池的优势
③、怎么实现数据库连接池
④、小结
4、lombok
①、介绍
二、MyBatis基础操作
1、环境准备
①、需求说明
②、准备工作
2、删除
①、根据主键删除
②、日志输出
③、预编译SQL
④、SQL注入
⑤、参数占位符(占位符不只#{},还有${})
⑥、小结
3、新增(插入数据)
①、新增示例
②、主键返回
③、小结
4、更新
①、更新示例
②、小结
5、查询
①、示例:根据ID查询
②、MyBatis的数据封装
③、条件查询
④、参数名说明
6、XML映射文件(通过XML文件实现MyBatis)
①、规范(三点)
②、XML映射文件插件(MyBatisX)
③、如何选择注解和XML?
④、小结
三、MyBatis动态SQL
1、标签
①、基础写法
②、案例:完善更新员工操作,改为动态SQL
③、小结
2、标签
①、批量删除操作
②、小结
3、标签(这两个标签配套使用)
4、小结
前言
什么是MyBatis?
MyBatis 官网: MyBatis中文网
一、MyBatis 入门
1、快速入门
①、案例介绍
案例:使用 MyBatis 查询所有用户数据
在 Java 中编写 SQL 语句,发送给服务器
实现步骤:
注意:在 MyBatis 的开发当中,我们只需要定义这个 Mapper 接口即可,是不需要定义它的实现类的,因为程序在运行时,框架底层会自动生成这个接口的实现类对象。
②、实现过程
Ⅰ、创建一个SpringBoot工程:
勾选 MyBatis 相关依赖:
Ⅱ、删除多余文件,保持项目整洁:
Ⅲ、数据库表与实体类的创建:
数据库表的创建可以在数据库中直接执行SQL文件解决;
实体类的创建:
Ⅳ、配置数据库的连接信息 -- application.properties(四要素):
Ⅴ、创建 Mapper 接口:
Ⅵ、基础代码写好后,进行单元测试:
效果展示:
③、小结
第一步: 第二步: 第三步: 第四步: |
④、扩展:配置SQL提示
我们可以在Mapper接口中配置SQL提示:
配置方法:
但是一开始配置的提示,是无法识别数据表信息的,解决办法就是 在IDEA中配置MySQL数据库连接
2、JDBC介绍
①、本质
②、JDBC操作数据库代码示例
这里的封装结果数据,需要有多少个字段就要解析多少个字段,最终效果展示: |
③、原始JDBC存在的问题
|
④、MyBatis是如何解决原始JDBC存在的问题的?
我们使用SpringBoot来整合MyBatis进行数据库操作的时候,主要关注两点:
⑤、小结
3、数据库连接池
类似于线程池:
①、有无数据库连接池的对比
如果没有数据库连接池:(随用随创建)
而有了数据库连接池:(在一开始就初始化了一定数量的连接对象),这样的话就可以做到连接的复用,而不是每一次都要新创建一个连接,同时数据库连接池还具有(空闲时间检测,当其监测到分配给客户端的连接对象空闲时间超过了指定时间,则将会把该连接释放,归还给连接池)
②、数据库连接池的优势
③、怎么实现数据库连接池
SpringBoot项目默认连接池:(HikariCP 来源于日语,意思为「光」,意味着它很快)
而Druid是阿里巴巴开源的数据库连接池项目:
切换数据库连接池:(主要就是切换pom.xml中的依赖)GitHub上有详细介绍
运行效果展示:
结构框图:
④、小结
4、lombok
简化实体类的方法:
①、介绍
但要想使用lombok,那么首先就要引入lombok的依赖:
示例:
注意事项:
lombok插件:
二、MyBatis基础操作
1、环境准备
①、需求说明
②、准备工作
具体可参考一中的快速入门案例
实体类中的注意点:
Mapper接口:(加上了@Mapper注解,就代表程序在运行时会自动的创建接口的代理对象,并且会将这个代理对象放入到 IOC 容器当中)
2、删除
①、根据主键删除
示例:
根据 ID 删除数据: |
EmpMapper.java(delete这里是有返回值的,返回的是影响的操作数) 单元测试: 效果展示: |
②、日志输出
运行之后效果展示:
③、预编译SQL
采用预编译SQL具有两大优势:
④、SQL注入
示例:(直接拼接SQL的方式)
而在预编译SQL中,这种方法则无法奏效:(这是因为在预编译SQL中无论你输入了什么,你输入的参数都将作为一个完整的数据添到占位符?处)
⑤、参数占位符(占位符不只#{},还有${})
但${}会直接将参数拼接在SQL语句中,存在SQL注入风险,所以一般情况下都使用#{}方式即可
⑥、小结
3、新增(插入数据)
①、新增示例
示例:
新增员工:(Mapper) |
单元测试: 效果展示: |
先写出SQL语句,再考虑在MyBatis当中,我该如何执行这条语句:(属性名一般以驼峰命名)
②、主键返回
默认情况下,执行基础的插入操作是不会把主键值返回的,我们如果想拿到这个主键值,我们该怎么做呢?(加入注解@Options())
③、小结
4、更新
①、更新示例
示例:根据主键修改员工的信息
更新数据:(SQL语句) (Mapper): |
单元测试: 效果展示: |
②、小结
5、查询
①、示例:根据ID查询
SQL语句: Mapper: |
单元测试: 效果展示: |
我们仔细看一下示例中的效果展示,结果发现,前面的数据都返回回来了,但是最后的三个属性却显示为null:
这就需要看一下MyBatis中的数据封装
②、MyBatis的数据封装
属性没有封装成功的原因就是因为类中的属性名与表中的字段名不一致
解决方案一:给字段起别名,让别名与实体类属性一致
解决方案二:通过@Results,@Result注解手动映射封装(因为其写法过于臃肿,实际开发中一般不怎么用)
解决方案三:开启MyBatis的驼峰命名自动映射开关
application.properties:
开启之后,就可以按照原来的写法返回查询了
但使用第三种方式是有前提的,你需要严格按照书写规范,数据库中的字段名用下划线分隔,类中的属性名采用驼峰命名的方式,才能自动完成映射
③、条件查询
示例:
Mapper语句: 【注意点】:#{}是不能出现在‘’中的,那么在进行模糊查询的时候,我们可以把 #{} 改为 ${} 应将其改为: |
单元测试: 效果展示: |
但是由于模糊查询这里我们使用的是 ${} 的方式实现的,这就会导致性能低,存在SQL注入问题的风险,我们可以通过 concat 字符串拼接函数来解决该问题:
④、参数名说明
这是因为在1.x版本中,在对Mapper接口进行编译的过程中,它并不会保留方法的形参名称,就比如:name, gender, begin, end 并不会在编译之后的字节码文件中保留,在生成的字节码文件中最终形成的形参的名字就成了下列的形式:
此时,就无法将形参和名称对应起来,所以需要额外加上一个@Param注解进行解释,而在2.x版本,在编译时,这些形参名会被保留下来:
6、XML映射文件(通过XML文件实现MyBatis)
①、规范(三点)
示例:创建一个XML映射文件
Ⅰ、在 resources 目录下创建包:(不用.,而是使用/ 分隔)
Ⅱ、创建XML文件,XML语法规范可以在MyBatis官网查询到
问题:为什么要遵循以上三点规范? |
答:因为两个文件是独立的,没有任何关联,我们需要通过以上规范来给它们建立关联关系 |
②、XML映射文件插件(MyBatisX)
可以实现语法的快速定位:
③、如何选择注解和XML?
简单来说:
④、小结
三、MyBatis动态SQL
我们想实现的效果:这个查询是根据输入的条件动态组装的,如我们要查询姓名,则只根据姓名进行查询,而实现这种查询的方式就是动态SQL
1、<if>标签
①、基础写法
XML语句: 单元测试: 效果展示:(没有查询 entrydate 与 update_time) |
我们将单元测试语句改为下列形式: 如果XML中的语句没变,则会出现以下错误:(提示语法错误,多了一个and) |
解决办法:将where关键字替换为<where>标签,用来动态生成where关键字,以及自动清除语句中的and 或者 or |
②、<if>案例:完善更新员工操作,改为动态SQL
之前写的update方法,如果某些字段没有赋值为空的话,也会将对应的字段赋值为空: 所以需要为其改为动态更新:(由于我们之前安装了MyBatisX,所以可以利用其自动生成) 生成:(标签会根据方法名进行生成,如这里是update,就给你生成update标签) 改造SQL语句: |
单元测试: 效果展示:(仅更新了赋值的字段) |
但是上列改造之后的SQL语句仍不完美,需要将其set关键字替换为<set>标签,作用与<where>类似
③、小结
2、<foreach>标签
①、批量删除操作
示例:
批量删除员工:(Mapper) (XML): |
单元测试: |
②、小结
3、<sql><include>标签(这两个标签配套使用)
如果XML中存在大量的重复语句时,就可以使用<sql><include>标签进行复用