1 Star 0 Fork 33

白云飞 / je-ibatis

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

JEIbatis项目

项目简介

JEIbatis项目,用于为其他应用服务提供基础持久层统一处理能力,使开发人员摆脱繁杂的实体和Mapper编写工作,提高服务的开发速度。

环境依赖

Maven安装 (http://maven.apache.org/download.cgi)

Maven学习,请参考maven-基础

主要目标

  • 支持平台元数据:提供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

开源协议

JECloud主目录

JECloud 微服务架构低代码平台(点击了解更多)

Spring-MVC 配置

<!-- Mybatis SessionFactory-->
<bean id="sqlSessionFactory" class="com.je.ibatis.SqlSessionFactoryBean">
   <property name="dataSource" ref="dataSource" />
   <property name="configurationProperties" >
       <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
           <!-- mybatis配置文件 -->
           <property name="locations" value="classpath*:mybatis.properties"/>
       </bean>
   </property>
   <!-- 元数据解析器 实现 MetaDataParse 接口 -->
   <property name="metaDataParse">
       <bean class="com.je.ibatis.extension.parse.DefaultMetaDataParse"/>
   </property>
   <!-- 元数据缓存管理 实现 MetaDataCacheManager 接口-->
   <property name="cacheManager">
       <bean class="com.je.cache.service.ibatis.SaaSMetaDataCacheManager"/>
   </property>
   <property name="plugins">
       <array>
           <!-- 分页插件配置 -->
           <bean id="paginationInterceptor" class="com.je.ibatis.extension.plugins.PaginationInterceptor"/>
       </array>
   </property>
</bean>
<!-- MapperScanner 扫描Mapper 创建代理 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
   <property name="basePackage" value="com.je.**.mapper" />
   <property name="annotationClass" value="org.apache.ibatis.annotations.Mapper" />
</bean>

ConditionsWrapper 条件构造器

说明:

  • 以下方法须按照正常sql语法顺序调用!,列如 orderBy 一定要最后调用
  • 以下出现的第一个入参boolean condition表示该条件是否加入sql中
  • 以下代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true
  • 以下出现的泛型Param均为ConditionsWrapper的实例
  • 以下方法在入参中出现的R为泛型,在ConditionsWrapper中是String
  • 以下方法入参中的R column均表示数据库字段
  • 以下举例均为使用普通wrapper,入参为MapList的均以json形式表现!

allEq

allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
  • 全部eq(或个别isNull) 个别参数说明: params : key为数据库字段名,value为字段值
    null2IsNull : 为true则在mapvaluenull时调用 isNull 方法,为false时则忽略valuenull

  • 例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 = '老王'

allEq(BiPredicate<R, V> filter, Map<R, V> params)
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) 

个别参数说明: filter : 过滤函数,是否允许字段传入比对条件中
paramsnull2IsNull : 同上

  • 例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

eq(R column, Object val)
eq(boolean condition, R column, Object val)
  • 等于 =
  • 例: eq("name", "老王")--->name = '老王'

ne

ne(R column, Object val)
ne(boolean condition, R column, Object val)
  • 不等于 <>
  • 例: ne("name", "老王")--->name <> '老王'

gt

gt(R column, Object val)
gt(boolean condition, R column, Object val)
  • 大于 >
  • 例: gt("age", 18)--->age > 18

ge

ge(R column, Object val)
ge(boolean condition, R column, Object val)
  • 大于等于 >=
  • 例: ge("age", 18)--->age >= 18

lt

lt(R column, Object val)
lt(boolean condition, R column, Object val)
  • 小于 <
  • 例: lt("age", 18)--->age < 18

le

le(R column, Object val)
le(boolean condition, R column, Object val)
  • 小于等于 <=
  • 例: le("age", 18)--->age <= 18

between

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

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

like(R column, Object val)
like(boolean condition, R column, Object val)
  • LIKE '%值%'
  • 例: like("name", "王")--->name like '%王%'

notLike

notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
  • NOT LIKE '%值%'
  • 例: notLike("name", "王")--->name not like '%王%'

likeLeft

likeLeft(R column, Object val)
likeLeft(boolean condition, R column, Object val)
  • LIKE '%值'
  • 例: likeLeft("name", "王")--->name like '%王'

likeRight

likeRight(R column, Object val)
likeRight(boolean condition, R column, Object val)
  • LIKE '值%'
  • 例: likeRight("name", "王")--->name like '王%'

isNull

isNull(R column)
isNull(boolean condition, R column)
  • 字段 IS NULL
  • 例: isNull("name")--->name is null

isNotNull

isNotNull(R column)
isNotNull(boolean condition, R column)
  • 字段 IS NOT NULL
  • 例: isNotNull("name")--->name is not null

in

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)
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

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)
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

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

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

groupBy(R... columns)
groupBy(boolean condition, R... columns)
  • 分组:GROUP BY 字段, ...
  • 例: groupBy("id", "name")--->group by id,name

orderByAsc

orderByAsc(R... columns)
orderByAsc(boolean condition, R... columns)
  • 排序:ORDER BY 字段, ... ASC
  • 例: orderByAsc("id", "name")--->order by id ASC,name ASC

orderByDesc

orderByDesc(R... columns)
orderByDesc(boolean condition, R... columns)
  • 排序:ORDER BY 字段, ... DESC
  • 例: orderByDesc("id", "name")--->order by id DESC,name DESC

orderBy

orderBy(boolean condition, boolean isAsc, R... columns)
  • 排序:ORDER BY 字段, ...
  • 例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC

