feat: add Mappers.java

This commit is contained in:
开源海哥 2023-07-24 16:55:36 +08:00
parent 269cb1354d
commit 1d868a0940
5 changed files with 129 additions and 49 deletions

View File

@ -18,24 +18,18 @@ package com.mybatisflex.core;
import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder;
import com.mybatisflex.core.mybatis.Mappers;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.util.MapUtil;
import javax.sql.DataSource;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
/**
* MybatisFlex 的启动类
@ -62,10 +56,8 @@ public class MybatisFlexBootstrap {
protected Configuration configuration;
protected List<Class<?>> mappers;
protected SqlSessionFactory sqlSessionFactory;
protected Class<? extends Log> logImpl;
private final Map<Class<?>, Object> mapperObjects = new ConcurrentHashMap<>();
/**
* 虽然提供了 getInstance但也允许用户进行实例化
@ -120,7 +112,7 @@ public class MybatisFlexBootstrap {
}
//init sqlSessionFactory
this.sqlSessionFactory = new FlexSqlSessionFactoryBuilder().build(configuration);
new FlexSqlSessionFactoryBuilder().build(configuration);
//init mappers
if (mappers != null) {
@ -134,20 +126,6 @@ public class MybatisFlexBootstrap {
}
@Deprecated
public <R, T> R execute(Class<T> mapperClass, Function<T, R> function) {
try (SqlSession sqlSession = openSession()) {
T mapper = sqlSession.getMapper(mapperClass);
return function.apply(mapper);
}
}
protected SqlSession openSession() {
return sqlSessionFactory.openSession(configuration.getDefaultExecutorType(), true);
}
/**
* 直接获取 mapper 对象执行
*
@ -155,16 +133,7 @@ public class MybatisFlexBootstrap {
* @return mapperObject
*/
public <T> T getMapper(Class<T> mapperClass) {
Object mapperObject = MapUtil.computeIfAbsent(mapperObjects, mapperClass, clazz ->
Proxy.newProxyInstance(mapperClass.getClassLoader()
, new Class[]{mapperClass}
, (proxy, method, args) -> {
try (SqlSession sqlSession = openSession()) {
T mapper1 = sqlSession.getMapper(mapperClass);
return method.invoke(mapper1, args);
}
}));
return (T) mapperObject;
return Mappers.ofMapperClass(mapperClass);
}
@ -224,15 +193,6 @@ public class MybatisFlexBootstrap {
}
public SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
public MybatisFlexBootstrap setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
return this;
}
public Class<? extends Log> getLogImpl() {
return logImpl;
}

View File

@ -47,7 +47,6 @@ import org.apache.ibatis.util.MapUtil;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -318,7 +317,9 @@ public class FlexConfiguration extends Configuration {
for (Type genericInterface : genericInterfaces) {
if (genericInterface instanceof ParameterizedType) {
Type actualTypeArgument = ((ParameterizedType) genericInterface).getActualTypeArguments()[0];
if (actualTypeArgument instanceof TypeVariable) {
if (actualTypeArgument instanceof Class) {
Mappers.addMapping((Class<?>) actualTypeArgument, type);
} else {
isGenericInterface = true;
break;
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.mybatisflex.core.mybatis;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.exception.FlexExceptions;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.util.MapUtil;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author michael
*/
@SuppressWarnings("unchecked")
public class Mappers {
private static final Map<Class<?>, Class<?>> ENTITY_MAPPER_MAP = new ConcurrentHashMap<>();
private static final Map<Class<?>, Object> MAPPER_OBJECTS = new ConcurrentHashMap<>();
static void addMapping(Class<?> entityClass, Class<?> mapperClass) {
ENTITY_MAPPER_MAP.put(entityClass, mapperClass);
}
/**
* 通过 entity Class 获取 Mapper 对象
* @param entityClass
* @param <Entity>
* @return mapper 对象
*/
public static <Entity> BaseMapper<Entity> ofEntityClass(Class<Entity> entityClass) {
Class<?> mapperClass = ENTITY_MAPPER_MAP.get(entityClass);
if (mapperClass == null) {
throw FlexExceptions.wrap("Can not find MapperClass by entity: " + entityClass);
}
return (BaseMapper<Entity>) ofMapperClass(mapperClass);
}
/**
* 通过 mapperClass 直接获取 mapper 对象执行
*
* @param mapperClass
* @return mapperObject
*/
public static <Mapper> Mapper ofMapperClass(Class<Mapper> mapperClass) {
Object mapperObject = MapUtil.computeIfAbsent(MAPPER_OBJECTS, mapperClass, clazz ->
Proxy.newProxyInstance(mapperClass.getClassLoader()
, new Class[]{mapperClass}
, new MapperHandler(mapperClass)));
return (Mapper) mapperObject;
}
static class MapperHandler implements InvocationHandler {
private Class<?> mapperClass;
private final SqlSessionFactory sqlSessionFactory = FlexGlobalConfig.getDefaultConfig().getSqlSessionFactory();
private final ExecutorType executorType = FlexGlobalConfig.getDefaultConfig().getConfiguration().getDefaultExecutorType();
public MapperHandler(Class<?> mapperClass) {
this.mapperClass = mapperClass;
}
private SqlSession openSession() {
return sqlSessionFactory.openSession(executorType, true);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try (SqlSession sqlSession = openSession()) {
Object mapper = sqlSession.getMapper(mapperClass);
return method.invoke(mapper, args);
}
}
}
}

View File

@ -51,17 +51,26 @@ public class TableDefs implements Serializable {
}
}
public static QueryColumn getQueryColumn(Class<?> entityClass, String key, String column) {
public static TableDef getTableDef(Class<?> entityClass, String tableNameWithSchema) {
if (TABLE_DEF_MAP.isEmpty()) {
init(entityClass.getPackage().getName());
}
Map<String, QueryColumn> queryColumnMap = QUERY_COLUMN_MAP.get(key);
return TABLE_DEF_MAP.get(tableNameWithSchema);
}
public static QueryColumn getQueryColumn(Class<?> entityClass, String tableNameWithSchema, String column) {
if (TABLE_DEF_MAP.isEmpty()) {
init(entityClass.getPackage().getName());
}
Map<String, QueryColumn> queryColumnMap = QUERY_COLUMN_MAP.get(tableNameWithSchema);
return queryColumnMap != null ? queryColumnMap.get(column) : null;
}
public static void registerTableDef(Class<?> clazz) throws IllegalAccessException {
TableDef tableDef = (TableDef) ClassUtil.getFirstField(clazz, field -> {
public static void registerTableDef(Class<?> tableDefClass) throws IllegalAccessException {
TableDef tableDef = (TableDef) ClassUtil.getFirstField(tableDefClass, field -> {
int mod = Modifier.fieldModifiers();
return Modifier.isPublic(mod) && Modifier.isStatic(mod);
}).get(null);

View File

@ -19,6 +19,7 @@ import com.mybatisflex.core.MybatisFlexBootstrap;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector;
import com.mybatisflex.core.mybatis.Mappers;
import com.mybatisflex.core.query.If;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.DbChain;
@ -73,6 +74,14 @@ public class AccountTester {
.where(ACCOUNT.ID.ge(1))
.listAs(Account.class)
.forEach(System.out::println);
AccountMapper accountBaseMapper = (AccountMapper) Mappers.ofEntityClass(Account.class);
AccountMapper accountMapper = Mappers.ofMapperClass(AccountMapper.class);
System.out.println(">>>>> : " + (accountBaseMapper == accountMapper));
Account account = accountBaseMapper.selectOneById(1);
System.out.println(">>>> account: " + account);
}
@Test