mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 09:08:24 +08:00
feat: add Mappers.java
This commit is contained in:
parent
269cb1354d
commit
1d868a0940
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user