一、快速入门
1、使用MybatisPlus基本步骤
- 引入maven依赖,代替Mybatis依赖
- 让自定义的Mapper接口继承MyabtisPlus提供的父类
BaseMapper<T>
,其中T
是该表对应的实体类 - 在service层中直接调用SQL方法
2、MybatisPlus的优点
- 对mybatis没有侵入性,只增强不改造
- MyabtisPlus提供的父类
BaseMapper<T>
中包含大量常用的单表CRUD语句,Mapper接口继承后可以直接调用这些方法,不需要再使用xml文件或者@select注释来配置SQL语句,提高开发速度
3、常用注解
mybatisplus利用反射可以通过实体类来获得实体类中的字段信息,并能够自动将驼峰命名法与sql命名法进行互相转化
如果实体类中的字段名不符合驼峰命名法或无法转化,则可通过注释进行手动转化:
- @TableName:用来指定表名
- @TableId:用来指定表中主键的名称
- @TableField:用来指定表中普通键的名称
exist = false
用来表示该字段在表中不存在
type = IdType.AUTO
表示该键为自增长
4、常用配置
mp继承了mybatis一些原生的配置,也有自己独有的一些配置
为什么需要xml文件地址?不是不用xml配置sql语句吗?
mp只擅长进行简单的单表查询,如果涉及到多表查询或者复杂sql语句,用mybatis的xml文件会风方便
二、核心功能
1、条件构造器
条件构造器 Wrapper是Mp提供的一个类,用于构造sql语句的条件。它允许开发者以链式调用的方式构造 SQL 的 WHERE 子句,提供了极大的灵活性和便利性。
-
AbstractWrapper:这是一个抽象基类,提供了所有 Wrapper 类共有的方法和属性。它定义了条件构造的基本逻辑,包括字段(column)、值(value)、操作符(condition)等。所有的 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper 都继承自 AbstractWrapper。
-
QueryWrapper:专门用于构造查询条件,支持基本的等于、不等于、大于、小于等各种常见操作。它允许你以链式调用的方式添加多个查询条件,并且可以组合使用
and
和or
逻辑。 -
UpdateWrapper:用于构造更新条件,可以在更新数据时指定条件。与 QueryWrapper 类似,它也支持链式调用和逻辑组合。使用 UpdateWrapper 可以在不创建实体对象的情况下,直接设置更新字段和条件。
即不掉用mapper层,直接执行sql命令
例:查询名字带o的,存款大于1000的用户的id、姓名、信息、存款
select id, name, info, balance from user where name like '%o%' and balance > 1000
//构造查询条件 QueryWrapper<User> wrapper = new QueryWrapper<User>() .select("id","name","info","balance") .like("username","o") .ge("balance",1000); //ge表示大于 //以该条件为参数,调用Mapper进行查询,用User列表接受多个返回值 List<User> users = userMapper.selectList(wrapper);
查询
2、自定义SQL
条件构造器Wrapper能够负责编写where
这一部分,其他部分(例如limit
,group by
)需要自己编写
在某些场景下,构造Wrapper时会显式的使用SQL语句,而Wrapper位于Service层,不符合开发规范
例:把id为1、2、4的用户的余额减去200
其中
setsql()
部分直接使用了balance = balance -200
我们希望:利用mp方便构造where
的优势,并把构造的条件向下传递到mapper层,再到mapper层中编写完整的sql语句,以满足开发规范
使用自定义SQL优化代码:
-
使用Wrapper构造条件,后面不再使用
setsql()
-
在mapper层中自定义函数,并且以wapper为参数接收查询条件
构造自定义函数时,参数前必须加
@Param
注解,且wrapper的参数名必须设置为ew
-
自定义sql语句,调用传递下来的wapper条件
可以在xml文件中写sql,也可以直接在
@update
注解上写 -
在service层中调用自定义函数
3、IService接口
mp提供的IService接口与BaseMapper类似,都提供了大量的基础sql语句,继承之后可以直接使用,节省开发时间
继承IService时的问题
对于自定义的Service接口:UserService
来说,同时要有一个实现类UserServiceImp
;UserService
继承了IService
接口后,UserServiceI
需要实现IService
接口中大量的sql语句,否则编译不通过。为了方便开发,mp提供了IService的实现类ServiceImp
,只需让UserServiceImp
继承ServiceImp
实现类,即可继承这些方法的实现。
继承语法
UserServiceImp继承IServiceImp时,泛型需要指定相关数据表的实体类User以操作该表的Mapper接口:UserMapper
因为IService中的所有sql方法都是通过调用Mappper层来实现的,而不是自己再写一遍
比较Service和数据库交互的两种方式
- 直接在
UserService
中通过@Autowired
注入Mapper
对象
当您在UserService
接口的实现类中直接通过@Autowired
注入Mapper
对象时,您实际上是在服务层直接依赖了数据访问层(DAO或Mapper层)。这种方式的好处是直接、明确,您可以在服务层的方法中直接调用Mapper
的方法来执行数据库操作。
-
优点:
- 直接性:您可以清晰地看到服务层是如何调用数据库层的。
- 灵活性:在服务层中,您可以自由地组合多个
Mapper
的方法来实现复杂的业务逻辑。
-
缺点:
- 耦合度较高:服务层直接依赖于具体的
Mapper
实现,这可能会增加代码之间的耦合度。 - 难以复用:如果多个服务需要执行类似的数据库操作,您可能会发现自己在多个地方重复编写类似的代码。
- 耦合度较高:服务层直接依赖于具体的
- 让
UserService
继承IService
后使用IService
中的方法
当您让UserService
继承IService
(通常是通过实现IService
接口,因为IService
是一个接口,而不是一个类)并使用IService
中定义的方法时,您实际上是在遵循一种更为抽象和可复用的设计。在 MyBatis-Plus 中,IService
往往是一个预定义的接口,它包含了一系列常用的数据库操作方法,而ServiceImpl
则是这个接口的一个实现,它内部使用了BaseMapper
来执行实际的数据库操作。
-
优点:
- 抽象性:
IService
提供了数据库操作的抽象,使得服务层可以更加关注于业务逻辑的实现。 - 复用性:如果多个服务需要执行相似的数据库操作,您可以通过实现
IService
接口来复用这些操作。 - 耦合度低:服务层不直接依赖于具体的
Mapper
实现,而是通过IService
接口与数据库层进行交互,这有助于降低代码之间的耦合度。
- 抽象性:
-
缺点:
- 灵活性受限:由于
IService
提供了预定义的数据库操作方法,您可能无法在服务层中直接执行一些非常特定的数据库操作(除非您扩展了IService
接口并提供了相应的实现)。 - 需要额外实现:虽然 MyBatis-Plus 提供了
ServiceImpl
作为IService
的一个实现,但在某些情况下,您可能需要根据自己的需求来扩展或重写这些方法。
- 灵活性受限:由于
总结
选择哪种方式主要取决于您的项目需求、代码风格以及个人偏好。如果您的项目比较简单,或者您更喜欢直接控制数据库操作,那么直接在服务层中注入Mapper
对象可能是一个不错的选择。但如果您希望代码更加抽象、可复用,并且愿意遵循 MyBatis-Plus 提供的设计模式,那么让服务层实现IService
接口并使用其提供的方法可能是更好的选择。