# mybatis-plus-join
**Repository Path**: youlizhu/mybatis-plus-join
## Basic Information
- **Project Name**: mybatis-plus-join
- **Description**: mybatis-plus的多表插件完全按照mybats plus的用法来做,支持一对一返回映射,多对多返回映射,自定义返回Vo,自定义表别名,自定义查询字段,你只要会mp,那你就会用mpj,无感引入,不会对之前的业务产生一点点影响,采用扩展方式来集成mp,更容易适配版本,后期mp版本升级,您不用更改东西,只需要更新版本就行(目前支持大部分主流版本 )
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 58
- **Created**: 2022-10-18
- **Last Updated**: 2022-10-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# mybatis-plus-join
mybatis-plus-join是mybatis plus的一个多表插件,上手简单,十分钟不到就能学会全部使用方式,只要会用mp就会用这个插件,仅仅依赖了lombok,而且是扩展mp的构造器并非更改原本的构造器,不会对原有项目产生一点点影响,相信大多数项目都有这俩插件,四舍五入就是没依赖。
mybatis-plus-join示例:
> gitee: https://gitee.com/mhb0409/mybatis-plus-join-example
> github: https://github.com/bobo667/mybatis-plus-join-example
### 关于该插件的一点问题
1. 出现了bug怎么办,不是mybatis plus官方的会不会不稳定啊? 这个大可以放心,这个插件我已经在生产环境跑了半年多了,没出过什么问题,如果遇到问题可以在 Issues 上提出,我看见就会解决,上午提的,不忙的话下午就能打包新版本,忙的话大概就需要晚上就差不多了
2. 关于维护到啥时候?mybatis plus不倒我不倒(当然,如果长期没有star,哪怕是我得先倒了,还是那,您的star就是作者更新的动力,手动ღ( ´・ᴗ・` )比心)
3. 有什么有想法的新功能啊,或者改善啊,可以在Issues 上提出
4. 如果想联系作者,可以在wx上搜索小程序 马汇博的博客在关于我中有微信号,欢迎来扰
**目前支持大部分mp常用版本**
maven坐标
mybatis plus:3.2.0版本依赖地址:
```xml
icu.mhb
mybatis-plus-join
1.2.0
```
最新版本依赖地址:
```xml
icu.mhb
mybatis-plus-join
1.1.3
```
## 版本对应关系(此处只显示对应的最新版本)
> 标注:*号代表,从起始版本之后都是可以使用的
| Mybatis-plus | Mybatis-plus-join |
| ------------ | ------------------------------------------------------------ |
| 3.2.0 | 1.2.0 |
| 3.3.1 - 3.42 | 1.0.2 |
| 3.4.3.4 - * | 1.0.3 、1.0.4、1.0.5、1.0.6、1.0.8、1.0.9、1.1.1、1.1.2、1.1.3 |
## 版本日志
### 1.0.1 版本
1.初始化项目 mybatis-plus-join项目诞生
### 1.0.2 版本
1.优化了selectAs()方法,支持函数简洁式写法
2.增加了缓存优化性能
### 1.0.3 版本
1.支持3.4.3.4版本
2.增加根据传入实体不为空的数据查询
3.优化了代码逻辑
4.增加notDefaultSelectAll() 不默认查询主表全部的字段
### 1.0.4 版本
1.支持查询单个参数时候返回单个参数,例如List String
2.优化转换类型的方式
### 1.0.5 版本
1.修复在没有条件下order 排序失效的问题
### 1.0.6 版本
1.修复实体条件为主键ID的时候没有加别名问题
2.增加返回值支持一对一查询
### 1.0.8 版本
1. 增加了多对多映射
2. 去掉了fastJSON依赖
3. 更改serviceImpl动态返回类型的处理方式,采用更优的插件式注入方式
这次终于去掉了总是说的fastJSON依赖,现在采用动态注入resultMap方式,来构建普通多表,一对一,多对多查询,采用插件式懒加载 + 缓存机制,启动时间无影响,使用加载一下就可以直接从缓存调用,保证不影响使用中的效率。
### 1.0.9 版本
1. 更改默认表、字段别名关键字As 为 空格
2. 增加自定义表、字段别名关键字,在不同数据库中兼容
### 1.1.1 版本
1. 修复在添加逻辑删除的时候SQL报错问题
2. 返回类型支持Map类型
3. 增加主表和子表自定义别名,方便多个相同子表对应一个主表
这次更新解决了目前使用的一些特殊场景下的缺陷问题,使用的更灵活了
### 1.1.2 版本
1. 修复逻辑删除没有加别名的问题
2. 修复多个连表情况下,只查询主表的逻辑删除的问题
3. 修复在定义typeHandler不生效的问题
这次更新主要是修复的bug版本,目前作者没有什么特别多的思路去要写什么样的新功能,如果各位有可以提出来
### 1.1.3 版本
1. 更改逻辑删除出现的条件为join后,而不是where后
2. Merge pull request !2 from f_ms/N/A
3. Merge pull request !1 from f_ms/N/A
这次更新主要是修复的bug版本,目前作者没有什么特别多的思路去要写什么样的新功能,如果各位有可以提出来
### 其他版本
#### 1.2.0 版本
1.支持了3.2.0 版本
废话不多说,直接看怎么使用
```java
/**
* 查询列表
*
* @param wrapper 实体对象封装操作类
* @param 返回泛型(如果只查询一个字段可以传递String Int之类的类型)
* @return 返回E 类型的列表
*/
List joinList(Wrapper wrapper, Class clz);
/**
* 查询单个对象
*
* @param wrapper 实体对象封装操作类
* @param clz 返回对象 (如果只查询一个字段可以传递String Int之类的类型)
* @param 包装泛型类型
* @param 返回类型泛型
* @return EV
*/
EV joinGetOne(Wrapper wrapper, Class clz);
/**
* 查询count
*
* @param wrapper 实体对象封装操作类
* @param 返回泛型
* @return 总数
*/
int joinCount(Wrapper wrapper);
/**
* 翻页查询
*
* @param page 翻页对象
* @param wrapper 实体对象封装操作类
*/
, C> IPage joinPage(E page, Wrapper wrapper, Class clz);
```
一共是四个方法,分别重写于mp的
`joinList -> list `
`joinGetOne -> getOne`
`joinCount -> count`
`joinPage -> page`
**注意:这几个方法,前面俩参数和mp的用法一致,最后一个class类型的是返回类型,这个主要是大多数多表操作都是需要有额外字段,所以需要额外定义,而Wrapper wrapper中的这个需要填写在需要构建条件的实体,这个实体是任意的,不强制,创建条件构造器的时候定义的那个对象就是主表**
## 基本使用方法
1.mapper继承 JoinBaseMapper< T>
2.service继承 JoinIService< T>
3.impl 继承 JoinServiceImpl
4.注入mp自定义方法,主要是继承JoinDefaultSqlInjector
```java
package icu.mhb.mpj.example.config;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import icu.mhb.mybatisplus.plugln.injector.JoinDefaultSqlInjector;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class MyBatisPlusConfig extends JoinDefaultSqlInjector {
@Override
public List getMethodList(Class> mapperClass) {
List methodList = super.getMethodList(mapperClass);
// 自己的自定义方法
return methodList;
}
}
```
然后就可以愉快的使用了
## 自定义查询字段和表别名关键字
```java
// 为何要这个东西,因为在不同数据库之间,别名关键字不一样,例如Mysql表别名是 As 而oracle中 是 is 关键字所以需要
// 以oracle 关键字为例
// 解释一下为什么要这样声明,因为注入器在启动的时候就进行初始化,所以这个构建需要在初始化之前,最简单的办法就是在注入MybatisPlusPropertiesCustomizer的地方进行实例化
@Bean
public MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() {
MybatisPlusJoinConfig.builder()
// 查询字段别名关键字
.columnAliasKeyword("as")
// 表、left join、right join、inner join 表别名关键字
.tableAliasKeyword("is")
.build();
return MybatisPlusProperties::getGlobalConfig;
}
// 运行的SQL
SELECT 1 as id
FROM users is users
LEFT JOIN users_age is users_age
ON users_age.id = users.age_id
```
下面来看构造器的使用:
```java
// 第一步new 一个JoinLambdaWrapper构造参数是主表的实体对象(如果在service中直接使用joinLambdaWrapper()方法即可获得)
JoinLambdaWrapper wrapper = new JoinLambdaWrapper<>(Users.class);
// 第二步 使用leftJoin方法创建一个左连接
/*
有三个方法可以使用
leftJoin 左联
rightJoin 右联
innerJoin 内联
*/
// 这一部分一个参数是join中定义的连接的表,第二个参数是随意的表,但是是要出现构造器中的
wrapper.leftJoin(UsersAge.class,UsersAge::getId,Users::getAgeId);
// 然后可以设置多表中的查询条件,这一步和mp一致
wrapper.eq(UserAge::getAgeName,"95")
.select(UserAge::getAgeName)
// 最后一步 需要使用end方法结束
.end();
// 完整的就是
JoinLambdaWrapper wrapper = new JoinLambdaWrapper<>(Users.class);
wrapper.leftJoin(UsersAge.class,UsersAge::getId,Users::getAgeId)
.eq(UserAge::getAgeName,"95")
.select(UserAge::getAgeName)
.end();
usersService.joinList(wrapper,UsersVo.class);
// 执行SQL
select
users.user_id,
users.user_name,
users_age.age_name
from users users
left join users_age users_age on users_age.id = users.age_id
where (
users_age.age_name = '95'
)
```
是不是就很简单,就和mp的原生的比,就是增加了 join方法啥的
## 加料用法
OK,来点丝滑的加料用法
### 自定义别名和返回map类型
```java
// 两个参数代表自定义别名
JoinLambdaWrapper wrapper = joinLambdaQueryWrapper(Users.class, "userMaster");
wrapper
.select(Users::getUserId, Users::getUserName)
// leftJoin innerJoin rightJoin 三个参数代表使用默认别名,四个参数代表使用自定义别名
.leftJoin(UsersAge.class, UsersAge::getId, Users::getAgeId, "u_age")
.select(UsersAge::getAgeDoc).end()
.leftJoin(UsersAge.class, UsersAge::getId, Users::getAgeId, "u_a")
.select(UsersAge::getAgeName).end();
// 需要注意的是当返回参数为map的时候是没有下划线转驼峰的,如果需要请自行配置mybatis的下划线转驼峰
List