- JDBC
- MyBatis概述
- MyBatis基础应用
- MyBatis动态标签
一、JDBC( Java DataBase Connectivity ):Java连接数据库的解决方案
概念:JDBC就是Java后端操作数据库的解决方案,操作数据的指令应该来自于前端,前端把数据提交到后端Java代码,由后端Java代码操作数据库(JDBC是Java提供的一套专门用于操作数据库的接口或规范,没有提供实现,由各大数据厂商提供实现)他们提供的实现统称为驱动包driver,要操作数据库就需要导入相应的驱动包
二、MyBatis概述
- 概念:MyBatis是一个半ORM的数据库持久化框架,它是三层架构中持久层的技术
框架:框架指的就是一些类和接口的集合,是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展
持久化:就是将对象数据,保存到数据库当中,从而达到数据断电也存在的目的,叫做持久化
持久层:指的是就是数据访问层/Dao层,是用来操作数据库的
ORM:对象关系映射(Object Relational Mapping,简称ORM):是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术
半ORM(半映射):不是通过完整的映射方式,需要自己写sql语句【Mybatis】
全ORM框架(全映射):JPA、Hibernate、MyBatis-Plus
注意:Mybatis底层还是通过JDBC实现数据库的操作的。封装了JDBC代码
注意:操作mysql唯一语言:sql。java代码操作mysql的唯一技术:jdbc
- 持久化技术对比
- JDBC
- Hibernate&JPA
- MyBatis
JDBC(Java Database Connectivity )Java数据库连接
概念:是一套用于通过执行SQL语句操作数据库的Java API,应用程序可通过这套API连接到关系数据库,并使用SQL语句来完成对数据库中数据的查询、更新和删除等操作
作用:JDBC是Java连接数据库的唯一技术,只不过因为缺点太过明显,现在基本上都是使用JDBC的封装框架,例如MyBatis、MyBatis-Plus等
特点:
1. SQL语句与Java代码写在一起,耦合度高。不易维护,如果要修改SQL语句还需要修改Java代码 2. 代码量多,开发效率低,重复代码过多 3. 开发麻烦,需要手动设置参数,如果有查询结果还需要手动转换结果(ResultSet - domain或List) 原生操作数据库代码,执行效率高
Hibernate&JPA
概念:JPA是一种持久化规范,而Hibernate是一种实现(全ORM框架)。简单的CRUD不用写SQL
特点:
1. 全映射ORM框架,大量字段时映射部分字段比较困难 2. 内部反射操作多,性能较低 3. 简单的CRUD不用写SQL,但自动生成的SQL语句,SQL语句不方便优化 操作简单,性能较高
MyBatis
特点:
1. SQL语句与业务代码分开,职责分离,方便维护 2. 轻量级框架,易上手 3. 社区活跃、功能强大 4. 性能虽然不如Hibernate,也可以接受
- Mapping映射
概念:一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术
使用工Navicat的时候,能够直接看到表格的数据,但是如何在Java程序中操作数据库以及接收结果的呢?
- 使用实体类对象进行接收,表字段与实体类字段名称保持一致,一条数据对应一个实体类对象实例
对应关系:
Java | 数据库 |
---|---|
实体类 | 表 |
字段 | 字段/列 |
实例对象 | 记录/行 |
三、MyBatis基础应用
1.1. 创建SpringBoot项目
1.2 导入依赖(注意版本问题)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- 启动类需要:以前导入了一个web起步依赖,里面就有 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoottest -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 驱动包:连接mysql数据库的 - jdbc的实现 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- SpringBoot整合Mybatis:注意版本号要与springboot的版本号对应,否者Mapper代理对象无法创建 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<!-- lombok小辣椒 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
1.3. 数据准备
第一步:准备数据库表,在设置中改SQL Dialects,全部改成MySQL,不然写sql没有提示
第二步:在domian里面编写Student实体类,并提供Getter&Setter&toString方法。字段名称必须跟数据库表字段名称保持一致
1.4. 配置信息
第一步: IDEA中数据库客户端 (只需要填写四个参数就可以连接)
四个参数:
数据库驱动类名称 | 数据库连接URL | 数据库连接账号 | 数据库连接密码 |
---|---|---|---|
MySql8.0驱动:com.mysql.cj.jdbc.Driver | jdbc:mysql://localhost:3306/数据库名称 | 账号 | 密码 |
1.5 Yml配置
spring:
# 数据库连接四大参数
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis
username: root #直接打username就出来了
password: 123456
mybatis:
configurantion:
# Mybatis日志配置,输出到控制台 直接打log-impl
log-impl:org.apache.ibatis.logging.stdout.StdOutImpl
server
port:80 #端口号
1.6 代码开发
MyBatis的实现CRUD的方式分类:
- 注解方式(Java代码耦合,不方便维护,多表查询时不方便映射数据)
- XML映射文件方式
注解方式:
首先了解Mapper接口:
概念:Mapper接口就是Dao层接口,之前操作持久层需要建立接口以及实现类,但是在MyBatis框架下我们只需要创建接口即可,不需要实现类,因为Mybatis 提供了 Mapper接口的代理对象
首先要遵循以及了解以下规范---------->
1.1 Mybatis的持久层接口命名规范(第一步:在java.cn.zy下创建包):
- 包:mapper
- 类名:XxxMapper Xxx就是domain里面最后你想要映射回来的类名
1.2 @Mapper注解(第二步:在上面创建的mapper下创建创建一个跟domian中类名相同的接口,这里接口前面不加I 因为没有实现类XxxMapper)
作用:表示是MyBatis中的Mapper接口,程序运行时框架会自动生成接口的实现类对象(代理对象),并交给Spring的IOC容器管理,这样我们在使用持久层时就跟以前一样,注入即可使用
1.3 使用@Select、@Update、@Insert、@Delete四大注解(第三步:直接在CRUD注解后面写sql语句,select * from employee)
1.4 单元测试
直接使用SpringBoot测试类,因为其中有IOC容器,可以直接DI注入
第四步:
@Autowired // 先注入接口对象,这样才能够使用里面的方法
private EmployeeMapper employee;@test // 编写测试方式
public void findOne() throws Exception{
System.out.println(employee.findOne(1)); // 直接调用接口中的方法
}
XML映射文件方式 :
Mapper规范:
1. XML映射文件的名称与Mapper接口名称一样,并且将XML映射文件和Mapper接口放置在相同包下,保持同包同名
2. XML映射文件的namespace属性与Mapper接口全限定名保持一致
3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。一个标签对应Mapper接口一个方法
第一步:创建XML映射文件包,也就是在resources下右键—>new---->directory(文件夹),输入cn/zy/mapper(注意一定要用斜杠,这样创建的才是多级文件夹,否则用.创建的是一个文件夹)
第二步:在其中创建XML映射文件,右键new---->file(注意,文件名字要跟Mapper中的接口保持一致)
第三步:官网拷贝DTD约束文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
</mapper>
第四步:编写XML映射文件 copy reference可复制完全限定名 将mapper中的接口的完全限定名粘贴到namespace后面即可
namespace:命名空间,用来标识此SQL映射文件对应是那个Mapper接口,参数值是mapper接口的全限定名
id:映射文件中唯一,是SQL语句的唯一标识,与Mapper接口方法必须保持一致
resultType:此SQL的返回值类型,与Mapper接口方法的返回值类型必须保持一致,如果是List集合类型就是List集合的泛型,而不是集合类型
第五步:执行单元测试, 同注解
以上就基本能够完成功能,以下是拓展内容,但是也是经常需要的
1.7 新增返回主键ID
使用时机:某些情况下我们需要知道当前新增数据的主键Id是多少,那么此时我们可以通过配置开启主键返回得到我们的自增长主键Id。
第一步:映射文件中开启主键返回
- useGeneratedKeys:开启自增主键返回
- true:开启返回自增主键
- false:关闭返回自增主键,默认值
- keyProperty:此属性表示将Id返回到传递进来的对象的那个字段,一般我们都填写id字段
- keyColumn:此属性表示数据库中的那一列是主键,如果主键列在数据库表中是第一列,那么默认可以不写, 通常情况下我们在设计表时主键都是第一列,所以此属性可以不写
1.8 模糊查询
概念:模糊查询:通过一个字符或者多个字符去匹配某个字段值,叫做模糊查询,使用like关键字。要结合concat()。
concat(‘’,‘’,‘’):MySql中的拼接函数,可以在值的前后拼接指定值,我们利用这个函数帮助我们拼接前后百分号
select *from t_student where name like concat('%', #{name},'%') # #{}mybatis会将其解析为占位符,防止SQL注入
注意: #与$区别
使用#号
使用#时,Mybatis会将其解析为占位符?,并进行预编译防止SQL注入
- SQL语句:SELECT * FROM t_employee where name = #{name}
- 预编译语句为:SELECT * FROM t_employee where name = ? // 这里就是通过上方的#{name}解析而来,但是在传递进去数据的时候,又会自动加上一个单引号
在设置数据时,Mybatis会将数据自动加单引号 // 这是#号的特性
- 如果数据是数据库对象(表名,列名),就会造成语法错误
注意:在某些特殊场合下只能用KaTeX parse error: Expected 'EOF', got '#' at position 5: ,不能用#̲{}。当设置的数据是表名或列名…{},因为用#{}会自动加上单引号,表名这个字段名是不能加单引号的
使用$号
- 使用$设置数据时,本质上是字符串拼接。Mybatis会以字符串拼接的方式设置数据
- 例如:SELECT * FROM t_employee where name = name
- 如果我们传递的数据是字符串或时间类型的数据,需要手动添加单引号,避免语法错误
- 字符串拼接可能会造成SQL注入问题
sql注入
概念:不管我是否知道具体的条件,我都可以通过拼接OR 1= 1得到数据,这就是SQL注入
- name值为:'or ‘1’='1
- 代码中:SELECT * FROM t_student WHERE name = ${name}
- SQL语句为:SELECT * FROM t_student WHERE name = ‘name’
- 最终运行时:SELECT * FROM t_employee WHERE name = '‘or’1’=‘1’ 字符串 or true 就永远会满足
1.9 MyBatisX插件
概念:MybatisX是一款基于IDE 的快速开发插件,方便在使用MyBatis以及MyBatis-Plus开始时简化繁琐的重复操作,提高开发速率
优点:
- 节省大量持久层代码开发时间
- 强大的功能为业务编写提供各类支持
- 配置简单,告别各类复杂的配置文件
作用:
- XML跳转:Mapper接口方法与XML映射文件SQL语句之间快速定位
- 代码生成:可以根据数据库表生成Mapper接口、XML映射文件、Service层代码
- 自动生成映射方法
设置方式:settings—>Plugins—>Marketpalce—>search MybatisX
1.10 文件模板
作用:避免每次重复写一些代码,所以可以在idea中保存xml映射文件模板
设置方式:settings—>Editor—>File and Code Templates—> + —>Name=xxx extension=xxx
1.11 单元测试模板
设置方式:settings—>Editor—>Live Templates—>user—>test中修改 之前如果设置过就ok,没有就要点击+号新建
1.12 Lombok
概念:Lombok是一个实用的Java类库,可以通过简单的注解来简化和消除一些必须有但显得很臃肿的Java代码
作用:通过注解的形式自动生成构造器、Getter/Setter、Equals、HashCode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率
拓展:Lombok也称为小辣椒,因为图标是一个小辣椒
注解 | 作用 |
---|---|
@Getter/@Setter | 为所有的属性提供get/set方法 |
@ToString | 会给类自动生成易阅读的toString方法 |
@EqualsAndHashCode | 根据类所拥有的非静态字段自动重写Equals方法和HashCode方法 |
@Data | 提供了更综合的生成代码功能(@Getter+@Setter+@ToString+@EqualsAndHashCode) |
@NoArgsConstructor | 为实体类生成无参的构造器方法 |
@AllArgsConstructor | 为实体类生成除了static修饰的字段之外带有各参数的构造器方法 |
@Slf4j | 自动生成一个名为 log 的日志对象,用于在程序中输出日志信息 |
注意:如果是误删了,或者是旧版本,就去plugins里面下载
四. MyBatis动态标签
概念:动态SQL指的是SQL语句会随着参数的变化而发生变化,动态sql可以判断前端数据是否为null,为空就不拼接条件,不为空就拼接条件
- Query规范
概念:前端传的参数不确定,后端可以使用一个类去接收,然后在sql中判断是否为空即可。
格式:包名:query 类名:XxxQuery
- if标签
概念:if标签用于判断。通过test属性,我们可以判断某个参数是否为空,为空不拼接,不为空就拼接
注意:如果是字符串类型需要判断null以及空字符串,其他类型只需要判断null值即可
- where标签
用法:一般if标签会和where标签一起使用。
特点:
- 错误SQL:select * from t_student where
- 如果where标签中有一个条件成立,那么就会自动加上where关键字。如果一个都不成立就不会加上where关键字
- 会自动消除第一个多余的and或者or关键字
- 会自动调整格式,添加空格,不会出现关键字和数据贴在一起导致语法错误
课程总结
- JDBC是什么,用JDBC实现数据库操作有哪些问题?有好处吗? JDBC就是Java后端操作数据库的解决方案,代码太多耦合度高,不好维护,开发效率低 好处就是执行效率高
- Myabtis是什么?有什么优势? 是基于JDBC的一个半ORM的持久化框架 耦合度低,易维护,开发效率高
- Mybatis中Mapper规范有哪些?1.mapper映射文件中的namespace必须要=mapper接口的完全限定名 2.id要=mapper接口中的方法名 3.方法的返回值必须和resultType的值一致4.mapper映射文件中的Sql的paramterType必须跟对应的方法的类型相同.
- 添加时如何返回自增主键id值 useGenerateKeys:开启自增主键返回 keypropety:将id返回到传递进来的对象的那个字段 keycolumn 表示数据库的哪一列是主键
- #与KaTeX parse error: Expected 'EOF', got '#' at position 7: 区别 使用#̲时,Mybatis会将其解析为…设置数据时,本质上是字符串拼接
- lombok是什么,有什么好处 自动生成get/set以及Equals、HashCode、toString等方法
- MybaitsX是什么?有什么好处 节省开发时间
- 如何配置sql日志 在yml文件中写log-impl 后面输入个std
- 为什么需要动态sql 让sql语句随着参数的变化而变化,前端传过来的数据为null就不拼接,不为null就拼接 (如果不用动态sql,那么用户输入的东西都是不确定的,那么组合就会有太多,有了这个就只需要判断是否为参数为null)
相同.- 添加时如何返回自增主键id值 useGenerateKeys:开启自增主键返回 keypropety:将id返回到传递进来的对象的那个字段 keycolumn 表示数据库的哪一列是主键
- #与KaTeX parse error: Expected 'EOF', got '#' at position 7: 区别 使用#̲时,Mybatis会将其解析为…设置数据时,本质上是字符串拼接
- lombok是什么,有什么好处 自动生成get/set以及Equals、HashCode、toString等方法
- MybaitsX是什么?有什么好处 节省开发时间
- 如何配置sql日志 在yml文件中写log-impl 后面输入个std
- 为什么需要动态sql 让sql语句随着参数的变化而变化,前端传过来的数据为null就不拼接,不为null就拼接 (如果不用动态sql,那么用户输入的东西都是不确定的,那么组合就会有太多,有了这个就只需要判断是否为参数为null)
- Mybatis中有哪些动态sql,分别有什么用 if 判断参数是否为空 where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除 set用于动态包含需要更新的列,忽略其它不更新的列