mybatis从入门到精通 源码_Mybatis框架从入门到精通(四)

94ebd4f8a42a892a3c98966aceed5bc4.png

☞Mybatis框架从入门到精通视频实战教程☜

>>>学习交流群< < <

一、Mapper代理

前面已经使用MyBatis完成了对Emp表的CRUD操作,都是由SqlSession调用自身方法发送SQL命令并得到结果的,实现了MyBatis的入门。

但是却存在如下缺点:

  1. 不管是selectList()、selectOne()、selectMap(),都只能提供一个查询参数。如果要多个参数,需要封装到JavaBean中,并不一定永远是一个好办法。
  2. 返回值类型较为固定
  3. 只提供了映射文件,没有提供数据库操作的接口,不利于后期的维护扩展。

在MyBatis中提供了另外一种成为Mapper代理(或称为接口绑定)的操作方式。在实际开发中也使用该方式。下面我们就是要Mapper代理的方式来实现对Emp表的CRUD操作吧,还有完成多个参数传递、模糊查询、分页查询、自增主键回填等更多的技能实现。搭建好的项目框架如图所示,相比而言,增加了接口EmployeeMapper。但是却会引起映射文件和测试类的变化。

e6c6c73a229ce8143fcb44764f94b6f5.png

1.1 使用Mapper代理方式实现查询

  • 首先定义接口EmployeeMapper。
public 
  • 定义映射文件EmployeeMapper.xml,要求映射文件必须和接口名相同。
  • 在映射文件中进行配置
<mapper 

注意

  1. 使用Mapper代理方式,namespace必须是接口的全路径名。
  2. 使用Mapper代理方式,select等映射标签的id必须是接口中方法的名字。
  3. 使用#{},底层使用PreparedStatement;而是要${},底层使用Statement了,会有SQL注入风险,不建议使用。
  • 测试类完成对数据库的相关操作
public 

注意:此时对数据库的操作不是由SqlSession发起,不是调用selectList()、selectOne()等方法,而是由EmployeeMapper接口发起,直接调用接口的方法,更容易理解。

EmployeeMapper 

这条语句的底层使用了动态代理模式,动态创建一个EmployeeMapper的一个代理对象并赋给接口引用。所以在MyBatis中不需要显式提供Mapper接口的实现类,这也是简单的地方。

d2e70cfa2c248880fced348f12e293e9.png

关于动态代理设计模式的原理,在Spring中详细讲解。

1.2 使用sql元素重用数据库字段列表

在映射文件中,可以使用sql标签定义SQL语句的一部分,方便SQL语句来引用。

比如最典型的就是数据库表的列名,通常情况下要在select、insert语句中来反复编写,此时就可以使用sql元素编写一次,就可以多次引用了。

引用时要使用include元素来完成。可以看到避免了重复书写,也便于后期修改维护。

<mapper 

二、更多的映射

下面继续使用Mapper代理方式完成更多更复杂的数据库操作,涉及多个参数传递、模糊查询、分页查询、自增主键回填等内容。

2.1 多参数传递

在EmployeeMapper接口中定义方法实现同时按照job、deptno两个字段完成信息查询。可以有四种方式来实现。分别为:

  • 方式1:直接传递多个参数

映射文件中,参数可以使用param1,param2...表示,或者使用arg0,arg1...表 示,可读性低。

  • 方式2:使用Param注解传递多个参数

映射文件中参数可以使用Param注解指定的名称来表示,同时保留使用param1, param2...表示,但是不可以再使用arg0,arg1...表示

  • 方式3:使用JavaBean传递多个参数

映射文件中的参数直接使用JavaBean的属性来接收,可读性高。底层调用是相应 属性的getter方法。

  • 方式4:使用Map传递多个参数

映射文件中使用相应参数在map中的key来表示。

public 

因为映射文件元素的id要保持唯一,所以Mapper接口不允许存在重载的方法。

在映射文件完成SQL语句的编写,关键是参数的接收。

<mapper 

在测试类中完成SQL语句的调用和结果输出,这就没有难度了吧。

public 

总结:

  1. 使用Map方式导致了业务可读性的丧失,导致了后续扩展和维护的困难,应该果断放弃使用。
  2. 直接传递多个参数,会导致映射文件中可读性降低,从可读性考虑,也不推荐使用。
  3. 如果参数数量<=5个,推荐使用Param注解方式,因为更直观。
  4. 如果参数数量>5个,推荐使用JavaBean方式。
  5. 如果涉及到多个JavaBean的参数,可以同时使用Param注解进行标记

2.2 模糊查询

在进行模糊查询时,在映射文件中可以使用concat()函数来连接参数和通配符。另外注意对于特殊字符,比如<,不能直接书写,应该使用字符实体替换。

public 
<mapper 

2.3 分页参数

MyBatis不仅提供分页,还内置了一个专门处理分页的类RowBounds,其实就是一个简单的实体类。其中有两个成员变量:

  • offset:偏移量,从0开始计数
  • limit:限制条数

在映射文件中不需要接收RowBounds的任何信息,MyBatis会自动识别并据此完成分页 。从控制台显示的SQL日志中发现,SQL语句中也没有引入分页。这说明是MyBatis先查询出所有符合条件的数据,再根据偏移量和限制条数筛选指定内容。所有仅适用小数据量情况,对于大数据的情况,请自己编写分页类来实现。后续分页专题专门说明。

public 
<select 

测试类代码:

RowBounds 

2.4 自增主键回填

MySQL支持主键自增。有时候完成添加后需要立刻获取刚刚自增的主键,由下一个操作来使用。比如结算购物车后,主订单的主键确定后,需要作为后续订单明细项的外键存在。如何拿到主键呢,MyBatis提供了支持,可以非常简单的获取。

<insert 
  • useGeneratedKeys:表示要使用自增的主键
  • keyProperty:表示把自增的主键赋给JavaBean的哪个成员变量。

以添加Employee对象为例,添加前Employee对象的empno是空的,添加完毕后可以通过getEmpno() 获取自增的主键。

<insert 
  • order:取值AFTER|BEFORE,表示在新增之后|之前执行<selectKey>中的SQL命令
  • keyProperty:执行select @@identity后结果填充到哪个属性中
  • resultType:结果类型。

技术扩展

在很多应用场景中需要新增数据后获取到新增数据的主键值,针对这样的需求一般由三种解决方式:

  • 主键自定义,用户通过UUID或时间戳等方式生成唯一主键,把这个值当做主键值。在分布式场景中应用较多。
  • 查询后通过select max(主键) from 表获取主键最大值。这种方式在多线程访问情况下可能出现问题。
  • 查询后通过select @@identity获取最新生成主键。要求这条SQL必须在insert操作之后,且数据库连接没有关闭。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值