Mybatis是啥?
是持久层架构,不是spring的,是spring集成的框架,主要就是对jdbc进行封装,让我们开发效率更高
Mybatis和JDBC的区别
原先我们使用java要访问数据库的时候,就需要使用jdbc去访问mysql,mybatis则是对jdbc进行封装,我们通过访问mybatis再去访问mysql。
如何创建mybatis项目

这里一定要导入mysql的驱动,不然你只是有这个框架没有地方去施展你的才能
修改配置文件

连接上数据库,这里的username和password自己写自己的密码
根据你需要查询的去创建对象
这里我以查询用户举例

创建好对应的mapper接口

记得要加上一个mapper注解
单元测试
在spring框架中自带的一个test类,需要导入依赖的

如何生成测试类
在你要测试的代码中右键生成test,选择你要测试的方法即可


这里有一个before和一个after,如果勾选了,代表的意思是在你的程序启动前执行的操作,以及在程序停止后的操作

@SpringbootTest,这个注解是告诉spring自动加载运行的环境
@Test注解说明这个是一个测试

测试成功,可以正常读取到数据库的内容
Mybatis基础操作(注解版)
配置打印的日志

这段需要写在yml配置文件中,告诉mybatis帮我们打印详细的日志
配置前

配置后

配置后会给出我们详细的信息,你的查询语句,参数类型,返回的结果
查


蓝色的是使用数组接收,红色的使用对象接收
这样写的话,就把里面的查询给写死了,没办法进行想要的查询,如何才能改进这个
参数绑定
绑定一个
使用#{ }进行绑定

注意点
这里需要注意一个点,因为我们这里只传输了一个参数,所以无论我们把#{ }里面写啥都会默认绑定我们需要的参数

我就算把这个对应的参数名字改成aaa他也照样可以识别到,因为只有这一个参数需要传递,就算你随便起名他也会自动绑定
传递多个参数

传递多个参数的时候,需要注意一个点,就是传参的过程需要注意对应上,因为这里有多个参数,所以如果像之前传递一个参数那样随意命名就会导致报错,这种是最推荐的写法,对应的关系清晰

报错的是找不到对应的参数
使用默认的参数名称

Param是默认参数的意思,mybatis会按照你传参的次序进行排序,但是我们一般不使用这种写法,含义不清晰并且前后顺序一旦打乱就会报错

不建议使用这种
参数的重命名
使用注解@param
可以把你不想要的换成你想要的名字,用的也少

注意点
当返回的查询条数为0-1则使用对象接收
当返回的查询条件为0-n则使用list接收(推荐)
当查询条数超过对象能接收的范围,就会报错

报错的信息为,只能接收一个但是却找到了好多个
流

常用的流

就是把数据变成流的形式,然后进行操作,第一个类似于foreach循环,第二个是筛选,第三个的查找第一个元素,这几个是比较常用的
查存在的问题
由于java和mysql的命名规则不一样,所以就会出现赋值失败的问题


如何解决
重命名法

使用mysql的as大法,就可以解决这个问题,但是这个实在是太麻烦了,如果下一个我还要写这么多
Results

这里有一个需要注意的点,results是一个数组,里面的内容需要使用{@result }存起来,这个results是kv形式的,可以对这个进行命名,之后如果需要使用只需要使用resultmap进行复用就可


这个方法也是比较麻烦的,我们可以观察一下命名规则的区别,无非就是一个蛇形一个驼峰,所以我们这里可以直接使用把蛇形变成驼峰不就结束了
蛇形变成驼峰
使用yml配置即可

允许驼峰自动转化,这样我们就不需要使用其他麻烦的注解和as了,直接搞定
效果和前面的完全一样,但是步骤比前面简单了太多
增
添加使用的注解是@insert,语法和mysql是一样的,记得进行参数绑定即可


传类的时候如果进行了重命名会怎么样

进行重命名之后,就相当于把这个类进行了套壳,这个时候mybatis无法识别到,所以要使用类.属性的方法

这里最主要的注意点就是这个好像披了一层衣服的param,需要使用类+属性
获取自增值
我们插入一条数据之后,之后获取到这个数据0或1,即这个数据插入成功与否,有时候我们需要获取到这个自增值(Id)用来做其他的事情,所以就需@Options的注解


这里有一个点需要注意的,当你起了别名之后,同样的在options中也要使用类名+属性才可以访问到对应的,否则就会一直为null
Options
useGeneratedKeys:获取到数据库的主键,默认是false,需要手动改成true
keyProperty:会把获取到的主键值设置到类中对应的属性,这里切记需要和类的名称完全一样,如果使用了别名就需要使用类+属性的方式去设置
删除

删除的逻辑很简答,使用注解@Delete即可,输入你要删除的就行
更新

更新的逻辑也是同样简单,只需要使用@Update的注解即可,需要注意的就是参数的绑定,在上面的查询过程已经讲过了,此处不做赘述
MyBatis基础操作(XML配置⽂件版)
- 添加依赖
- 配置数据库信息
- 定义接口
- 使用xml实现接口
添加依赖

