1、什么是mybatis,为什么要使用它?
2、特点
Mybatis:
a、支持自定义SQL、存储过程、及高级映射
b、实现自动对SQL的参数设置
c、实现自动对结果集进行解析和封装
d、通过XML或者注解进行配置和映射,大大减少代码量
e、数据源的连接信息通过配置文件进行配置
3、和jdbc及hibernate进行对比
可以发现,MyBatis是对JDBC进行了简单的封装,帮助用户进行SQL参数的自动设置,以及结果集与Java对象的自动映射。与Hibernate相比,配置更加简单、灵活、执行效率高。但是正因为此,所以没有实现完全自动化,需要手写SQL,这是优点也是缺点。
4、如果你是公司研发人员你会如何做选择?
对性能要求较高的电商类项目,一般会使用MyBatis,而对与业务逻辑复杂,不太在乎执行效率的传统行业,一般会使用Hibernate
5、整体架构
6、mybatis-config.xml配置
mybatis-config.xml讲究严格的顺序,具体顺序遵循文档的顺序
7、properties属性读取外部资源
添加jdbc.properties资源文件:
在Mybatis-config.xml中引入jdbc.properties资源文件:
8、typeAliases
之前咱们在映射文件中用到java类型时,都是使用类的全路径,书写起来非常麻烦
解决方案:
类型别名是为 Java 类型命名的一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
9、Mappers
既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。
10、resource
在mybatis-config.xml引入项目目录下的映射文件:
缺点很大:
a、硬盘位置可能随着项目的部署或迁移,路径发生变化,不方便维护
b、每新增一个映射文件,就要在全局配置文件中引入
解决方法:
在mybatis-config.xml配置mapper接口的全路径
这种配置方式,在全局配置文件中配置了mapper接口的全路径,并没有配置mapper接口的映射文件的位置。如果要让mybatis找到对应的映射文件,则必须满足一定的条件或规则:
a、映射文件和mapper接口在同一个目录下
b、文件名必须一致
c、映射文件的namespace必须和mapper接口的全路径保持一致
目录结构如下:
11、mybatis-config.xml开启包扫描
我们发现,我们每添加一个mapper.java就要在配置中添加一条信息,不利于维护。
解决方案:
有利必有弊,如果包的路径有很多,显得很杂;mapper.xml和mapper.java没有分离
12、CRUD标签
a、select
b、insert
c、update
d、delete
13、parameterType传入参数(常用)
CRUD标签都有一个属性parameterType,statement通过它指定接收的参数类型。
接收参数的方式有两种:
a、#{}预编译
b、${}非预编译(直接的sql拼接,不能防止sql注入)
参数类型有三种:
a、基本数据类型
b、HashMap(使用方式和pojo类似)
c、Pojo自定义包装类型
a、#{}预编译
b、${}非预编译(直接的sql拼接,不能防止sql注入)
应用场景:
在UserMapper接口中,添加根据表名查询用户信息的方法:
在UserMapper映射文件中,添加方法对应的statement:
输出(报错):
如果你要动态传入的字段名是表名,并且sql执行是预编译的(预编译:就是?,看不到的数据),这显然是不行的,所以你必须改成非预编译的,也就是这样:
使用${} 去接收参数信息,在一个参数时,默认情况下必须使用${value}获取参数值,
而#{} 只是表示占位,与参数的名字无关,如果只有一个参数,可以使用任意参数名接收参数值,会自动对应。
但是这并不是一种稳妥的解决方案,推荐使用@Param注解指定参数名,所以以上接口及映射文件可以改成如下:
一个参数时,在使用#{}传参时,可以通过任意参数名接收参数;而${},默认必须通过value来接收参数
详细可以参考:https://jingyan.baidu.com/article/0320e2c110ded71b87507b35.html
14、实现一个简单的用户登录,根据username和password验证用户信息(这里是多个参数)
在UserMapper接口中,添加登陆方法:
在接口方法中的参数前,添加@Param注解指定参数名:
通常在方法的参数列表上加上一个注解@Param(“xxxx”) 表示参数的名字,然后通过${“xxxx”}或#{“xxxx”}获取参数。
总结:
单个参数时,#{}与参数名无关的。
多个参数时,#{} ${}与参数名(@Param)有关。
什么时候需要加@Param注解?什么时候不加?
单个参数不加,多个参数加
终极解决方案:都加。
15、面试题(#、$区别)
16、resultMap
在UserMapper.xml中配置resultMap:
在UserMapper.xml中使用resultMap:
在使用mybatis进行数据库连接操作时对于SQL语句返回结果的处理通常有两种方式,一种就是resultType另一种就是resultMap。
<select>标签中resultMap根据<resultMap>标签中的id找到对应的type类型,相当于resultType直接写类的类型,resultMap会自动
映射单表查询的结果集。
17、HashMap
parameterType有三种类型的输入参数:
- 基本数据类型
- hashMap
- pojo包装类
前面已经使用了基本数据类型和pojo类型的参数,那么hashMap这种类型的参数怎么传递参数呢?
其实,它的使用方式和pojo有点类似,简单类型通过#{key}或者${key},复杂类型通过${key.属性名}或者#{key.属性名}
UserMapper接口方法:
UserMapper配置文件:
测试用例:
18、动态sql
a、if
案例:查询男性用户,如果输入了用户名,按用户名模糊查询
在UserMapper接口中定义方法:
在UserMapper映射文件中,定义接口方法对应的Statement
在UserMapperTest测试类中,添加测试用例
b、choose when otherwise
案例:查询男性用户,如果输入了用户名则按照用户名模糊查找,否则如果输入了年龄则按照年龄查找,否则查找用户名为“zhangsan”的用户。
在UserMapper接口中,定义接口方法:
在UserMapper.xml中,定义接口方法对应的Statement
在UserMapperTest测试类中,添加测试用例
c、where
案例:查询所有用户,如果输入了用户名按照用户名进行模糊查询,如果输入年龄,按照年龄进行查询,如果两者都输入,两个条件都要成立
在UserMapper接口中,定义接口方法:
在UserMapper.xml中,定义接口方法对应的Statement
在UserMapperTest测试类中,添加测试用例
d、foreach
案例:按照多个id查询用户信息
在UserMapper.xml中,定义接口方法对应的Statement
在UserMapperTest测试类中,添加测试用例
总结:
If 判断 test-判断条件,OGNL表达式
Choose when(判断,test,一旦有一个when成立,后续不再执行) otherwise(所有的when都不成立,才会执行)
Where:添加where关键字,去掉动态sql之前多余的一个and|or
Set:添加set关键字,去掉动态sql之后多余的一个逗号
Foreach:collection-接收集合 item-遍历其中一个元素 separator-分割符 open-以什么开始 close-以什么结束。
19、mybatis中的resultType和resultMap我该如何做选择,这里一幅图来告诉大家如何选择
a、resultType是自动映射,通过给到的类(这里我举例是User),自动将查询出来的数据(键值对),映射到对应的类的属性名及属性值上
b、resultMap自定义映射,属性通过column标签来指定表与实体类之间的对应关系,通过<resultMap>标签中的id找到对应的类
下面更详细的解释