支持 solon 启动插件模块结构扩展包
This commit is contained in:
parent
0995140b94
commit
ea714cf111
4
.kotlin/errors/errors-1726886507129.log
Normal file
4
.kotlin/errors/errors-1726886507129.log
Normal file
@ -0,0 +1,4 @@
|
||||
kotlin version: 2.0.20
|
||||
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
|
||||
1. Kotlin compile daemon is ready
|
||||
|
@ -0,0 +1,5 @@
|
||||
|
||||
- opt: 优化代码生成器支持可视化配置生产能力
|
||||
- opt: 解构扩展包不再强制依赖 spring 开发框架
|
||||
- feat: 重构 service 模块抽象为 CrudRepository 不再建议使用 IService 避免业务层数据混乱
|
||||
- feat: 新增 solon 启动插件支持
|
@ -1,4 +1,4 @@
|
||||
APP_VERSION=3.5.8
|
||||
APP_VERSION=3.5.9
|
||||
APP_GROUP=com.baomidou
|
||||
signing.keyId=1FD337F9
|
||||
signing.password=243194995
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.baomidou.mybatisplus.test.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.test.entity.AEntity;
|
||||
import com.baomidou.mybatisplus.test.entity.BEntity;
|
||||
|
||||
public interface BMapper extends BaseMapper<BEntity> {
|
||||
|
@ -6,12 +6,9 @@ compileKotlin{
|
||||
|
||||
dependencies {
|
||||
api project(":mybatis-plus-core")
|
||||
implementation "${lib."mybatis-spring"}"
|
||||
|
||||
implementation "${lib."kotlin-stdlib-jdk8"}"
|
||||
implementation "${lib."kotlin-reflect"}"
|
||||
implementation "${lib."spring-context-support"}"
|
||||
implementation "${lib."spring-jdbc"}"
|
||||
implementation "${lib."slf4j-api"}"
|
||||
implementation "${lib."p6spy"}"
|
||||
implementation "${lib."jackson"}"
|
||||
|
@ -21,11 +21,10 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||
import com.baomidou.mybatisplus.extension.compatible.CompatibleHelper;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
@ -43,11 +42,11 @@ import java.util.Objects;
|
||||
* @author hubin
|
||||
* @since 2016-11-06
|
||||
*/
|
||||
public abstract class Model<T extends Model<?>> implements Serializable {
|
||||
public abstract class AbstractModel<T extends AbstractModel<?>> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final transient Class<?> entityClass = this.getClass();
|
||||
protected final transient Class<?> entityClass = this.getClass();
|
||||
|
||||
/**
|
||||
* 插入(字段选择插入)
|
||||
@ -237,13 +236,6 @@ public abstract class Model<T extends Model<?>> implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行 SQL
|
||||
*/
|
||||
public SqlRunner sql() {
|
||||
return new SqlRunner(this.entityClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Session 默认自动提交
|
||||
*/
|
||||
@ -284,6 +276,6 @@ public abstract class Model<T extends Model<?>> implements Serializable {
|
||||
* @param sqlSession session
|
||||
*/
|
||||
protected void closeSqlSession(SqlSession sqlSession) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(this.entityClass));
|
||||
CompatibleHelper.getCompatibleSet().closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(this.entityClass));
|
||||
}
|
||||
}
|
@ -17,17 +17,13 @@ package com.baomidou.mybatisplus.extension.ddl;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.extension.ddl.history.IDdlGenerator;
|
||||
import com.baomidou.mybatisplus.extension.ddl.history.MysqlDdlGenerator;
|
||||
import com.baomidou.mybatisplus.extension.ddl.history.OracleDdlGenerator;
|
||||
import com.baomidou.mybatisplus.extension.ddl.history.PostgreDdlGenerator;
|
||||
import com.baomidou.mybatisplus.extension.ddl.history.SQLiteDdlGenerator;
|
||||
import com.baomidou.mybatisplus.extension.compatible.CompatibleHelper;
|
||||
import com.baomidou.mybatisplus.extension.ddl.history.*;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.io.Resources;
|
||||
import org.apache.ibatis.jdbc.ScriptRunner;
|
||||
import org.apache.ibatis.jdbc.SqlRunner;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.*;
|
||||
@ -126,7 +122,7 @@ public class DdlHelper {
|
||||
}
|
||||
|
||||
public static InputStream getInputStream(String path) throws Exception {
|
||||
return new ClassPathResource(path).getInputStream();
|
||||
return CompatibleHelper.getCompatibleSet().getInputStream(path);
|
||||
}
|
||||
|
||||
protected static String getNowTime() {
|
||||
|
@ -0,0 +1,128 @@
|
||||
package com.baomidou.mybatisplus.extension.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
|
||||
import com.baomidou.mybatisplus.core.toolkit.MybatisUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class AbstractRepository<M extends BaseMapper<T>, T> implements IRepository<T> {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
* @see #getEntityClass()
|
||||
*/
|
||||
private Class<T> entityClass;
|
||||
|
||||
@Override
|
||||
public Class<T> getEntityClass() {
|
||||
if(this.entityClass == null) {
|
||||
this.entityClass = (Class<T>) GenericTypeUtils.resolveTypeArguments(this.getMapperClass(), BaseMapper.class)[0];
|
||||
}
|
||||
return this.entityClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getMapperClass()
|
||||
*/
|
||||
private Class<M> mapperClass;
|
||||
|
||||
private volatile SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
protected SqlSessionFactory getSqlSessionFactory() {
|
||||
if (this.sqlSessionFactory == null) {
|
||||
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this.getBaseMapper());
|
||||
this.sqlSessionFactory = MybatisUtils.getSqlSessionFactory(mybatisMapperProxy);
|
||||
}
|
||||
return this.sqlSessionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return baseMapper 真实类型
|
||||
* @since 3.5.7
|
||||
*/
|
||||
public Class<M> getMapperClass() {
|
||||
if (this.mapperClass == null) {
|
||||
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this.getBaseMapper());
|
||||
this.mapperClass = (Class<M>) mybatisMapperProxy.getMapperInterface();
|
||||
}
|
||||
return this.mapperClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* TableId 注解存在更新记录,否插入一条记录
|
||||
*
|
||||
* @param entity 实体对象
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean saveOrUpdate(T entity) {
|
||||
return getBaseMapper().insertOrUpdate(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return getBaseMapper().selectOne(queryWrapper, throwEx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<T> getOneOpt(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return Optional.ofNullable(getBaseMapper().selectOne(queryWrapper, throwEx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
|
||||
return SqlHelper.getObject(log, getBaseMapper().selectMaps(queryWrapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
|
||||
return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行批量操作
|
||||
*
|
||||
* @param list 数据集合
|
||||
* @param batchSize 批量大小
|
||||
* @param consumer 执行方法
|
||||
* @param <E> 泛型
|
||||
* @return 操作结果
|
||||
* @since 3.3.1
|
||||
*/
|
||||
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
|
||||
return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, list, batchSize, consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行批量操作(默认批次提交数量{@link IRepository#DEFAULT_BATCH_SIZE})
|
||||
*
|
||||
* @param list 数据集合
|
||||
* @param consumer 执行方法
|
||||
* @param <E> 泛型
|
||||
* @return 操作结果
|
||||
* @since 3.3.1
|
||||
*/
|
||||
protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) {
|
||||
return executeBatch(list, DEFAULT_BATCH_SIZE, consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeById(Serializable id, boolean useFill) {
|
||||
return SqlHelper.retBool(getBaseMapper().deleteById(id, useFill));
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +1,4 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.service;
|
||||
package com.baomidou.mybatisplus.extension.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
@ -22,30 +7,21 @@ import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.ChainQuery;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.update.ChainUpdate;
|
||||
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.kotlin.KtQueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.kotlin.KtUpdateChainWrapper;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 顶级 Service
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
public interface IService<T> {
|
||||
public interface IRepository<T> {
|
||||
|
||||
/**
|
||||
* 默认批次提交数量
|
||||
@ -61,16 +37,6 @@ public interface IService<T> {
|
||||
return SqlHelper.retBool(getBaseMapper().insert(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入(批量)
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean saveBatch(Collection<T> entityList) {
|
||||
return saveBatch(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入(批量)
|
||||
*
|
||||
@ -79,16 +45,6 @@ public interface IService<T> {
|
||||
*/
|
||||
boolean saveBatch(Collection<T> entityList, int batchSize);
|
||||
|
||||
/**
|
||||
* 批量修改插入
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean saveOrUpdateBatch(Collection<T> entityList) {
|
||||
return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改插入
|
||||
*
|
||||
@ -174,59 +130,6 @@ public interface IService<T> {
|
||||
return SqlHelper.retBool(getBaseMapper().deleteByIds(list, useFill));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除(jdbc批量提交)
|
||||
*
|
||||
* @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
|
||||
* @return 删除结果
|
||||
* @since 3.5.0
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean removeBatchByIds(Collection<?> list) {
|
||||
return removeBatchByIds(list, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除(jdbc批量提交)
|
||||
*
|
||||
* @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
|
||||
* @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
|
||||
* @return 删除结果
|
||||
* @since 3.5.0
|
||||
*/
|
||||
default boolean removeBatchByIds(Collection<?> list, boolean useFill) {
|
||||
return removeBatchByIds(list, DEFAULT_BATCH_SIZE, useFill);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除(jdbc批量提交)
|
||||
*
|
||||
* @param list 主键ID或实体列表
|
||||
* @param batchSize 批次大小
|
||||
* @return 删除结果
|
||||
* @since 3.5.0
|
||||
* @deprecated 3.5.7 {@link #removeBatchByIds(Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean removeBatchByIds(Collection<?> list, int batchSize) {
|
||||
throw new UnsupportedOperationException("不支持的方法!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除(jdbc批量提交)
|
||||
*
|
||||
* @param list 主键ID或实体列表
|
||||
* @param batchSize 批次大小
|
||||
* @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
|
||||
* @return 删除结果
|
||||
* @since 3.5.0
|
||||
* @deprecated 3.5.7 {@link #removeBatchByIds(Collection)}
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean removeBatchByIds(Collection<?> list, int batchSize, boolean useFill) {
|
||||
throw new UnsupportedOperationException("不支持的方法!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 选择修改
|
||||
*
|
||||
@ -256,16 +159,6 @@ public interface IService<T> {
|
||||
return SqlHelper.retBool(getBaseMapper().update(entity, updateWrapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID 批量更新
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean updateBatchById(Collection<T> entityList) {
|
||||
return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID 批量更新
|
||||
*
|
||||
@ -570,20 +463,24 @@ public interface IService<T> {
|
||||
*/
|
||||
Class<T> getEntityClass();
|
||||
|
||||
/**
|
||||
/*
|
||||
* 以下的方法使用介绍:
|
||||
*
|
||||
* <p>
|
||||
* 一. 名称介绍
|
||||
* 1. 方法名带有 query 的为对数据的查询操作, 方法名带有 update 的为对数据的修改操作
|
||||
* 2. 方法名带有 lambda 的为内部方法入参 column 支持函数式的
|
||||
* </p>
|
||||
* <p>
|
||||
* 二. 支持介绍
|
||||
*
|
||||
* 1. 方法名带有 query 的支持以 {@link ChainQuery} 内部的方法名结尾进行数据查询操作
|
||||
* 2. 方法名带有 update 的支持以 {@link ChainUpdate} 内部的方法名为结尾进行数据修改操作
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* 三. 使用示例,只用不带 lambda 的方法各展示一个例子,其他类推
|
||||
* 1. 根据条件获取一条数据: `query().eq("column", value).one()`
|
||||
* 2. 根据条件删除一条数据: `update().eq("column", value).remove()`
|
||||
* </p>
|
||||
*
|
||||
*/
|
||||
|
||||
@ -655,23 +552,4 @@ public interface IService<T> {
|
||||
default LambdaUpdateChainWrapper<T> lambdaUpdate() {
|
||||
return ChainWrappers.lambdaUpdateChain(getBaseMapper());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
|
||||
* 此次修改主要是减少了此项业务代码的代码量(存在性验证之后的saveOrUpdate操作)
|
||||
* </p>
|
||||
* <p>
|
||||
* 该方法不推荐在多线程并发下使用,并发可能存在间隙锁的问题,可以采用先查询后判断是否更新或保存。
|
||||
* </p>
|
||||
* <p>
|
||||
* 该方法存在安全隐患将在后续大版本删除
|
||||
* </p>
|
||||
*
|
||||
* @param entity 实体对象
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {
|
||||
return update(entity, updateWrapper) || saveOrUpdate(entity);
|
||||
}
|
||||
}
|
@ -1,310 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
|
||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
import org.apache.ibatis.binding.MapperMethod;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
|
||||
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@Autowired
|
||||
protected M baseMapper;
|
||||
|
||||
@Override
|
||||
public M getBaseMapper() {
|
||||
Assert.notNull(this.baseMapper, "baseMapper can not be null");
|
||||
return this.baseMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getEntityClass()
|
||||
*/
|
||||
private Class<T> entityClass;
|
||||
|
||||
@Override
|
||||
public Class<T> getEntityClass() {
|
||||
if(this.entityClass == null) {
|
||||
this.entityClass = (Class<T>) GenericTypeUtils.resolveTypeArguments(this.getMapperClass(), BaseMapper.class)[0];
|
||||
}
|
||||
return this.entityClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #currentMapperClass()
|
||||
*/
|
||||
private Class<M> mapperClass;
|
||||
|
||||
private volatile SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
protected SqlSessionFactory getSqlSessionFactory() {
|
||||
if (this.sqlSessionFactory == null) {
|
||||
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this.getBaseMapper());
|
||||
this.sqlSessionFactory = MybatisUtils.getSqlSessionFactory(mybatisMapperProxy);
|
||||
}
|
||||
return this.sqlSessionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断数据库操作是否成功
|
||||
*
|
||||
* @param result 数据库操作返回影响条数
|
||||
* @return boolean
|
||||
* @deprecated 3.3.1
|
||||
*/
|
||||
@Deprecated
|
||||
protected boolean retBool(Integer result) {
|
||||
return SqlHelper.retBool(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return baseMapper 真实类型
|
||||
* @deprecated 3.5.7 {@link #getMapperClass()}
|
||||
*/
|
||||
@Deprecated
|
||||
protected Class<M> currentMapperClass() {
|
||||
return this.getMapperClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return baseMapper 真实类型
|
||||
* @since 3.5.7
|
||||
*/
|
||||
public Class<M> getMapperClass() {
|
||||
if (this.mapperClass == null) {
|
||||
MybatisMapperProxy<?> mybatisMapperProxy = MybatisUtils.getMybatisMapperProxy(this.getBaseMapper());
|
||||
this.mapperClass = (Class<M>) mybatisMapperProxy.getMapperInterface();
|
||||
}
|
||||
return this.mapperClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 实体类型
|
||||
* @deprecated 3.5.7 {@link #getEntityClass()}
|
||||
*/
|
||||
@Deprecated
|
||||
protected Class<T> currentModelClass() {
|
||||
return getEntityClass();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 批量操作 SqlSession
|
||||
*
|
||||
* @deprecated 3.3.0
|
||||
*/
|
||||
@Deprecated
|
||||
protected SqlSession sqlSessionBatch() {
|
||||
return getSqlSessionFactory().openSession(ExecutorType.BATCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放sqlSession
|
||||
*
|
||||
* @param sqlSession session
|
||||
* @deprecated 3.3.0
|
||||
*/
|
||||
@Deprecated
|
||||
protected void closeSqlSession(SqlSession sqlSession) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, getSqlSessionFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 SqlStatement
|
||||
*
|
||||
* @param sqlMethod ignore
|
||||
* @return ignore
|
||||
* @see #getSqlStatement(SqlMethod)
|
||||
* @deprecated 3.4.0
|
||||
*/
|
||||
@Deprecated
|
||||
protected String sqlStatement(SqlMethod sqlMethod) {
|
||||
return SqlHelper.table(getEntityClass()).getSqlStatement(sqlMethod.getMethod());
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入
|
||||
*
|
||||
* @param entityList ignore
|
||||
* @param batchSize ignore
|
||||
* @return ignore
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean saveBatch(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取mapperStatementId
|
||||
*
|
||||
* @param sqlMethod 方法名
|
||||
* @return 命名id
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected String getSqlStatement(SqlMethod sqlMethod) {
|
||||
return SqlHelper.getSqlStatement(this.currentMapperClass(), sqlMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* TableId 注解存在更新记录,否插入一条记录
|
||||
*
|
||||
* @param entity 实体对象
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean saveOrUpdate(T entity) {
|
||||
return getBaseMapper().insertOrUpdate(entity);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.getEntityClass());
|
||||
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
|
||||
String keyProperty = tableInfo.getKeyProperty();
|
||||
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
|
||||
return SqlHelper.saveOrUpdateBatch(getSqlSessionFactory(), this.currentMapperClass(), this.log, entityList, batchSize, (sqlSession, entity) -> {
|
||||
Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
|
||||
return StringUtils.checkValNull(idVal)
|
||||
|| CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
|
||||
}, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean updateBatchById(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(sqlStatement, param);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return getBaseMapper().selectOne(queryWrapper, throwEx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<T> getOneOpt(Wrapper<T> queryWrapper, boolean throwEx) {
|
||||
return Optional.ofNullable(getBaseMapper().selectOne(queryWrapper, throwEx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
|
||||
return SqlHelper.getObject(log, getBaseMapper().selectMaps(queryWrapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
|
||||
return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行批量操作
|
||||
*
|
||||
* @param consumer consumer
|
||||
* @since 3.3.0
|
||||
* @deprecated 3.3.1 后面我打算移除掉 {@link #executeBatch(Collection, int, BiConsumer)} }.
|
||||
*/
|
||||
@Deprecated
|
||||
protected boolean executeBatch(Consumer<SqlSession> consumer) {
|
||||
return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行批量操作
|
||||
*
|
||||
* @param list 数据集合
|
||||
* @param batchSize 批量大小
|
||||
* @param consumer 执行方法
|
||||
* @param <E> 泛型
|
||||
* @return 操作结果
|
||||
* @since 3.3.1
|
||||
*/
|
||||
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
|
||||
return SqlHelper.executeBatch(getSqlSessionFactory(), this.log, list, batchSize, consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行批量操作(默认批次提交数量{@link IService#DEFAULT_BATCH_SIZE})
|
||||
*
|
||||
* @param list 数据集合
|
||||
* @param consumer 执行方法
|
||||
* @param <E> 泛型
|
||||
* @return 操作结果
|
||||
* @since 3.3.1
|
||||
*/
|
||||
protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) {
|
||||
return executeBatch(list, DEFAULT_BATCH_SIZE, consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeById(Serializable id, boolean useFill) {
|
||||
return SqlHelper.retBool(getBaseMapper().deleteById(id, useFill));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeBatchByIds(Collection<?> list, int batchSize) {
|
||||
return SqlHelper.retBool(getBaseMapper().deleteByIds(list));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeBatchByIds(Collection<?> list, int batchSize, boolean useFill) {
|
||||
return SqlHelper.retBool(getBaseMapper().deleteByIds(list, useFill));
|
||||
}
|
||||
|
||||
}
|
@ -21,18 +21,12 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.*;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.ibatis.exceptions.PersistenceException;
|
||||
import com.baomidou.mybatisplus.extension.compatible.CompatibleHelper;
|
||||
import org.apache.ibatis.executor.BatchResult;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.reflection.ExceptionUtil;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.MyBatisExceptionTranslator;
|
||||
import org.mybatis.spring.SqlSessionHolder;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
@ -92,7 +86,7 @@ public final class SqlHelper {
|
||||
*/
|
||||
@Deprecated
|
||||
public static SqlSession sqlSession(Class<?> clazz) {
|
||||
return SqlSessionUtils.getSqlSession(GlobalConfigUtils.currentSessionFactory(clazz));
|
||||
return CompatibleHelper.getCompatibleSet().getSqlSession(GlobalConfigUtils.currentSessionFactory(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,40 +182,8 @@ public final class SqlHelper {
|
||||
return executeBatch(sqlSessionFactory(entityClass), log, consumer);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static boolean executeBatch(SqlSessionFactory sqlSessionFactory, Log log, Consumer<SqlSession> consumer) {
|
||||
SqlSessionHolder sqlSessionHolder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sqlSessionFactory);
|
||||
boolean transaction = TransactionSynchronizationManager.isSynchronizationActive();
|
||||
if (sqlSessionHolder != null) {
|
||||
SqlSession sqlSession = sqlSessionHolder.getSqlSession();
|
||||
//原生无法支持执行器切换,当存在批量操作时,会嵌套两个session的,优先commit上一个session
|
||||
//按道理来说,这里的值应该一直为false。
|
||||
sqlSession.commit(!transaction);
|
||||
}
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
if (!transaction) {
|
||||
log.warn("SqlSession [" + sqlSession + "] Transaction not enabled");
|
||||
}
|
||||
try {
|
||||
consumer.accept(sqlSession);
|
||||
//非事务情况下,强制commit。
|
||||
sqlSession.commit(!transaction);
|
||||
return true;
|
||||
} catch (Throwable t) {
|
||||
sqlSession.rollback();
|
||||
Throwable unwrapped = ExceptionUtil.unwrapThrowable(t);
|
||||
if (unwrapped instanceof PersistenceException) {
|
||||
MyBatisExceptionTranslator myBatisExceptionTranslator
|
||||
= new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true);
|
||||
Throwable throwable = myBatisExceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
throw ExceptionUtils.mpe(unwrapped);
|
||||
} finally {
|
||||
sqlSession.close();
|
||||
}
|
||||
return CompatibleHelper.getCompatibleSet().executeBatch(sqlSessionFactory, log, consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,9 +280,9 @@ public final class SqlHelper {
|
||||
* 例: {@code
|
||||
* SqlSession sqlSession = SqlHelper.sqlSession(entityClass);
|
||||
* try {
|
||||
* BaseMapper<User> userMapper = getMapper(User.class, sqlSession);
|
||||
* BaseMapper<User> userMapper = getMapper(User.class, sqlSession);
|
||||
* } finally {
|
||||
* sqlSession.close();
|
||||
* sqlSession.close();
|
||||
* }
|
||||
* }
|
||||
*
|
||||
@ -330,7 +292,7 @@ public final class SqlHelper {
|
||||
* @return Mapper
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T,M extends BaseMapper<T>> M getMapper(Class<T> entityClass, SqlSession sqlSession) {
|
||||
public static <T, M extends BaseMapper<T>> M getMapper(Class<T> entityClass, SqlSession sqlSession) {
|
||||
Assert.notNull(entityClass, "entityClass can't be null!");
|
||||
TableInfo tableInfo = Optional.ofNullable(TableInfoHelper.getTableInfo(entityClass)).orElseThrow(() -> ExceptionUtils.mpe("Can not find TableInfo from Class: \"%s\".", entityClass.getName()));
|
||||
Class<?> mapperClass = ClassUtils.toClassConfident(tableInfo.getCurrentNamespace());
|
||||
@ -347,12 +309,12 @@ public final class SqlHelper {
|
||||
* @param <M> Mapper类型
|
||||
* @return 返回lambda执行结果
|
||||
*/
|
||||
public static <T, R,M extends BaseMapper<T>> R execute(Class<T> entityClass, SFunction<M, R> sFunction) {
|
||||
public static <T, R, M extends BaseMapper<T>> R execute(Class<T> entityClass, SFunction<M, R> sFunction) {
|
||||
SqlSession sqlSession = SqlHelper.sqlSession(entityClass);
|
||||
try {
|
||||
return sFunction.apply(SqlHelper.getMapper(entityClass, sqlSession));
|
||||
} finally {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(entityClass));
|
||||
CompatibleHelper.getCompatibleSet().closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(entityClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package com.baomidou.mybatisplus.generator.config.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
|
||||
@ -229,7 +228,7 @@ public class TableInfo {
|
||||
} else {
|
||||
if (entity.isActiveRecord()) {
|
||||
// 无父类开启 AR 模式
|
||||
this.importPackages.add(Model.class.getCanonicalName());
|
||||
this.importPackages.add("com.baomidou.mybatisplus.extension.activerecord.Model");
|
||||
}
|
||||
}
|
||||
if (entity.isSerialVersionUID() || entity.isActiveRecord()) {
|
||||
|
17
mybatis-plus-solon-plugin/build.gradle
Normal file
17
mybatis-plus-solon-plugin/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
compileKotlin{
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(":mybatis-plus-extension")
|
||||
api "org.noear:mybatis-solon-plugin:3.0.0"
|
||||
api "org.noear:solon-aot:3.0.0"
|
||||
testImplementation "org.noear:solon-test:3.0.0"
|
||||
testImplementation "io.github.classgraph:classgraph:4.8.176"
|
||||
testImplementation "com.zaxxer:HikariCP:4.0.3"
|
||||
testImplementation "${lib.h2}"
|
||||
testImplementation "${lib.mysql}"
|
||||
testImplementation "${lib.'logback-classic'}"
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baomidou.mybatisplus.core.override;
|
||||
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class SolonMybatisMapperProxy<T> extends MybatisMapperProxy<T> {
|
||||
|
||||
private final SqlSessionFactory factory;
|
||||
private final Class<T> mapperInterface;
|
||||
private final SqlSession sqlSession;
|
||||
|
||||
public SolonMybatisMapperProxy(SqlSessionFactory sqlSessionFactory, SqlSession sqlSession, Class<T> mapperInterface) {
|
||||
super(null, mapperInterface, null);
|
||||
this.factory = sqlSessionFactory;
|
||||
this.sqlSession = sqlSession;
|
||||
this.mapperInterface = mapperInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlSession getSqlSession() {
|
||||
return sqlSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
try (SqlSession session = factory.openSession(true)) {
|
||||
Object mapper = session.getMapper(mapperInterface);
|
||||
return method.invoke(mapper, args);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.activerecord;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
||||
|
||||
/**
|
||||
* ActiveRecord 模式 CRUD
|
||||
* <p>
|
||||
* 必须存在对应的原始mapper并继承baseMapper并且可以使用的前提下
|
||||
* 才能使用此 AR 模式 !!!
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* @author hubin
|
||||
* @since 2016-11-06
|
||||
*/
|
||||
public abstract class Model<T extends Model<?>> extends AbstractModel<T> {
|
||||
|
||||
/**
|
||||
* 执行 SQL
|
||||
*/
|
||||
public SqlRunner sql() {
|
||||
return new SqlRunner(this.entityClass);
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.compatible;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.reflection.ExceptionUtil;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.noear.solon.core.util.GenericUtil;
|
||||
import org.noear.solon.core.util.ResourceUtil;
|
||||
import org.noear.solon.data.tran.TranUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* spring 兼容方法集接口实现类
|
||||
*/
|
||||
public class SolonCompatibleSet implements CompatibleSet {
|
||||
|
||||
@Override
|
||||
public SqlSession getSqlSession(SqlSessionFactory sessionFactory) {
|
||||
return sessionFactory.openSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeSqlSession(SqlSession sqlSession, SqlSessionFactory sqlSessionFactory) {
|
||||
if (sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeBatch(SqlSessionFactory sqlSessionFactory, Log log, Consumer<SqlSession> consumer) {
|
||||
boolean transaction = TranUtils.inTrans();
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
if (!transaction) {
|
||||
log.warn("SqlSession [" + sqlSession + "] Transaction not enabled");
|
||||
}
|
||||
try {
|
||||
consumer.accept(sqlSession);
|
||||
//非事务情况下,强制commit。
|
||||
sqlSession.commit(!transaction);
|
||||
return true;
|
||||
} catch (RuntimeException t) {
|
||||
throw t;
|
||||
} catch (Throwable t) {
|
||||
sqlSession.rollback();
|
||||
Throwable unwrapped = ExceptionUtil.unwrapThrowable(t);
|
||||
if (unwrapped instanceof RuntimeException) {
|
||||
throw (RuntimeException) unwrapped;
|
||||
} else {
|
||||
throw ExceptionUtils.mpe(unwrapped);
|
||||
}
|
||||
} finally {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(String path) throws Exception {
|
||||
return ResourceUtil.findResource(path).openStream();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.ddl;
|
||||
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 非多数据源 DDL 实现
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2021-09-23
|
||||
*/
|
||||
public class SimpleDdl implements IDdl {
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
|
||||
@Override
|
||||
public void runScript(Consumer<DataSource> consumer) {
|
||||
consumer.accept(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSqlFiles() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
import org.apache.ibatis.binding.MapperMethod;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.data.annotation.Tran;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
public abstract class CrudRepository<M extends BaseMapper<T>, T> extends AbstractRepository<M, T> {
|
||||
|
||||
@Inject
|
||||
protected M baseMapper;
|
||||
|
||||
@Override
|
||||
public M getBaseMapper() {
|
||||
Assert.notNull(this.baseMapper, "baseMapper can not be null");
|
||||
return this.baseMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入
|
||||
*
|
||||
* @param entityList ignore
|
||||
* @param batchSize ignore
|
||||
* @return ignore
|
||||
*/
|
||||
@Tran
|
||||
@Override
|
||||
public boolean saveBatch(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取mapperStatementId
|
||||
*
|
||||
* @param sqlMethod 方法名
|
||||
* @return 命名id
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected String getSqlStatement(SqlMethod sqlMethod) {
|
||||
return SqlHelper.getSqlStatement(this.getMapperClass(), sqlMethod);
|
||||
}
|
||||
|
||||
@Tran
|
||||
@Override
|
||||
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.getEntityClass());
|
||||
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
|
||||
String keyProperty = tableInfo.getKeyProperty();
|
||||
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
|
||||
return SqlHelper.saveOrUpdateBatch(getSqlSessionFactory(), this.getMapperClass(), this.log, entityList, batchSize, (sqlSession, entity) -> {
|
||||
Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
|
||||
return StringUtils.checkValNull(idVal)
|
||||
|| CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
|
||||
}, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
|
||||
});
|
||||
}
|
||||
|
||||
@Tran
|
||||
@Override
|
||||
public boolean updateBatchById(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(sqlStatement, param);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.repository.IRepository;
|
||||
import org.noear.solon.data.annotation.Tran;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 顶级 Service
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
public interface IService<T> extends IRepository<T> {
|
||||
|
||||
/**
|
||||
* 插入(批量)
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Tran
|
||||
default boolean saveBatch(Collection<T> entityList) {
|
||||
return saveBatch(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改插入
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Tran
|
||||
default boolean saveOrUpdateBatch(Collection<T> entityList) {
|
||||
return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除(jdbc批量提交)
|
||||
*
|
||||
* @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
|
||||
* @return 删除结果
|
||||
* @since 3.5.0
|
||||
*/
|
||||
@Tran
|
||||
default boolean removeBatchByIds(Collection<?> list) {
|
||||
return removeByIds(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID 批量更新
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Tran
|
||||
default boolean updateBatchById(Collection<T> entityList) {
|
||||
return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.repository.CrudRepository;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
public class ServiceImpl<M extends BaseMapper<T>, T> extends CrudRepository<M, T> implements IService<T> {
|
||||
|
||||
}
|
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.toolkit;
|
||||
|
||||
import com.baomidou.mybatisplus.core.assist.ISqlRunner;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.noear.solon.data.annotation.Tran;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* SqlRunner 执行 SQL
|
||||
*
|
||||
* @author Caratacus
|
||||
* @since 2016-12-11
|
||||
*/
|
||||
public class SqlRunner implements ISqlRunner {
|
||||
|
||||
// 单例Query
|
||||
public static final SqlRunner DEFAULT = new SqlRunner();
|
||||
private final Log log = LogFactory.getLog(SqlRunner.class);
|
||||
private Class<?> clazz;
|
||||
|
||||
public SqlRunner() {
|
||||
}
|
||||
|
||||
public SqlRunner(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认的SqlQuery(适用于单库)
|
||||
*
|
||||
* @return ignore
|
||||
*/
|
||||
public static SqlRunner db() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前class对象获取SqlQuery(适用于多库)
|
||||
*
|
||||
* @param clazz ignore
|
||||
* @return ignore
|
||||
*/
|
||||
public static SqlRunner db(Class<?> clazz) {
|
||||
return new SqlRunner(clazz);
|
||||
}
|
||||
|
||||
@Tran
|
||||
@Override
|
||||
public boolean insert(String sql, Object... args) {
|
||||
SqlSession sqlSession = sqlSession();
|
||||
try {
|
||||
return SqlHelper.retBool(sqlSession.insert(INSERT, sqlMap(sql, args)));
|
||||
} finally {
|
||||
closeSqlSession(sqlSession);
|
||||
}
|
||||
}
|
||||
|
||||
@Tran
|
||||
@Override
|
||||
public boolean delete(String sql, Object... args) {
|
||||
SqlSession sqlSession = sqlSession();
|
||||
try {
|
||||
return SqlHelper.retBool(sqlSession.delete(DELETE, sqlMap(sql, args)));
|
||||
} finally {
|
||||
closeSqlSession(sqlSession);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sqlMap参数
|
||||
*
|
||||
* @param sql 指定参数的格式: {0}, {1}
|
||||
* @param args 仅支持String
|
||||
* @return ignore
|
||||
*/
|
||||
private Map<String, String> sqlMap(String sql, Object... args) {
|
||||
Map<String, String> sqlMap = CollectionUtils.newHashMapWithExpectedSize(1);
|
||||
sqlMap.put(SQL, StringUtils.sqlArgsFill(sql, args));
|
||||
return sqlMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sqlMap参数
|
||||
*
|
||||
* @param sql 指定参数的格式: {0}, {1}
|
||||
* @param page 分页模型
|
||||
* @param args 仅支持String
|
||||
* @return ignore
|
||||
*/
|
||||
private Map<String, Object> sqlMap(String sql, IPage<?> page, Object... args) {
|
||||
Map<String, Object> sqlMap = CollectionUtils.newHashMapWithExpectedSize(2);
|
||||
sqlMap.put(PAGE, page);
|
||||
sqlMap.put(SQL, StringUtils.sqlArgsFill(sql, args));
|
||||
return sqlMap;
|
||||
}
|
||||
|
||||
@Tran
|
||||
@Override
|
||||
public boolean update(String sql, Object... args) {
|
||||
SqlSession sqlSession = sqlSession();
|
||||
try {
|
||||
return SqlHelper.retBool(sqlSession.update(UPDATE, sqlMap(sql, args)));
|
||||
} finally {
|
||||
closeSqlSession(sqlSession);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sql查询Map结果集
|
||||
* <p>SqlRunner.db().selectList("select * from tbl_user where name={0}", "Caratacus")</p>
|
||||
*
|
||||
* @param sql sql语句,可添加参数,格式:{0},{1}
|
||||
* @param args 只接受String格式
|
||||
* @return ignore
|
||||
*/
|
||||
@Override
|
||||
public List<Map<String, Object>> selectList(String sql, Object... args) {
|
||||
SqlSession sqlSession = sqlSession();
|
||||
try {
|
||||
return sqlSession.selectList(SELECT_LIST, sqlMap(sql, args));
|
||||
} finally {
|
||||
closeSqlSession(sqlSession);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sql查询一个字段值的结果集
|
||||
* <p>注意:该方法只会返回一个字段的值, 如果需要多字段,请参考{@code selectList()}</p>
|
||||
*
|
||||
* @param sql sql语句,可添加参数,格式:{0},{1}
|
||||
* @param args 只接受String格式
|
||||
* @return ignore
|
||||
*/
|
||||
@Override
|
||||
public List<Object> selectObjs(String sql, Object... args) {
|
||||
SqlSession sqlSession = sqlSession();
|
||||
try {
|
||||
return sqlSession.selectList(SELECT_OBJS, sqlMap(sql, args));
|
||||
} finally {
|
||||
closeSqlSession(sqlSession);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据sql查询一个字段值的一条结果
|
||||
* <p>注意:该方法只会返回一个字段的值, 如果需要多字段,请参考{@code selectOne()}</p>
|
||||
*
|
||||
* @param sql sql语句,可添加参数,格式:{0},{1}
|
||||
* @param args 只接受String格式
|
||||
* @return ignore
|
||||
*/
|
||||
@Override
|
||||
public Object selectObj(String sql, Object... args) {
|
||||
return SqlHelper.getObject(log, selectObjs(sql, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long selectCount(String sql, Object... args) {
|
||||
SqlSession sqlSession = sqlSession();
|
||||
try {
|
||||
return SqlHelper.retCount(sqlSession.<Long>selectOne(COUNT, sqlMap(sql, args)));
|
||||
} finally {
|
||||
closeSqlSession(sqlSession);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> selectOne(String sql, Object... args) {
|
||||
return SqlHelper.getObject(log, selectList(sql, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends IPage<Map<String, Object>>> E selectPage(E page, String sql, Object... args) {
|
||||
if (null == page) {
|
||||
return null;
|
||||
}
|
||||
SqlSession sqlSession = sqlSession();
|
||||
try {
|
||||
page.setRecords(sqlSession.selectList(SELECT_LIST, sqlMap(sql, page, args)));
|
||||
} finally {
|
||||
closeSqlSession(sqlSession);
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Session 默认自动提交
|
||||
*/
|
||||
private SqlSession sqlSession() {
|
||||
return getSqlSessionFactory().openSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放sqlSession
|
||||
*
|
||||
* @param sqlSession session
|
||||
*/
|
||||
private void closeSqlSession(SqlSession sqlSession) {
|
||||
if (sqlSession != null) {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取SqlSessionFactory
|
||||
*/
|
||||
private SqlSessionFactory getSqlSessionFactory() {
|
||||
return Optional.ofNullable(clazz).map(GlobalConfigUtils::currentSessionFactory).orElse(SqlHelper.FACTORY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.5.3.2
|
||||
*/
|
||||
@Deprecated
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.baomidou.mybatisplus.solon.integration;
|
||||
|
||||
import org.apache.ibatis.solon.MybatisAdapter;
|
||||
import org.apache.ibatis.solon.MybatisAdapterFactory;
|
||||
import org.noear.solon.core.BeanWrap;
|
||||
import org.noear.solon.core.Props;
|
||||
|
||||
/**
|
||||
* 适配器工厂 for mybatis-plus
|
||||
*
|
||||
* @author noear, iYarnFog
|
||||
* @since 1.5
|
||||
*/
|
||||
public class MybatisAdapterFactoryPlus implements MybatisAdapterFactory {
|
||||
@Override
|
||||
public MybatisAdapter create(BeanWrap dsWrap) {
|
||||
return new MybatisAdapterPlus(dsWrap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MybatisAdapter create(BeanWrap dsWrap, Props dsProps) {
|
||||
return new MybatisAdapterPlus(dsWrap, dsProps);
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
package com.baomidou.mybatisplus.solon.integration;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
|
||||
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.core.override.SolonMybatisMapperProxy;
|
||||
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
||||
import org.apache.ibatis.mapping.Environment;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.solon.integration.MybatisAdapterDefault;
|
||||
import org.noear.solon.Utils;
|
||||
import org.noear.solon.core.BeanWrap;
|
||||
import org.noear.solon.core.Props;
|
||||
import org.noear.solon.core.VarHolder;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 适配器 for mybatis-plus
|
||||
* <p>
|
||||
* 1.提供 mapperScan 能力
|
||||
* 2.生成 factory 的能力
|
||||
*
|
||||
* @author noear, iYarnFog
|
||||
* @since 1.5
|
||||
*/
|
||||
public class MybatisAdapterPlus extends MybatisAdapterDefault {
|
||||
|
||||
MybatisSqlSessionFactoryBuilder factoryBuilderPlus;
|
||||
GlobalConfig globalConfig;
|
||||
SqlSession sqlSession;
|
||||
Map<Class<?>, Object> mapperCached = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 构建Sql工厂适配器,使用默认的 typeAliases 和 mappers 配置
|
||||
*/
|
||||
protected MybatisAdapterPlus(BeanWrap dsWrap) {
|
||||
super(dsWrap);
|
||||
|
||||
this.factoryBuilderPlus = new MybatisSqlSessionFactoryBuilder();
|
||||
|
||||
dsWrap.context().getBeanAsync(MybatisSqlSessionFactoryBuilder.class, bean -> {
|
||||
factoryBuilderPlus = bean;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Sql工厂适配器,使用属性配置
|
||||
*/
|
||||
protected MybatisAdapterPlus(BeanWrap dsWrap, Props dsProps) {
|
||||
super(dsWrap, dsProps);
|
||||
|
||||
this.factoryBuilderPlus = new MybatisSqlSessionFactoryBuilder();
|
||||
|
||||
dsWrap.context().getBeanAsync(MybatisSqlSessionFactoryBuilder.class, bean -> {
|
||||
factoryBuilderPlus = bean;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化配置
|
||||
*/
|
||||
@Override
|
||||
protected void initConfiguration(Environment environment) {
|
||||
//for configuration section
|
||||
config = new MybatisConfiguration(environment);
|
||||
|
||||
Props cfgProps = dsProps.getProp("configuration");
|
||||
if (cfgProps.size() > 0) {
|
||||
Utils.injectProperties(config, cfgProps);
|
||||
}
|
||||
|
||||
|
||||
//for globalConfig section
|
||||
globalConfig = new GlobalConfig().setDbConfig(new GlobalConfig.DbConfig());
|
||||
|
||||
Props globalProps = dsProps.getProp("globalConfig");
|
||||
if (globalProps.size() > 0) {
|
||||
//尝试配置注入
|
||||
Utils.injectProperties(globalConfig, globalProps);
|
||||
}
|
||||
|
||||
GlobalConfigUtils.setGlobalConfig(config, globalConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话工厂
|
||||
*/
|
||||
@Override
|
||||
public SqlSessionFactory getFactory() {
|
||||
if (factory == null) {
|
||||
factory = factoryBuilderPlus.build(getConfiguration());
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
public SqlSession getSession() {
|
||||
if (sqlSession == null) {
|
||||
sqlSession = new SolonSqlSession(getFactory());
|
||||
}
|
||||
return sqlSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getMapper(Class<T> mapperClz) {
|
||||
Object mapper = mapperCached.get(mapperClz);
|
||||
|
||||
if (mapper == null) {
|
||||
synchronized (mapperClz) {
|
||||
mapper = mapperCached.get(mapperClz);
|
||||
if (mapper == null) {
|
||||
SolonMybatisMapperProxy<T> tMybatisMapperProxy = new SolonMybatisMapperProxy<>(getFactory(), getSession(), mapperClz);
|
||||
mapper = Proxy.newProxyInstance(
|
||||
mapperClz.getClassLoader(),
|
||||
new Class[]{mapperClz},
|
||||
tMybatisMapperProxy);
|
||||
mapperCached.put(mapperClz, mapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (T) mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全局配置
|
||||
*/
|
||||
public GlobalConfig getGlobalConfig() {
|
||||
return globalConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectTo(VarHolder varH) {
|
||||
super.injectTo(varH);
|
||||
|
||||
//@Db("db1") SqlSessionFactory factory;
|
||||
if (GlobalConfig.class.isAssignableFrom(varH.getType())) {
|
||||
varH.setValue(this.getGlobalConfig());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
package com.baomidou.mybatisplus.solon.integration;
|
||||
|
||||
import org.apache.ibatis.cursor.Cursor;
|
||||
import org.apache.ibatis.executor.BatchResult;
|
||||
import org.apache.ibatis.reflection.ExceptionUtil;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.noear.solon.data.tran.TranUtils;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Connection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SolonSqlSession implements SqlSession {
|
||||
|
||||
private final SqlSessionFactory sqlSessionFactory;
|
||||
private final SqlSession sqlSessionProxy;
|
||||
|
||||
public SolonSqlSession(SqlSessionFactory sqlSessionFactory) {
|
||||
this.sqlSessionFactory = sqlSessionFactory;
|
||||
this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionInterceptor());
|
||||
}
|
||||
|
||||
public SqlSessionFactory getSqlSessionFactory() {
|
||||
return this.sqlSessionFactory;
|
||||
}
|
||||
|
||||
public SqlSession getSqlSessionProxy() {
|
||||
return this.sqlSessionProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T selectOne(String statement) {
|
||||
return this.sqlSessionProxy.selectOne(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T selectOne(String statement, Object parameter) {
|
||||
return this.sqlSessionProxy.selectOne(statement, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
|
||||
return this.sqlSessionProxy.selectMap(statement, mapKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
|
||||
return this.sqlSessionProxy.selectMap(statement, parameter, mapKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
|
||||
return this.sqlSessionProxy.selectMap(statement, parameter, mapKey, rowBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Cursor<T> selectCursor(String statement) {
|
||||
return this.sqlSessionProxy.selectCursor(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Cursor<T> selectCursor(String statement, Object parameter) {
|
||||
return this.sqlSessionProxy.selectCursor(statement, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) {
|
||||
return this.sqlSessionProxy.selectCursor(statement, parameter, rowBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> selectList(String statement) {
|
||||
return this.sqlSessionProxy.selectList(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> selectList(String statement, Object parameter) {
|
||||
return this.sqlSessionProxy.selectList(statement, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
|
||||
return this.sqlSessionProxy.selectList(statement, parameter, rowBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void select(String statement, ResultHandler handler) {
|
||||
this.sqlSessionProxy.select(statement, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void select(String statement, Object parameter, ResultHandler handler) {
|
||||
this.sqlSessionProxy.select(statement, parameter, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
|
||||
this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(String statement) {
|
||||
return this.sqlSessionProxy.insert(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(String statement, Object parameter) {
|
||||
return this.sqlSessionProxy.insert(statement, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(String statement) {
|
||||
return this.sqlSessionProxy.update(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(String statement, Object parameter) {
|
||||
return this.sqlSessionProxy.update(statement, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(String statement) {
|
||||
return this.sqlSessionProxy.delete(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(String statement, Object parameter) {
|
||||
return this.sqlSessionProxy.delete(statement, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getMapper(Class<T> type) {
|
||||
return this.getConfiguration().getMapper(type, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() {
|
||||
throw new UnsupportedOperationException("Manual commit is not allowed over a Solon managed SqlSession");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit(boolean force) {
|
||||
throw new UnsupportedOperationException("Manual commit is not allowed over a Solon managed SqlSession");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() {
|
||||
throw new UnsupportedOperationException("Manual rollback is not allowed over a Solon managed SqlSession");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback(boolean force) {
|
||||
throw new UnsupportedOperationException("Manual rollback is not allowed over a Solon managed SqlSession");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
throw new UnsupportedOperationException("Manual close is not allowed over a Solon managed SqlSession");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
this.sqlSessionProxy.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration getConfiguration() {
|
||||
return this.sqlSessionFactory.getConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() {
|
||||
return this.sqlSessionProxy.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BatchResult> flushStatements() {
|
||||
return this.sqlSessionProxy.flushStatements();
|
||||
}
|
||||
|
||||
private class SqlSessionInterceptor implements InvocationHandler {
|
||||
private SqlSessionInterceptor() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
Object unwrapped;
|
||||
try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
|
||||
Object result = method.invoke(sqlSession, args);
|
||||
sqlSession.commit(!TranUtils.inTrans());
|
||||
unwrapped = result;
|
||||
} catch (Throwable var11) {
|
||||
unwrapped = ExceptionUtil.unwrapThrowable(var11);
|
||||
if (unwrapped instanceof RuntimeException) {
|
||||
throw (RuntimeException) unwrapped;
|
||||
}
|
||||
throw (Throwable) unwrapped;
|
||||
}
|
||||
return unwrapped;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.baomidou.mybatisplus.solon.integration;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
|
||||
import com.baomidou.mybatisplus.extension.compatible.CompatibleHelper;
|
||||
import com.baomidou.mybatisplus.extension.compatible.SolonCompatibleSet;
|
||||
import com.baomidou.mybatisplus.solon.integration.aot.MybatisPlusRuntimeNativeRegistrar;
|
||||
import org.noear.solon.aot.RuntimeNativeRegistrar;
|
||||
import org.noear.solon.core.AppContext;
|
||||
import org.noear.solon.core.runtime.NativeDetector;
|
||||
import org.noear.solon.core.util.ClassUtil;
|
||||
import org.noear.solon.core.util.GenericUtil;
|
||||
import org.apache.ibatis.solon.integration.MybatisAdapterManager;
|
||||
import org.noear.solon.core.Plugin;
|
||||
|
||||
/**
|
||||
* @author noear
|
||||
* @since 1.5
|
||||
*/
|
||||
public class XPluginImpl implements Plugin {
|
||||
|
||||
@Override
|
||||
public void start(AppContext context) {
|
||||
//
|
||||
// 此插件的 solon.plugin.priority 会大于 mybatis-solon-plugin 的值
|
||||
//
|
||||
MybatisAdapterManager.setAdapterFactory(new MybatisAdapterFactoryPlus());
|
||||
|
||||
// 注入兼容配置
|
||||
CompatibleHelper.setCompatibleSet(new SolonCompatibleSet());
|
||||
|
||||
// 提供反射处理类
|
||||
GenericTypeUtils.setGenericTypeResolver((GenericUtil::resolveTypeArguments));
|
||||
|
||||
// aot
|
||||
if (NativeDetector.isAotRuntime() && ClassUtil.hasClass(() -> RuntimeNativeRegistrar.class)) {
|
||||
context.wrapAndPut(MybatisPlusRuntimeNativeRegistrar.class);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.baomidou.mybatisplus.solon.integration.aot;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver;
|
||||
import com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.interfaces.Compare;
|
||||
import com.baomidou.mybatisplus.core.conditions.interfaces.Func;
|
||||
import com.baomidou.mybatisplus.core.conditions.interfaces.Join;
|
||||
import com.baomidou.mybatisplus.core.conditions.interfaces.Nested;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.Query;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import org.noear.solon.aot.RuntimeNativeMetadata;
|
||||
import org.noear.solon.aot.RuntimeNativeRegistrar;
|
||||
import org.noear.solon.aot.hint.ExecutableMode;
|
||||
import org.noear.solon.aot.hint.MemberCategory;
|
||||
import org.noear.solon.core.AppContext;
|
||||
|
||||
import java.lang.invoke.SerializedLambda;
|
||||
|
||||
/**
|
||||
* mybatis-plus aot 注册 native 元数据
|
||||
*
|
||||
* @author songyinyin
|
||||
* @since 2.3
|
||||
*/
|
||||
public class MybatisPlusRuntimeNativeRegistrar implements RuntimeNativeRegistrar {
|
||||
|
||||
@Override
|
||||
public void register(AppContext context, RuntimeNativeMetadata metadata) {
|
||||
metadata.registerDefaultConstructor(MybatisXMLLanguageDriver.class);
|
||||
metadata.registerReflection(MybatisConfiguration.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
metadata.registerAllDeclaredMethod(MybatisConfiguration.class, ExecutableMode.INVOKE);
|
||||
|
||||
metadata.registerReflection(AbstractLambdaWrapper.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
|
||||
metadata.registerJdkProxy(AbstractWrapper.DoSomething.class);
|
||||
metadata.registerReflection(AbstractWrapper.DoSomething.class);
|
||||
metadata.registerReflection(AbstractWrapper.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
metadata.registerAllDeclaredMethod(AbstractWrapper.class, ExecutableMode.INVOKE);
|
||||
|
||||
metadata.registerReflection(ISqlSegment.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
metadata.registerReflection(Wrapper.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
|
||||
metadata.registerAllDeclaredMethod(Wrapper.class, ExecutableMode.INVOKE);
|
||||
|
||||
metadata.registerReflection(Compare.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
metadata.registerReflection(Func.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
metadata.registerReflection(Join.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
metadata.registerReflection(Nested.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
|
||||
metadata.registerReflection(LambdaQueryWrapper.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_METHODS,
|
||||
MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS);
|
||||
metadata.registerAllDeclaredMethod(LambdaQueryWrapper.class, ExecutableMode.INVOKE);
|
||||
|
||||
metadata.registerReflection(Query.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS);
|
||||
|
||||
metadata.registerAllDeclaredMethod(BaseMapper.class, ExecutableMode.INVOKE);
|
||||
|
||||
metadata.registerSerialization(SerializedLambda.class);
|
||||
metadata.registerSerialization(SFunction.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
solon.plugin=com.baomidou.mybatisplus.solon.integration.XPluginImpl
|
||||
solon.plugin.priority=30
|
50
mybatis-plus-solon-plugin/src/test/java/demo/Config.java
Normal file
50
mybatis-plus-solon-plugin/src/test/java/demo/Config.java
Normal file
@ -0,0 +1,50 @@
|
||||
package demo;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
|
||||
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import demo.dso.MetaObjectHandlerImpl;
|
||||
import demo.dso.MybatisSqlSessionFactoryBuilderImpl;
|
||||
import okhttp3.Interceptor;
|
||||
import org.apache.ibatis.solon.annotation.Db;
|
||||
import org.noear.solon.Solon;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration
|
||||
public class Config {
|
||||
@Bean("db1")
|
||||
public DataSource db1(@Inject("${dataSource.db1}") HikariDataSource hikariDataSource) {
|
||||
return hikariDataSource;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public Interceptor plusInterceptor() {
|
||||
// MybatisPlusInterceptor plusInterceptor = new MybatisPlusInterceptor();
|
||||
// plusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
// return plusInterceptor;
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public void db1_ext(@Db("db1") GlobalConfig globalConfig) {
|
||||
MetaObjectHandler metaObjectHandler = new MetaObjectHandlerImpl();
|
||||
|
||||
globalConfig.setMetaObjectHandler(metaObjectHandler);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public void db1_ext2(@Db("db1") MybatisConfiguration config){
|
||||
config.getTypeHandlerRegistry().register("xxx");
|
||||
config.setDefaultEnumTypeHandler(null);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MybatisSqlSessionFactoryBuilder factoryBuilderNew(){
|
||||
return new MybatisSqlSessionFactoryBuilderImpl();
|
||||
}
|
||||
}
|
22
mybatis-plus-solon-plugin/src/test/java/demo/DemoApp.java
Normal file
22
mybatis-plus-solon-plugin/src/test/java/demo/DemoApp.java
Normal file
@ -0,0 +1,22 @@
|
||||
package demo;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import demo.dso.service.UserService;
|
||||
import demo.model.User;
|
||||
import org.noear.solon.Solon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author noear 2021/7/12 created
|
||||
*/
|
||||
public class DemoApp {
|
||||
public static void main(String[] args) {
|
||||
Solon.start(DemoApp.class, args);
|
||||
|
||||
//test
|
||||
UserService userService = Solon.context().getBean(UserService.class);
|
||||
|
||||
Assert.notNull(userService.getUserList(), "查询结果异常");
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package demo.controller;
|
||||
|
||||
import demo.dso.service.UserService;
|
||||
import demo.model.User;
|
||||
import org.noear.solon.annotation.Controller;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.annotation.Mapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
public class IndexController {
|
||||
|
||||
@Inject
|
||||
UserService userService;
|
||||
|
||||
@Mapping("/")
|
||||
public List<User> index() {
|
||||
return userService.getUserList();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package demo.dso;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
|
||||
/**
|
||||
* @author noear 2022/4/17 created
|
||||
*/
|
||||
public class MetaObjectHandlerImpl implements MetaObjectHandler {
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package demo.dso;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
|
||||
|
||||
/**
|
||||
* @author noear 2021/10/20 created
|
||||
*/
|
||||
public class MybatisSqlSessionFactoryBuilderImpl extends MybatisSqlSessionFactoryBuilder {
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package demo.dso.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import demo.model.User;
|
||||
|
||||
/**
|
||||
* @author 颖
|
||||
*/
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package demo.dso.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import demo.dso.mapper.UserMapper;
|
||||
import demo.model.User;
|
||||
import org.noear.solon.annotation.Component;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author noear 2021/9/9 created
|
||||
*/
|
||||
@Component
|
||||
public class UserService {
|
||||
@Inject
|
||||
UserMapper userMapper;
|
||||
|
||||
public List<User> getUserList() {
|
||||
assert userMapper != null;
|
||||
|
||||
return userMapper.selectList(new QueryWrapper<>());
|
||||
}
|
||||
}
|
31
mybatis-plus-solon-plugin/src/test/java/demo/model/User.java
Normal file
31
mybatis-plus-solon-plugin/src/test/java/demo/model/User.java
Normal file
@ -0,0 +1,31 @@
|
||||
package demo.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
/**
|
||||
* @author iYarnFog
|
||||
*/
|
||||
@TableName(value = "users")
|
||||
public class User {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String uuid;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package features;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.Mapper;
|
||||
import demo.dso.mapper.UserMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.noear.solon.core.util.GenericUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
public class IGenericTypeResolverImplTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void resolveTypeArguments() {
|
||||
System.out.println(Arrays.toString(GenericUtil.resolveTypeArguments(DemoImpl.class, Map.class)));
|
||||
System.out.println(Arrays.toString(GenericUtil.resolveTypeArguments(DemoImpl.class, Demo.class)));
|
||||
|
||||
System.out.println(Arrays.toString(GenericUtil.resolveTypeArguments(UserMapper.class, Mapper.class)));
|
||||
}
|
||||
|
||||
private interface Demo<T> {}
|
||||
private abstract static class DemoImpl implements Map<Integer, String>, IGenericTypeResolverImplTest.Demo<Double> {
|
||||
|
||||
}
|
||||
}
|
25
mybatis-plus-solon-plugin/src/test/resources/app.yml
Normal file
25
mybatis-plus-solon-plugin/src/test/resources/app.yml
Normal file
@ -0,0 +1,25 @@
|
||||
server:
|
||||
port: 6040
|
||||
|
||||
# 配置数据源
|
||||
dataSource:
|
||||
db1:
|
||||
# 与数据库名可用保持一致
|
||||
schema: test
|
||||
jdbcUrl: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
username: root
|
||||
password: 1234
|
||||
|
||||
mybatis:
|
||||
db1:
|
||||
mappers:
|
||||
- "demo.dso.mapper.*"
|
||||
configuration:
|
||||
cacheEnabled: false
|
||||
mapUnderscoreToCamelCase: true
|
||||
globalConfig:
|
||||
banner: false
|
||||
metaObjectHandler: "demo.dso.MetaObjectHandlerImpl"
|
||||
dbConfig:
|
||||
logicDeleteField: "deleted"
|
29
mybatis-plus-spring/build.gradle
Normal file
29
mybatis-plus-spring/build.gradle
Normal file
@ -0,0 +1,29 @@
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
compileKotlin{
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(":mybatis-plus-extension")
|
||||
implementation "${lib."mybatis-spring"}"
|
||||
|
||||
implementation "${lib."kotlin-stdlib-jdk8"}"
|
||||
implementation "${lib."kotlin-reflect"}"
|
||||
implementation "${lib."spring-context-support"}"
|
||||
implementation "${lib."spring-jdbc"}"
|
||||
implementation "${lib."slf4j-api"}"
|
||||
implementation "${lib."p6spy"}"
|
||||
implementation "${lib."jackson"}"
|
||||
implementation "${lib."fastjson"}"
|
||||
implementation "${lib."gson"}"
|
||||
implementation "${lib['mybatis-thymeleaf']}"
|
||||
implementation "${lib.'mybatis-velocity'}"
|
||||
implementation "${lib.'mybatis-freemarker'}"
|
||||
implementation "de.ruedigermoeller:fst:3.0.4-jdk17"
|
||||
implementation "com.github.ben-manes.caffeine:caffeine:2.9.3"
|
||||
testImplementation "io.github.classgraph:classgraph:4.8.176"
|
||||
testImplementation "${lib.h2}"
|
||||
testImplementation "${lib.mysql}"
|
||||
testImplementation "${lib.'logback-classic'}"
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.activerecord;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
|
||||
|
||||
/**
|
||||
* ActiveRecord 模式 CRUD
|
||||
* <p>
|
||||
* 必须存在对应的原始mapper并继承baseMapper并且可以使用的前提下
|
||||
* 才能使用此 AR 模式 !!!
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* @author hubin
|
||||
* @since 2016-11-06
|
||||
*/
|
||||
public abstract class Model<T extends Model<?>> extends AbstractModel<T> {
|
||||
|
||||
/**
|
||||
* 执行 SQL
|
||||
*/
|
||||
public SqlRunner sql() {
|
||||
return new SqlRunner(this.entityClass);
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.compatible;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.ibatis.exceptions.PersistenceException;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.reflection.ExceptionUtil;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.MyBatisExceptionTranslator;
|
||||
import org.mybatis.spring.SqlSessionHolder;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* spring 兼容方法集接口实现类
|
||||
*/
|
||||
public class SpringCompatibleSet implements CompatibleSet {
|
||||
|
||||
@Override
|
||||
public SqlSession getSqlSession(SqlSessionFactory sessionFactory) {
|
||||
return SqlSessionUtils.getSqlSession(sessionFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeSqlSession(SqlSession sqlSession, SqlSessionFactory sqlSessionFactory) {
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean executeBatch(SqlSessionFactory sqlSessionFactory, Log log, Consumer<SqlSession> consumer) {
|
||||
SqlSessionHolder sqlSessionHolder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sqlSessionFactory);
|
||||
boolean transaction = TransactionSynchronizationManager.isSynchronizationActive();
|
||||
if (sqlSessionHolder != null) {
|
||||
SqlSession sqlSession = sqlSessionHolder.getSqlSession();
|
||||
//原生无法支持执行器切换,当存在批量操作时,会嵌套两个session的,优先commit上一个session
|
||||
//按道理来说,这里的值应该一直为false。
|
||||
sqlSession.commit(!transaction);
|
||||
}
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
if (!transaction) {
|
||||
log.warn("SqlSession [" + sqlSession + "] Transaction not enabled");
|
||||
}
|
||||
try {
|
||||
consumer.accept(sqlSession);
|
||||
//非事务情况下,强制commit。
|
||||
sqlSession.commit(!transaction);
|
||||
return true;
|
||||
} catch (Throwable t) {
|
||||
sqlSession.rollback();
|
||||
Throwable unwrapped = ExceptionUtil.unwrapThrowable(t);
|
||||
if (unwrapped instanceof PersistenceException) {
|
||||
MyBatisExceptionTranslator myBatisExceptionTranslator
|
||||
= new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true);
|
||||
Throwable throwable = myBatisExceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
throw ExceptionUtils.mpe(unwrapped);
|
||||
} finally {
|
||||
sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(String path) throws Exception {
|
||||
return new ClassPathResource(path).getInputStream();
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
import org.apache.ibatis.binding.MapperMethod;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
public abstract class CrudRepository<M extends BaseMapper<T>, T> extends AbstractRepository<M, T> {
|
||||
|
||||
@Autowired
|
||||
protected M baseMapper;
|
||||
|
||||
@Override
|
||||
public M getBaseMapper() {
|
||||
Assert.notNull(this.baseMapper, "baseMapper can not be null");
|
||||
return this.baseMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入
|
||||
*
|
||||
* @param entityList ignore
|
||||
* @param batchSize ignore
|
||||
* @return ignore
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean saveBatch(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取mapperStatementId
|
||||
*
|
||||
* @param sqlMethod 方法名
|
||||
* @return 命名id
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected String getSqlStatement(SqlMethod sqlMethod) {
|
||||
return SqlHelper.getSqlStatement(this.getMapperClass(), sqlMethod);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
|
||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.getEntityClass());
|
||||
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
|
||||
String keyProperty = tableInfo.getKeyProperty();
|
||||
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
|
||||
return SqlHelper.saveOrUpdateBatch(getSqlSessionFactory(), this.getMapperClass(), this.log, entityList, batchSize, (sqlSession, entity) -> {
|
||||
Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
|
||||
return StringUtils.checkValNull(idVal)
|
||||
|| CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
|
||||
}, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean updateBatchById(Collection<T> entityList, int batchSize) {
|
||||
String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
|
||||
return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
|
||||
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
|
||||
param.put(Constants.ENTITY, entity);
|
||||
sqlSession.update(sqlStatement, param);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.repository.IRepository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 顶级 Service
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
public interface IService<T> extends IRepository<T> {
|
||||
|
||||
/**
|
||||
* 插入(批量)
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean saveBatch(Collection<T> entityList) {
|
||||
return saveBatch(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改插入
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean saveOrUpdateBatch(Collection<T> entityList) {
|
||||
return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除(jdbc批量提交)
|
||||
*
|
||||
* @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
|
||||
* @return 删除结果
|
||||
* @since 3.5.0
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean removeBatchByIds(Collection<?> list) {
|
||||
return removeByIds(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID 批量更新
|
||||
*
|
||||
* @param entityList 实体对象集合
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
default boolean updateBatchById(Collection<T> entityList) {
|
||||
return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.repository.CrudRepository;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-23
|
||||
*/
|
||||
public class ServiceImpl<M extends BaseMapper<T>, T> extends CrudRepository<M, T> implements IService<T> {
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2024, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* 通用 service 实现
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-08
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.service.impl;
|
@ -14,6 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* Spring相关类
|
||||
* 通用 Service 接口
|
||||
*
|
||||
* @author hubin
|
||||
* @since 2018-06-08
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.spring;
|
||||
package com.baomidou.mybatisplus.extension.service;
|
@ -15,11 +15,7 @@
|
||||
*/
|
||||
package com.baomidou.mybatisplus.extension.spring;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
|
||||
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
|
||||
import com.baomidou.mybatisplus.core.MybatisXMLConfigBuilder;
|
||||
import com.baomidou.mybatisplus.core.MybatisXMLMapperBuilder;
|
||||
import com.baomidou.mybatisplus.core.*;
|
||||
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
@ -61,13 +57,7 @@ import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -10,7 +10,6 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
@ -16,7 +16,6 @@ import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
|
||||
import static com.baomidou.mybatisplus.core.enums.SqlMethod.UPSERT_ONE;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
@ -13,8 +13,6 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author miemie
|
||||
* @since 2021-03-16
|
||||
|
@ -1,16 +1,15 @@
|
||||
package com.baomidou.mybatisplus.test.toolkit;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
import com.baomidou.mybatisplus.test.BaseDbTest;
|
||||
import com.baomidou.mybatisplus.test.rewrite.Entity;
|
||||
import com.baomidou.mybatisplus.test.rewrite.EntityMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* SqlHelper 工具类测试
|
||||
|
@ -21,6 +21,8 @@ include 'mybatis-plus-annotation'
|
||||
include 'mybatis-plus-extension'
|
||||
include 'mybatis-plus-generator'
|
||||
include 'mybatis-plus-bom'
|
||||
include 'mybatis-plus-spring'
|
||||
include 'mybatis-plus-solon-plugin'
|
||||
include 'spring-boot-starter'
|
||||
include ':spring-boot-starter:mybatis-plus-boot-starter'
|
||||
include ':spring-boot-starter:mybatis-plus-boot-starter-test'
|
||||
|
@ -1,4 +1,6 @@
|
||||
dependencies {
|
||||
api project(":mybatis-plus-spring")
|
||||
|
||||
implementation project(":mybatis-plus")
|
||||
implementation "${lib."mybatis-spring"}"
|
||||
implementation "org.springframework.boot:spring-boot-autoconfigure:${springBootVersion}"
|
||||
|
@ -24,6 +24,8 @@ import com.baomidou.mybatisplus.core.handlers.PostInitTableInfoHandler;
|
||||
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
|
||||
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
|
||||
import com.baomidou.mybatisplus.extension.compatible.CompatibleHelper;
|
||||
import com.baomidou.mybatisplus.extension.compatible.SpringCompatibleSet;
|
||||
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.mapping.DatabaseIdProvider;
|
||||
@ -148,6 +150,9 @@ public class MybatisPlusAutoConfiguration implements InitializingBean {
|
||||
this.sqlSessionFactoryBeanCustomizers = sqlSessionFactoryBeanCustomizers.getIfAvailable();
|
||||
this.mybatisPlusPropertiesCustomizers = mybatisPlusPropertiesCustomizerProvider.getIfAvailable();
|
||||
this.applicationContext = applicationContext;
|
||||
|
||||
// 注入兼容配置
|
||||
CompatibleHelper.setCompatibleSet(new SpringCompatibleSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user