需要告诉mybatis你的xml文件在哪里,这里需要注意的是这个位置必须是对应的,如果错了就会报错,**表示的是匹配的意思,如果去掉mapper只有**表示的是全部的xml文件

创建的xml文件必须对应实体类的路径,否则也会报错,这里需要注意的点是所有的xml文件开头的都是这样的

只需要把红色框内部的变成你自己对应的路径即可
查

XML文件中,需要注意的点就是所有的sql语句必须写在mapper之内,
Mapper namespace表示的是对应的实体类
Select id表示的是这个查询的名字
Resulttype表示的是这个查询之后返回的结构是啥
在select标签之内写的就是sql语句

这里需要加上一个Mapper注解让spring帮我管理,其余的和注解的方式差不多

Xml和类的对应关系

注意点:无论是注解还是xml都会出现字段名不匹配导致赋值为null,解决方式和注解一样,重命名,驼峰自动转换,resultmap映射
重命名法


这样就全部都不会为null
映射法

Resultmap id这个映射的名称
Type 要映射的类型
Result colum 数据库中的名称
Id column这个是你要查询的表的主键(推荐写)
Property 要改成的java中类的属性
如何使用,只需要在使用中加一个resultmap = 你起的名字就可以使用
驼峰自动转换
这个是最简单的,也是最推荐的写法

配置文件中写入这个即可
参数绑定



参数绑定和注解的方式是一样的使用#{ }即可,这里存在的问题也和注解可能存在的问题一样,当一个参数的时候,无论你写成啥名字,他都可以识别,如果多了的话,就需要手动绑定,否则就会报错
改



改这个也很简单,需要注意的点就是参数的绑定,其他的和注解一个样删
删



删除也是一样的简单,注意点依旧是参数的绑定
增



增加的语法也很简单,和注解的方式也是一样的,需要注意的点是sql语句切记不要写错
获取自增id

获取到自增的Id并赋值到id中,与注解同理
Mybatis对参数的赋值
#{ }与${ }
#{ },这个是一个预编译SQL
啥叫预编译SQL呢?
对传入的数据不使用拼接,使用?进行占位
传数字

可以看到我传入数据的时候,并不是简单的把我的数据进行拼接,而是先检查类型,确定类型之后把数据传入到占位符?中,这里#{}也是自动帮我们加了引号
传字符串

传字符串的时候,#{ }会帮我自动加引号,这里我们知道,字符串在mysql中是需要加""引起来的,这个就不会报错
${ }
${ },这个是一个及时SQL
啥叫及时SQL,说人话就是你写啥他就给你传入啥,不会帮你进行加引号
查Id

可以看到这个只是进行简单的拼接,把你传入的数据进行拼接就传输给数据库
传字符串

报错原因
首先我们知道mysql的语法,字符串必须使用引号包裹起来,因为这个及时编译只是简单的进行拼接,所以就没有加引号,所以就会报错
解决方案
手动加上引号即可

SQL注入问题
由于及时sql只是单纯的拼接,那么我只需要在传入的过程中传一些sql的关键字或者注释,就可以让sql同步执行我的其他代码

如果我再狠一点,我可以执行其他的指令,删库删表都是可以做到的
#{ }与${ }的区别
- $ { }性能更高,但是同时存在sql注入的问题
- #{ }更安全,不存在sql注入的问题
既然${ }存在sql注入的问题,那是不是就要被放弃掉不使用了呢?
还是有存在的意义的,比如排序和表名,字段名作为参数的时候
使用${ }解决排序问题

因为前面我们提到,使用#{}进行传输的过程,是会给我们默认添加引号的,而这里的排序,是不可以存在引号的,所以如果使用#就会报错,只有使用$才不会报错,这里需要注意一个点,这里也是存在sql注入风险的,但是由于这个输入我们一般不会提供给用户,所以就不会存在sql注入的问题
Like查询

同样的,这里依旧不可以#{ }进行操作,mybatis只会解析内部的参数名,不解析任何符号,同样会存在问题就是引号的问题只能使用$进行操作,但是这个又存在sql注入的风险,所以我们就采用sql内置的函数进行操作
Concat()
Sql的内置函数,用来查询模糊查询的

Sql注入也没有用,因为concat就相当于字符拼接,但是内部的核心是使用${}防止注入,所以还是无法注入成功的
总结
能使用#{}就不要使用${},减少sql注入的风险,
除非特定的场景,比如排序(不开放输入接口,只有默认asc或者desc)表名字段名作为参数可以使用(内部使用所以不存在sql注入)
Like查询的时候使用内部自带的concat函数,不使用${}减少sql注入的风险
数据库连接池
就和线程池一个样子,要用你就去拿,用完就要放回去,减小开销,资源可以重用

常见的数据库连接池
Druid
Hikari(Spring框架自带这个)
如果想要修改连接池成Druid,就修改一下配置即可,个人感觉hikari就够用了
Spring框架3.0

Spring框架2.0

注意点
MySQL中,数据库名,表名,字段名都是默认使用小写,如果是多个单词使用下划线连接
每个表都需要有Id,创建时间,更新时间
在查询的时候,少点使用*号,因为这个需要查询解析器去转义,效率就会低很多