# je-ibatis
**Repository Path**: wangscript/je-ibatis
## Basic Information
- **Project Name**: je-ibatis
- **Description**: JECloud和JEPaaS特色mybatis中间件
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: jecloud
- **Homepage**: https://jecloud.net
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 37
- **Created**: 2023-07-27
- **Last Updated**: 2023-07-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# JEIbatis项目
## 项目简介
JEIbatis项目,用于为其他应用服务提供基础持久层统一处理能力,使开发人员摆脱繁杂的实体和Mapper编写工作,提高服务的开发速度。
## 环境依赖
* jdk1.8
* maven
* 请使用官方仓库(http://maven.jepaas.com),暂不同步jar到中央仓库。
> Maven安装 (http://maven.apache.org/download.cgi)
> Maven学习,请参考[maven-基础](docs/mannual/maven-基础.md)
# 主要目标
- 支持平台元数据:提供MetaDataParse接口,默认使用JdbcTemplate查询数据库获取资源表和功能信息,支持自定义元数据解析器(详见配置)
- 主键策略拓展:在mybatis现有自增主键、查询主键的基础上,增加路由主键,插入数据时动态路由到资源表对应的主键策略。
- 元数据标签:提供<meta/>标签,可在mybatis的xml中使用,通过方法参数中的TableCode与标签type属性(update|insert|select|columns|pk-col|load|load-columns),动态生成sql。
- 条件解析器:增加ConditionsWrapper实现条件封装,支持自定义sql与复杂条件语句嵌套。
- 元数据CRUD:基于上述拓展,封装MetaBaseMapper,使用MetaStatementBuilder解析。继承MetaBaseMapper即可使用基础方法
- 分页插件:拓展MyBatis插件,支持多数据库方言,支持拓展。
## 项目依赖
- mybatis
- mybatis-spring
- spring-beans
- spring-context
- spring-jdbc
## 开源协议
- [MIT](./LICENSE)
- [平台证书补充协议](./SUPPLEMENTAL_LICENSE.md)
## JECloud主目录
[JECloud 微服务架构低代码平台(点击了解更多)](https://gitee.com/ketr/jecloud.git)
## Spring-MVC 配置
```xml
```
## ConditionsWrapper 条件构造器
说明:
- 以下方法须按照正常sql语法顺序调用!,列如 orderBy 一定要最后调用
- 以下出现的第一个入参`boolean condition`表示该条件**是否**加入sql中
- 以下代码块内的多个方法均为从上往下补全个别`boolean`类型的入参,默认为`true`
- 以下出现的泛型`Param`均为`ConditionsWrapper`的实例
- 以下方法在入参中出现的`R`为泛型,在ConditionsWrapper中是`String`
- 以下方法入参中的`R column`均表示数据库字段
- 以下举例均为使用普通wrapper,入参为`Map`和`List`的均以`json`形式表现!
### allEq
``` java{3}
allEq(Map params)
allEq(Map params, boolean null2IsNull)
allEq(boolean condition, Map params, boolean null2IsNull)
```
- 全部[eq](#eq)(或个别[isNull](#isnull))
个别参数说明:
`params` : `key`为数据库字段名,`value`为字段值
`null2IsNull` : 为`true`则在`map`的`value`为`null`时调用 [isNull](#isnull) 方法,为`false`时则忽略`value`为`null`的
- 例1: `allEq({id:1,name:"老王",age:null})`--->`id = 1 and name = '老王' and age is null`
- 例2: `allEq({id:1,name:"老王",age:null}, false)`--->`id = 1 and name = '老王'`
``` java{3}
allEq(BiPredicate filter, Map params)
allEq(BiPredicate filter, Map params, boolean null2IsNull)
allEq(boolean condition, BiPredicate filter, Map params, boolean null2IsNull)
```
个别参数说明:
`filter` : 过滤函数,是否允许字段传入比对条件中
`params` 与 `null2IsNull` : 同上
- 例1: `allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null})`--->`name = '老王' and age is null`
- 例2: `allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null}, false)`--->`name = '老王'`
### eq
``` java{2}
eq(R column, Object val)
eq(boolean condition, R column, Object val)
```
- 等于 =
- 例: `eq("name", "老王")`--->`name = '老王'`
### ne
``` java{2}
ne(R column, Object val)
ne(boolean condition, R column, Object val)
```
- 不等于 <>
- 例: `ne("name", "老王")`--->`name <> '老王'`
### gt
``` java{2}
gt(R column, Object val)
gt(boolean condition, R column, Object val)
```
- 大于 >
- 例: `gt("age", 18)`--->`age > 18`
### ge
``` java{2}
ge(R column, Object val)
ge(boolean condition, R column, Object val)
```
- 大于等于 >=
- 例: `ge("age", 18)`--->`age >= 18`
### lt
``` java{2}
lt(R column, Object val)
lt(boolean condition, R column, Object val)
```
- 小于 <
- 例: `lt("age", 18)`--->`age < 18`
### le
``` java{2}
le(R column, Object val)
le(boolean condition, R column, Object val)
```
- 小于等于 <=
- 例: `le("age", 18)`--->`age <= 18`
### between
``` java{2}
between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)
```
- BETWEEN 值1 AND 值2
- 例: `between("age", 18, 30)`--->`age between 18 and 30`
### notBetween
``` java{2}
notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
```
- NOT BETWEEN 值1 AND 值2
- 例: `notBetween("age", 18, 30)`--->`age not between 18 and 30`
### like
``` java{2}
like(R column, Object val)
like(boolean condition, R column, Object val)
```
- LIKE '%值%'
- 例: `like("name", "王")`--->`name like '%王%'`
### notLike
``` java{2}
notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
```
- NOT LIKE '%值%'
- 例: `notLike("name", "王")`--->`name not like '%王%'`
### likeLeft
``` java{2}
likeLeft(R column, Object val)
likeLeft(boolean condition, R column, Object val)
```
- LIKE '%值'
- 例: `likeLeft("name", "王")`--->`name like '%王'`
### likeRight
``` java{2}
likeRight(R column, Object val)
likeRight(boolean condition, R column, Object val)
```
- LIKE '值%'
- 例: `likeRight("name", "王")`--->`name like '王%'`
### isNull
``` java{2}
isNull(R column)
isNull(boolean condition, R column)
```
- 字段 IS NULL
- 例: `isNull("name")`--->`name is null`
### isNotNull
``` java{2}
isNotNull(R column)
isNotNull(boolean condition, R column)
```
- 字段 IS NOT NULL
- 例: `isNotNull("name")`--->`name is not null`
### in
``` java{2}
in(R column, Collection> value)
in(boolean condition, R column, Collection> value)
```
- 字段 IN (value.get(0), value.get(1), ...)
- 例: `in("age",[1,2,3])`--->`age in (1,2,3)`
- 例: `in("age",[])`--->`age in (null)`
``` java{2}
in(R column, Object... values)
in(boolean condition, R column, Object... values)
```
- 字段 IN (v0, v1, ...)
- 例: `in("age", 1, 2, 3)`--->`age in (1,2,3)`
### notIn
``` java{2}
notIn(R column, Collection> value)
notIn(boolean condition, R column, Collection> value)
```
- 字段 IN (value.get(0), value.get(1), ...)
- 例: `notIn("age",[1,2,3])`--->`age not in (1,2,3)`
``` java{2}
notIn(R column, Object... values)
notIn(boolean condition, R column, Object... values)
```
- 字段 NOT IN (v0, v1, ...)
- 例: `notIn("age", 1, 2, 3)`--->`age not in (1,2,3)`
### inSql
``` java{2}
inSql(R column, String inValue)
inSql(boolean condition, R column, String inValue)
```
- 字段 IN ( sql语句 )
- 例: `inSql("age", "1,2,3,4,5,6")`--->`age in (1,2,3,4,5,6)`
- 例: `inSql("id", "select id from table where id < 3")`--->`id in (select id from table where id < 3)`
### notInSql
``` java{2}
notInSql(R column, String inValue)
notInSql(boolean condition, R column, String inValue)
```
- 字段 NOT IN ( sql语句 )
- 例: `notInSql("age", "1,2,3,4,5,6")`--->`age not in (1,2,3,4,5,6)`
- 例: `notInSql("id", "select id from table where id < 3")`--->`age not in (select id from table where id < 3)`
### groupBy
``` java{2}
groupBy(R... columns)
groupBy(boolean condition, R... columns)
```
- 分组:GROUP BY 字段, ...
- 例: `groupBy("id", "name")`--->`group by id,name`
### orderByAsc
``` java{2}
orderByAsc(R... columns)
orderByAsc(boolean condition, R... columns)
```
- 排序:ORDER BY 字段, ... ASC
- 例: `orderByAsc("id", "name")`--->`order by id ASC,name ASC`
### orderByDesc
``` java{2}
orderByDesc(R... columns)
orderByDesc(boolean condition, R... columns)
```
- 排序:ORDER BY 字段, ... DESC
- 例: `orderByDesc("id", "name")`--->`order by id DESC,name DESC`
### orderBy
``` java{1}
orderBy(boolean condition, boolean isAsc, R... columns)
```
- 排序:ORDER BY 字段, ...
- 例: `orderBy(true, true, "id", "name")`--->`order by id ASC,name ASC`
### or
``` java{2}
or()
or(boolean condition)
```
- 拼接 OR
注意事项:
主动调用`or`表示紧接着下一个**方法**不是用`and`连接!(不调用`or`则默认为使用`and`连接)
- 例: `eq("id",1).or().eq("name","老王")`--->`id = 1 or name = '老王'`
``` java{2}
or(Consumer consumer)
or(boolean condition, Consumer consumer)
```
- OR 嵌套
- 例: `or(i -> i.eq("name", "李白").ne("status", "活着"))`--->`or (name = '李白' and status <> '活着')`
### and
``` java{2}
and(Consumer consumer)
and(boolean condition, Consumer consumer)
```
- AND 嵌套
- 例: `and(i -> i.eq("name", "李白").ne("status", "活着"))`--->`and (name = '李白' and status <> '活着')`
### nested
``` java{2}
nested(Consumer consumer)
nested(boolean condition, Consumer consumer)
```
- 正常嵌套 不带 AND 或者 OR
- 例: `nested(i -> i.eq("name", "李白").ne("status", "活着"))`--->`(name = '李白' and status <> '活着')`
### exists
``` java{2}
exists(String existsSql)
exists(boolean condition, String existsSql)
```
- 拼接 EXISTS ( sql语句 )
- 例: `exists("select id from table where age = 1")`--->`exists (select id from table where age = 1)`
### notExists
``` java{2}
notExists(String notExistsSql)
notExists(boolean condition, String notExistsSql)
```
- 拼接 NOT EXISTS ( sql语句 )
- 例: `notExists("select id from table where age = 1")`--->`not exists (select id from table where age = 1)`
### apply
``` java{2}
apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)
```
- 拼接 sql
注意事项:
- 动态入参`params`对应前面`applySql`内部的`{index}`部分.使用预处理方式,不会有sql注入风险的!
- 此方法会保留原有sql,不会对sql字符串进行增删操作。
- 可变参中不可包含数组,如有in语句预处理参数应使用List或Set(见示例)。
######
- 例: `apply("id = 1")`--->`id = 1`
- 例: `apply("id in ({0})", Lists.newArrayList(1,2,3))`--->`and id in(1,2,3)`
- 例: `apply("name like {0}", "jay%")`--->`name like 'jay%'`
- 例: `apply("name like {0}", "%jay%")`--->`name like '%jay%'`
- 例: `apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")`--->`date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")`
- 例: `apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")`--->`date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")`
# MetaBaseMapper 平台基础CRUD封装
说明:
- 以下出现的变量`mapper`均为`MetaBaseMapper`子接口的Mapper实例
- 以下出现的变量`tableCode`均为平台资源表名称
- 以下出现的变量`pkValue`均为主键
- 以下出现的变量`wrapper`均为`ConditionsWrapper`实例
### 继承 MetaBaseMapper
``` java
@Mapper
public interface MetaMapper extends MetaBaseMapper {
}
```
### 注入 MetaBaseMapper 子接口实例
``` java
@Autowired
private MetaMapper baseDataMapper;
```
### insertMap
- 平台资源表基础插入方法,须指定 tableCode
``` java
int insertMap(Map beanMap)
```
- 示例
``` java
Map beanMap = new HashMap<>();
beanMap.put(Constants.KEY_TABLE_CODE, tableCode);
// 如果插入前未指定主键值,则会使用自动生成主键策略
// beanMap.put("ID", "1");
beanMap.put("CODE", "编号");
beanMap.put("NAME", "名称");
// 插入数据
mapper.insertMap(beanMap);
// 主键为自动生成时,插入后会将主键值放入Map
Object pkValue = beanMap.get("ID");
```
### updateMap
- 平台资源表基础修改方法,须指定 tableCode
``` java
int updateMap(@Param(Constants.MAP_ALIAS) Map beanMap, @Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper)
```
- 示例
``` java
Map beanMap = new HashMap<>();
beanMap.put(Constants.KEY_TABLE_CODE, tableCode);
beanMap.put("CODE", "编号01");
beanMap.put("NAME", "名称01");
// 如果wrapper为空时,使用主键作为where条件
beanMap.put(Constants.KEY_PK_VALUE, pkValue);
//update语句的where条件
ConditionsWrapper wrapper = ConditionsWrapper.builder().apply("CODE = '编号' and NAME = '名称'");
mapper.updateMap(beanMap, wrapper);
```
### select
- 平台资源表基础查询方法,查询资源表全部字段,须指定 tableCode
``` java
List