or

or()
or(boolean condition)
  • 拼接 OR 注意事项: 主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)

  • 例: eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王'

or(Consumer<Param> consumer)
or(boolean condition, Consumer<Param> consumer)
  • OR 嵌套
  • 例: or(i -> i.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')

and

and(Consumer<Param> consumer)
and(boolean condition, Consumer<Param> consumer)
  • AND 嵌套
  • 例: and(i -> i.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')

nested

nested(Consumer<Param> consumer)
nested(boolean condition, Consumer<Param> consumer)
  • 正常嵌套 不带 AND 或者 OR
  • 例: nested(i -> i.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')

exists

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

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

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

@Mapper
public interface MetaMapper extends MetaBaseMapper {
}

注入 MetaBaseMapper 子接口实例

@Autowired
private MetaMapper baseDataMapper;

insertMap

  • 平台资源表基础插入方法,须指定 tableCode
int insertMap(Map<String, Object> beanMap)
  • 示例
Map<String, Object> 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
int updateMap(@Param(Constants.MAP_ALIAS) Map<String, Object> beanMap, @Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper)
  • 示例
Map<String, Object> 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
List<Map<String, Object>> select(@Param(Constants.PAGE_ALIAS) Page page, @Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper);
  • 示例
//页编码 current = -1 时不分页
int current = 1;
//每页数量
int size = 30;
Page page = new Page(current, size);
//select语句的where条件
ConditionsWrapper wrapper = ConditionsWrapper.builder()
    //指定tableCode
    .table(tableCode)
    //添加where条件
    .apply("CODE = '编号' and NAME = '名称'")
    .apply(" ORDER BY CODE ");
//wrapper作为where条件语句时不能以AND开头, 可调用 wrapper.getSql()进行调试。
List<Map<String, Object>> list = mapper.select(page, wrapper);

load

  • 平台功能基础查询方法,只查询功能列表加载字段,须指定 funcCode 功能编码
List<Map<String, Object>> load(@Param(Constants.PAGE_ALIAS) Page page, @Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper);
  • 示例
//页编码 current = -1 时不分页
int current = 1;
//每页数量
int size = 30;
Page page = new Page(current, size);
//select语句的where条件
ConditionsWrapper wrapper = ConditionsWrapper.builder()
    //指定funcCode
    .function(funcCode)
    //添加where条件
    .apply("CODE = '编号' and NAME = '名称'")
    .apply(" ORDER BY CODE ");
//wrapper作为where条件语句时不能以AND开头, 可调用 wrapper.getSql()进行调试。
List<Map<String, Object>> list = mapper.load(page, wrapper);

selectOneByPk

  • 根据主键查询,须指定 tableCode pkValue
Map<String, Object> selectOneByPk(@Param(Constants.KEY_TABLE_CODE) String tableCode, @Param(Constants.KEY_PK_VALUE) String pkValue);
  • 示例
//使用表名与主键查询,查询资源表所有列
Map<String, Object> map = mapper.selectOneByPk(tableCode, pkValue);

delete

  • 平台资源表基础删除方法
int delete(@Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper);
  • 示例
//delete语句的where条件
ConditionsWrapper wrapper = ConditionsWrapper.builder()
    //指定tableCode
    .table(tableCode)
    //添加where条件
    .apply("CODE = '编号' and NAME = '名称'")
    .apply(" ORDER BY CODE ");
//wrapper作为where条件语句时不能以AND开头, 可调用 wrapper.getSql()进行调试。
int num = mapper.delete(wrapper);

selectSql

  • 自定义Sql查询
List<Map<String, Object>> selectSql(@Param(Constants.PAGE_ALIAS) Page page, @Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper);
  • 示例
//页编码 current = -1 时不分页
int current = 1;
//每页数量
int size = 30;
Page page = new Page(current, size);
//wrapper为完整select语句
ConditionsWrapper wrapper = ConditionsWrapper.builder()
    .apply("select * from USER where ")
    //添加where条件
    .eq("CODE", "编号")
    .apply(" and NAME = {0}", "名称")
    .apply(" ORDER BY CODE ");
List<Map<String, Object>> list = mapper.selectSql(page, wrapper);

insertSql

  • 执行新增sql
int insertSql(@Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper);
  • 示例
//wrapper为完整语句
ConditionsWrapper wrapper = ConditionsWrapper.builder()
    .apply("INSERT INTO USER (CODE, NAME) VALUES ({0}, {1})", "编号", "名称");
int num = mapper.insertSql(wrapper);

updateSql

  • 执行更新sql
int updateSql(@Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper);
  • 示例
//wrapper为完整语句
ConditionsWrapper wrapper = ConditionsWrapper.builder()
    .apply("UPDATE USER SET AGE = {0} WHERE CODE = {1} ", 18, "Wang");
int num = mapper.updateSql(wrapper);

deleteSql

  • 执行删除sql
int deleteSql(@Param(Constants.WRAPPER_ALIAS) ConditionsWrapper wrapper);
  • 示例
//wrapper为完整语句
ConditionsWrapper wrapper = ConditionsWrapper.builder()
    .apply("DELETE FROM USER WHERE CODE = {0} ", "Wilson");
int num = mapper.deleteSql(wrapper);
MIT License Copyright (c) 2023 北京凯特伟业科技有限公司 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

JECloud和JEPaaS特色mybatis中间件 展开 收起
Java
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/byfjl/je-ibatis.git
git@gitee.com:byfjl/je-ibatis.git
byfjl
je-ibatis
je-ibatis
jecloud

搜索帮助