!516 优化 mapper bean 生成方式;文档补充 solon 相关配置内容

Merge pull request !516 from 西东/main
This commit is contained in:
Michael Yang 2025-01-01 02:38:18 +00:00 committed by Gitee
commit 1af1929cd9
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 186 additions and 46 deletions

View File

@ -1,6 +1,6 @@
# SpringBoot 配置文件 # SpringBoot 或 Solon 配置文件
SpringBoot 配置文件(`application.yml` 等)主要是用于对 MyBatis 原生以及 MyBatis-Flex 的 `FlexGlobalConfig` 进行配置。 SpringBoot 配置文件(`application.yml` 等)Solon 配置文件(`app.yml` 等)。主要是用于对 MyBatis 原生以及 MyBatis-Flex 的 `FlexGlobalConfig` 进行配置。
示例如下: 示例如下:
@ -26,7 +26,7 @@ mybatis-flex:
- 类型:`Map<String, Map<String, String>>` - 类型:`Map<String, Map<String, String>>`
- 默认值:`null` - 默认值:`null`
MyBatis-Flex 多数据源配置,参考 [多数据源配置](../core/multi-datasource.md#更多的-spring-yaml-配置支持)。 MyBatis-Flex 多数据源配置,参考 [多数据源配置](../core/multi-datasource.md#更多的 Spring 或 Solon Yaml 配置支持)。
### config-location ### config-location
@ -203,7 +203,7 @@ mybatis-flex:
### seata-mode ### seata-mode
- 类型:`com.mybatisflex.spring.boot.MybatisFlexProperties.SeataMode` - 类型:`com.mybatisflex.spring.boot.MybatisFlexProperties.SeataMode`,或者 `com.mybatisflex.solon.MybatisFlexProperties.SeataMode`
- 默认值:`AT` - 默认值:`AT`
使用 Seata AT 模式代理数据源。 使用 Seata AT 模式代理数据源。

View File

@ -18,7 +18,7 @@ mybatis-flex:
在以上配置中,`ds1``ds2` 是由用户自定义的,我们可以理解为数据源的名称,或者数据源的 `key`,这个在动态切换数据库中非常有用。 在以上配置中,`ds1``ds2` 是由用户自定义的,我们可以理解为数据源的名称,或者数据源的 `key`,这个在动态切换数据库中非常有用。
在无 Spring 框架的场景下,代码如下: 在无 Spring 或 Solon 框架的场景下,代码如下:
```java ```java
DataSource dataSource1 = new HikariDataSource(); DataSource dataSource1 = new HikariDataSource();
@ -72,7 +72,7 @@ MyBatis-Flex 提供了 4 种方式来配置数据源:
- 3、`@UseDataSource("dataSourceName")` 在 Mapper 方法上,添加注解,用于指定使用哪个数据源。 - 3、`@UseDataSource("dataSourceName")` 在 Mapper 方法上,添加注解,用于指定使用哪个数据源。
- 4、`@Table(dataSource="dataSourceName")` 在 Entity 类上添加注解,该 Entity 的增删改查请求默认使用该数据源。 - 4、`@Table(dataSource="dataSourceName")` 在 Entity 类上添加注解,该 Entity 的增删改查请求默认使用该数据源。
> 在 SpringBoot 项目上,`@UseDataSource("dataSourceName")` 也可用于在 Controller 或者 Service 上。若是 Spring 项目(非 SpringBoot, > 在 SpringBoot 或 Solon 项目上,`@UseDataSource("dataSourceName")` 也可用于在 Controller 或者 Service 上。若是 Spring 项目(非 SpringBoot,
> 用户需要参考 `MultiDataSourceAutoConfiguration` 进行配置后才能使用。 > 用户需要参考 `MultiDataSourceAutoConfiguration` 进行配置后才能使用。
@ -123,7 +123,7 @@ public class Account {
`DataSourceKey.use()` > `@UseDataSource()在方法上` > `@UseDataSource()在类上` >`@Table(dataSource="...")` `DataSourceKey.use()` > `@UseDataSource()在方法上` > `@UseDataSource()在类上` >`@Table(dataSource="...")`
::: :::
## 更多的 Spring Yaml 配置支持 ## 更多的 Spring 或 Solon Yaml 配置支持
```yaml ```yaml
mybatis-flex: mybatis-flex:
datasource: datasource:

View File

@ -6,8 +6,8 @@ import com.mybatisflex.core.MybatisFlexBootstrap;
import com.mybatisflex.core.mybatis.FlexConfiguration; import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder; import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder;
import com.mybatisflex.core.row.RowMapperInvoker; import com.mybatisflex.core.row.RowMapperInvoker;
import com.mybatisflex.solon.transaction.MybatisMapperInterceptor;
import com.mybatisflex.solon.transaction.SolonManagedTransactionFactory; import com.mybatisflex.solon.transaction.SolonManagedTransactionFactory;
import com.mybatisflex.solon.transaction.MybatisSessionTemplate;
import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.io.Resources;
@ -171,13 +171,10 @@ public class MybatisFlexAutoConfiguration {
public void mapperPublish(FlexConfiguration flexConfiguration, public void mapperPublish(FlexConfiguration flexConfiguration,
FlexGlobalConfig globalConfig, FlexGlobalConfig globalConfig,
SqlSessionFactory sqlSessionFactory) { SqlSessionFactory sqlSessionFactory) {
for (Class<?> mapperClz : flexConfiguration.getMapperRegistry().getMappers()) { MybatisSessionTemplate sqlSessionTemplate = new MybatisSessionTemplate(sqlSessionFactory);
MybatisMapperInterceptor handler = new MybatisMapperInterceptor(sqlSessionFactory, mapperClz);
Object mapperProxy = Proxy.newProxyInstance( for (Class<?> mapperClz : flexConfiguration.getMapperRegistry().getMappers()) {
mapperClz.getClassLoader(), Object mapperProxy = sqlSessionTemplate.getMapper(mapperClz);
new Class[]{mapperClz},
handler);
//推入容器之后可以被注入 //推入容器之后可以被注入
appContext.wrapAndPut(mapperClz, mapperProxy); appContext.wrapAndPut(mapperClz, mapperProxy);

View File

@ -1,31 +0,0 @@
package com.mybatisflex.solon.transaction;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* Mybatis Mapper Interceptor
*
* @author noear
* @since 1.6
*/
public class MybatisMapperInterceptor implements InvocationHandler {
private SqlSessionFactory factory;
private Class<?> mapperClz;
public MybatisMapperInterceptor(SqlSessionFactory factory, Class<?> mapperClz) {
this.factory = factory;
this.mapperClz = mapperClz;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try (SqlSession session = factory.openSession(true)) {
Object mapper = session.getMapper(mapperClz);
return method.invoke(mapper, args);
}
}
}

View File

@ -0,0 +1,174 @@
package com.mybatisflex.solon.transaction;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.session.*;
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;
/**
* @author noear 2024/12/30 created
* @since 3.0
*/
public class MybatisSessionTemplate implements SqlSession {
private final SqlSessionFactory sqlSessionFactory;
private final ExecutorType executorType;
private final SqlSession sqlSessionProxy;
public MybatisSessionTemplate(SqlSessionFactory sqlSessionFactory) {
this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
}
public MybatisSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionInterceptor());
}
public SqlSessionFactory getSqlSessionFactory() {
return this.sqlSessionFactory;
}
public ExecutorType getExecutorType() {
return this.executorType;
}
public <T> T selectOne(String statement) {
return (T) this.sqlSessionProxy.selectOne(statement);
}
public <T> T selectOne(String statement, Object parameter) {
return (T) this.sqlSessionProxy.selectOne(statement, parameter);
}
public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
return this.sqlSessionProxy.selectMap(statement, mapKey);
}
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
return this.sqlSessionProxy.selectMap(statement, parameter, mapKey);
}
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
return this.sqlSessionProxy.selectMap(statement, parameter, mapKey, rowBounds);
}
public <T> Cursor<T> selectCursor(String statement) {
return this.sqlSessionProxy.selectCursor(statement);
}
public <T> Cursor<T> selectCursor(String statement, Object parameter) {
return this.sqlSessionProxy.selectCursor(statement, parameter);
}
public <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) {
return this.sqlSessionProxy.selectCursor(statement, parameter, rowBounds);
}
public <E> List<E> selectList(String statement) {
return this.sqlSessionProxy.selectList(statement);
}
public <E> List<E> selectList(String statement, Object parameter) {
return this.sqlSessionProxy.selectList(statement, parameter);
}
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
return this.sqlSessionProxy.selectList(statement, parameter, rowBounds);
}
public void select(String statement, ResultHandler handler) {
this.sqlSessionProxy.select(statement, handler);
}
public void select(String statement, Object parameter, ResultHandler handler) {
this.sqlSessionProxy.select(statement, parameter, handler);
}
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
}
public int insert(String statement) {
return this.sqlSessionProxy.insert(statement);
}
public int insert(String statement, Object parameter) {
return this.sqlSessionProxy.insert(statement, parameter);
}
public int update(String statement) {
return this.sqlSessionProxy.update(statement);
}
public int update(String statement, Object parameter) {
return this.sqlSessionProxy.update(statement, parameter);
}
public int delete(String statement) {
return this.sqlSessionProxy.delete(statement);
}
public int delete(String statement, Object parameter) {
return this.sqlSessionProxy.delete(statement, parameter);
}
public <T> T getMapper(Class<T> type) {
return (T) this.getConfiguration().getMapper(type, this);
}
public void commit() {
throw new UnsupportedOperationException("Manual commit is not allowed over a Solon managed SqlSession");
}
public void commit(boolean force) {
throw new UnsupportedOperationException("Manual commit is not allowed over a Solon managed SqlSession");
}
public void rollback() {
throw new UnsupportedOperationException("Manual rollback is not allowed over a Solon managed SqlSession");
}
public void rollback(boolean force) {
throw new UnsupportedOperationException("Manual rollback is not allowed over a Solon managed SqlSession");
}
public void close() {
throw new UnsupportedOperationException("Manual close is not allowed over a Solon managed SqlSession");
}
public void clearCache() {
this.sqlSessionProxy.clearCache();
}
public Configuration getConfiguration() {
return this.sqlSessionFactory.getConfiguration();
}
public Connection getConnection() {
return this.sqlSessionProxy.getConnection();
}
public List<BatchResult> flushStatements() {
return this.sqlSessionProxy.flushStatements();
}
public void destroy() throws Exception {
}
private class SqlSessionInterceptor implements InvocationHandler {
private SqlSessionInterceptor() {
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try (SqlSession sqlSession = MybatisSessionTemplate.this.sqlSessionFactory.openSession(MybatisSessionTemplate.this.executorType)) {
return method.invoke(sqlSession, args);
}
}
}
}

View File

@ -19,7 +19,7 @@
<module>mybatis-flex-spring-test</module> <module>mybatis-flex-spring-test</module>
<module>mybatis-flex-spring-boot-test</module> <module>mybatis-flex-spring-boot-test</module>
<module>mybatis-flex-spring-cloud-test</module> <module>mybatis-flex-spring-cloud-test</module>
<!-- <module>mybatis-flex-solon-test</module>--> <module>mybatis-flex-solon-test</module>
</modules> </modules>
<properties> <properties>