diff --git a/build.gradle b/build.gradle
index 1cfd7b8271638ac37e177e1d83b84eb86b25dd52..da9c6096cc370a836b832a52e77e7666cda753d1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ apply plugin: 'signing'
buildscript {
ext {
mybatisPlusVersion = "3.5.9"
- solonVersion = "3.0.1"
+ solonVersion = "3.0.2"
}
// 仓库配置
@@ -42,9 +42,13 @@ dependencies {
api("org.noear:mybatis-solon-plugin:${solonVersion}")
api("org.noear:solon-aot:${solonVersion}")
+ testImplementation("com.baomidou:mybatis-plus-jsqlparser-4.9:${mybatisPlusVersion}")
testImplementation("org.noear:solon-test:${solonVersion}")
- testImplementation("io.github.classgraph:classgraph:4.8.176")
+ testImplementation("org.noear:solon-data-sqlutils:${solonVersion}")
+ testImplementation("org.noear:solon-web:${solonVersion}")
testImplementation("com.zaxxer:HikariCP:4.0.3")
+ testImplementation("com.h2database:h2:2.3.232")
+ testImplementation("org.projectlombok:lombok:1.18.34")
}
// 编译环境 JDK-1.8+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a7af2001befe504065f01017a9cd46cc2771f6aa
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,86 @@
+
+
+ 4.0.0
+
+ com.baomidou
+ mybatis-plus-solon-plugin
+ 3.5.9
+ jar
+
+
+ 3.0.2
+
+
+
+
+ com.baomidou
+ mybatis-plus-extension
+ ${project.version}
+
+
+
+ org.noear
+ mybatis-solon-plugin
+ ${solon.version}
+
+
+
+ org.noear
+ solon-aot
+ ${solon.version}
+ provided
+
+
+
+ org.noear
+ solon-test
+ ${solon.version}
+ test
+
+
+
+ org.noear
+ solon-data-sqlutils
+ ${solon.version}
+ test
+
+
+
+ org.noear
+ solon-web
+ ${solon.version}
+ test
+
+
+
+ com.baomidou
+ mybatis-plus-jsqlparser-4.9
+ ${project.version}
+ test
+
+
+
+ com.zaxxer
+ HikariCP
+ 4.0.3
+ test
+
+
+
+ com.h2database
+ h2
+ 2.3.232
+ test
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.34
+ test
+
+
+
+
diff --git a/src/main/java/com/baomidou/mybatisplus/extension/repository/CrudRepository.java b/src/main/java/com/baomidou/mybatisplus/extension/repository/CrudRepository.java
index 7e4e46b28fd8e3456ecce3008d69ad29917cb709..2ba65139705e887f465b8a2ba4340b2d9e5b7f0e 100644
--- a/src/main/java/com/baomidou/mybatisplus/extension/repository/CrudRepository.java
+++ b/src/main/java/com/baomidou/mybatisplus/extension/repository/CrudRepository.java
@@ -47,6 +47,15 @@ public abstract class CrudRepository, T> extends Abstrac
return this.baseMapper;
}
+ /**
+ * 设置 baseMapper(用于支持 Db 注入 CrudRepository)
+ *
+ * @author noear
+ * */
+ public void setBaseMapper(M baseMapper) {
+ this.baseMapper = baseMapper;
+ }
+
/**
* 批量插入
*
diff --git a/src/main/java/com/baomidou/mybatisplus/solon/integration/MybatisAdapterPlus.java b/src/main/java/com/baomidou/mybatisplus/solon/integration/MybatisAdapterPlus.java
index 7bf9bde8fe1fb3a4a564c33766ae03a310c398f1..5f470df8d3b8ce7c4ec78b79cecb3605c557c373 100644
--- a/src/main/java/com/baomidou/mybatisplus/solon/integration/MybatisAdapterPlus.java
+++ b/src/main/java/com/baomidou/mybatisplus/solon/integration/MybatisAdapterPlus.java
@@ -3,8 +3,11 @@ 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.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.override.SolonMybatisMapperProxy;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
+import com.baomidou.mybatisplus.extension.repository.CrudRepository;
+import com.baomidou.mybatisplus.extension.repository.IRepository;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
@@ -105,6 +108,7 @@ public class MybatisAdapterPlus extends MybatisAdapterDefault {
return sqlSession;
}
+ @SuppressWarnings("unchecked")
@Override
public T getMapper(Class mapperClz) {
Object mapper = mapperCached.get(mapperClz);
@@ -134,13 +138,72 @@ public class MybatisAdapterPlus extends MybatisAdapterDefault {
}
@Override
- public void injectTo(VarHolder varH) {
- super.injectTo(varH);
+ public void injectTo(VarHolder vh) {
+ if (IRepository.class.isAssignableFrom(vh.getType())) {
+ vh.context().getWrapAsync(vh.getType(), serviceBw -> {
+ if (serviceBw.raw() instanceof CrudRepository) {
+ //如果是 ServiceImpl
+ injectService(vh, serviceBw);
+ } else {
+ //如果不是 ServiceImpl
+ vh.setValue(serviceBw.get());
+ }
+ });
+ return;
+ }
//@Db("db1") SqlSessionFactory factory;
- if (GlobalConfig.class.isAssignableFrom(varH.getType())) {
- varH.setValue(this.getGlobalConfig());
+ if (GlobalConfig.class.isAssignableFrom(vh.getType())) {
+ vh.setValue(this.getGlobalConfig());
return;
}
+
+ super.injectTo(vh);
+
+
+ }
+
+ /**
+ * 服务缓存
+ */
+ private Map, CrudRepository> repositoryCached = new HashMap<>();
+
+ /**
+ * 注入服务 IService
+ */
+ @SuppressWarnings("unchecked")
+ private void injectService(VarHolder vh, BeanWrap serviceBw) {
+ CrudRepository repository = serviceBw.raw();
+
+ if (repositoryCached.containsKey(vh.getType())) {
+ //从缓存获取
+ repository = repositoryCached.get(vh.getType());
+ } else {
+ Object baseMapperOld = repository.getBaseMapper();
+
+ if (baseMapperOld != null) {
+ Class> baseMapperClass = null;
+ for (Class> clz : baseMapperOld.getClass().getInterfaces()) {
+ //baseMapperOld.getClass() 是个代理类,所以要从基类接口拿
+ if (BaseMapper.class.isAssignableFrom(clz)) {
+ baseMapperClass = clz;
+ break;
+ }
+ }
+
+ if (baseMapperClass != null) {
+ //如果有 baseMapper ,说明正常;;创建新实例,并更换 baseMapper
+ repository = serviceBw.create();
+
+ BaseMapper baseMapper = (BaseMapper) this.getMapper(baseMapperClass);
+ repository.setBaseMapper(baseMapper);
+
+ //缓存
+ repositoryCached.put(vh.getType(), repository);
+ }
+ }
+ }
+
+ vh.setValue(repository);
}
}
diff --git a/src/test/java/demo/Config.java b/src/test/java/demo/Config.java
index c3ed33dbd4ee9d8680d770a5d6d688aae991cf8d..f585152c8994d1f47ea252d538ae4bae3ff71a77 100644
--- a/src/test/java/demo/Config.java
+++ b/src/test/java/demo/Config.java
@@ -1,29 +1,49 @@
package demo;
+import com.baomidou.mybatisplus.annotation.DbType;
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 demo.dso.MetaObjectHandlerImpl;
-import demo.dso.MybatisSqlSessionFactoryBuilderImpl;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import demo.dso.mybatisplus_ext.MyLogicSqlInjector;
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;
+import org.noear.solon.core.util.ResourceUtil;
+import org.noear.solon.data.sql.SqlUtils;
@Configuration
public class Config {
+//有 “solon.dataSources” 配置后,不需要手动构建 bean
+// @Bean(value = "db1", typed = true)
+// public DataSource db1(@Inject("${test.db1}") HikariDataSource ds) {
+// return ds;
+// }
+
@Bean
- public void db1_cfg(@Db("db1") MybatisConfiguration cfg,
- @Db("db1") GlobalConfig globalConfig) {
- //增加 mybatis-plus 的自带分页插件
+ public void db1_cfg(
+ @Inject SqlUtils sqlUtils,
+ @Db("db1") MybatisConfiguration cfg,
+ @Db("db1") GlobalConfig globalConfig) throws Exception {
+
+ String sql = ResourceUtil.getResourceAsString("db.sql");
+
+ for (String s1 : sql.split(";")) {
+ if (s1.trim().length() > 10) {
+ sqlUtils.sql(s1).update();
+ }
+ }
+
+ ////
+
MybatisPlusInterceptor plusInterceptor = new MybatisPlusInterceptor();
- plusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
+ plusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
+ cfg.setCacheEnabled(false);
cfg.addInterceptor(plusInterceptor);
+
+ globalConfig.setSqlInjector(new MyLogicSqlInjector());
}
// @Bean
@@ -31,4 +51,3 @@ public class Config {
// return new MybatisSqlSessionFactoryBuilderImpl();
// }
}
-
diff --git a/src/test/java/demo/DemoApp.java b/src/test/java/demo/DemoApp.java
index 3ce885e1ffd0c14df0755286f8059ed68609a5a1..a48270dc4734018fa1f2e37fcb02871d6dd488a9 100644
--- a/src/test/java/demo/DemoApp.java
+++ b/src/test/java/demo/DemoApp.java
@@ -1,22 +1,31 @@
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;
+import org.noear.solon.annotation.SolonMain;
/**
- * @author noear 2021/7/12 created
- */
+ *
+ * 演示用到的表结构::
+ *
+ * CREATE TABLE `appx` (
+ * `app_id` int NOT NULL AUTO_INCREMENT COMMENT '应用ID',
+ * `app_key` varchar(40) DEFAULT NULL COMMENT '应用访问KEY',
+ * `akey` varchar(40) DEFAULT NULL COMMENT '(用于取代app id 形成的唯一key) //一般用于推广注册之类',
+ * `ugroup_id` int DEFAULT '0' COMMENT '加入的用户组ID',
+ * `agroup_id` int DEFAULT NULL COMMENT '加入的应用组ID',
+ * `name` varchar(50) DEFAULT NULL COMMENT '应用名称',
+ * `note` varchar(50) DEFAULT NULL COMMENT '应用备注',
+ * `ar_is_setting` int NOT NULL DEFAULT '0' COMMENT '是否开放设置',
+ * `ar_is_examine` int NOT NULL DEFAULT '0' COMMENT '是否审核中(0: 没审核 ;1:审核中)',
+ * `ar_examine_ver` int NOT NULL DEFAULT '0' COMMENT '审核 中的版本号',
+ * `log_fulltime` datetime DEFAULT NULL,
+ * PRIMARY KEY (`app_id`),
+ * UNIQUE KEY `IX_akey` (`akey`) USING BTREE
+ * ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='应用表';
+ * */
+@SolonMain
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(), "查询结果异常");
}
}
diff --git a/src/test/java/demo/controller/DemoController.java b/src/test/java/demo/controller/DemoController.java
new file mode 100644
index 0000000000000000000000000000000000000000..74bd842b244b89d81577fe407e95c37ee78ab3ad
--- /dev/null
+++ b/src/test/java/demo/controller/DemoController.java
@@ -0,0 +1,23 @@
+package demo.controller;
+
+import demo.dso.mapper.AppxMapper;
+import demo.model.AppxModel;
+import org.apache.ibatis.solon.annotation.Db;
+import org.noear.solon.annotation.Controller;
+import org.noear.solon.annotation.Mapping;
+
+/**
+ * 分包模式,一开始就被会话工厂mapperScan()并关联好了
+ * */
+@Mapping("/demo/")
+@Controller
+public class DemoController {
+ @Db
+ AppxMapper appxMapper;
+
+ @Mapping("test")
+ public AppxModel test(){
+ return appxMapper.appx_get();
+ }
+
+}
diff --git a/src/test/java/demo/controller/IndexController.java b/src/test/java/demo/controller/IndexController.java
deleted file mode 100644
index d3313718394074ae7a6c64fd8be684dd644d88e9..0000000000000000000000000000000000000000
--- a/src/test/java/demo/controller/IndexController.java
+++ /dev/null
@@ -1,21 +0,0 @@
-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 index() {
- return userService.getUserList();
- }
-}
diff --git a/src/test/java/demo/controller/PageController.java b/src/test/java/demo/controller/PageController.java
new file mode 100644
index 0000000000000000000000000000000000000000..21099ce5dcd414a3df2b4b1e7e8d30f452b5f6c4
--- /dev/null
+++ b/src/test/java/demo/controller/PageController.java
@@ -0,0 +1,26 @@
+package demo.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import demo.dso.mapper.AppxMapper;
+import demo.model.AppxModel;
+import org.apache.ibatis.solon.annotation.Db;
+import org.noear.solon.annotation.Controller;
+import org.noear.solon.annotation.Mapping;
+
+/**
+ * 分面演示(使用sqlhelper组件)
+ *
+ * */
+@Mapping("/page/")
+@Controller
+public class PageController {
+ @Db
+ AppxMapper appxMapper;
+
+ @Mapping("test")
+ public Object test() throws Throwable {
+ Page page = new Page<>(2, 2);
+
+ return appxMapper.appx_get_page(page);
+ }
+}
diff --git a/src/test/java/demo/controller/PlusController.java b/src/test/java/demo/controller/PlusController.java
new file mode 100644
index 0000000000000000000000000000000000000000..81d4b495d806a5e6dc69235caa903d69fe1d199d
--- /dev/null
+++ b/src/test/java/demo/controller/PlusController.java
@@ -0,0 +1,22 @@
+package demo.controller;
+
+import demo.dso.service.AppServicePlus;
+import demo.model.AppxModel;
+import org.apache.ibatis.solon.annotation.Db;
+import org.noear.solon.annotation.Controller;
+import org.noear.solon.annotation.Mapping;
+
+/**
+ * @author noear 2022/3/28 created
+ */
+@Mapping("/plus/")
+@Controller
+public class PlusController {
+ @Db
+ AppServicePlus appServicePlus;
+
+ @Mapping("test")
+ public AppxModel test() {
+ return appServicePlus.getById(12);
+ }
+}
diff --git a/src/test/java/demo/controller/TranController.java b/src/test/java/demo/controller/TranController.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a405f2776e0824456cee6b5feaaf16e30c172c4
--- /dev/null
+++ b/src/test/java/demo/controller/TranController.java
@@ -0,0 +1,119 @@
+package demo.controller;
+
+import demo.dso.service.AppService;
+import org.noear.solon.annotation.Controller;
+import org.noear.solon.annotation.Inject;
+import org.noear.solon.annotation.Mapping;
+import org.noear.solon.data.annotation.Tran;
+
+@Mapping("/tran/")
+@Controller
+public class TranController {
+ @Inject
+ AppService appService;
+
+ @Tran
+ @Mapping("test")
+ public void test() throws Exception {
+ //添加会成功
+ //
+ appService.addApp();
+ appService.addApp();
+ }
+
+ @Tran
+ @Mapping("test2")
+ public void test2() throws Exception {
+ //添加会失败,因为在事务里出异常了
+ //
+ appService.addApp();
+ appService.addApp();
+
+ throw new RuntimeException("不让你加");
+ }
+
+ @Mapping("test11")
+ public void test11() throws Exception {
+ //添加会成功
+ //
+ appService.addApp2();
+ }
+
+ @Mapping("test12")
+ public void test12() throws Exception {
+ //添加会成功(因为异常在事务之外) // addApp2 有事务
+ //
+ appService.addApp2();
+
+ throw new RuntimeException("不让你加;但还是加了:(");
+ }
+
+ @Tran
+ @Mapping("test21")
+ public void test21() throws Exception {
+ appService.addApp2();
+ }
+
+ @Tran
+ @Mapping("test22")
+ public void test22() throws Exception {
+ //添加会失败,因为在事务里出异常了
+ //
+ appService.addApp2();
+
+ throw new RuntimeException("不让你加");
+ }
+
+ @Tran
+ @Mapping("test41")
+ public void test41() throws Exception {
+ //添加会成功
+ //
+ appService.addApp3();
+
+ throw new RuntimeException("不让你加,但还是成功了:(");
+ }
+
+ @Tran
+ @Mapping("test51")
+ public void test51() throws Exception {
+ //添加会成功,因为addApp4是独立的新事务
+ //
+ appService.addApp4();
+
+ throw new RuntimeException("不让你加,但还是成功了:(");
+ }
+
+ @Tran
+ @Mapping("test61")
+ public void test61() throws Exception {
+ //会失败
+ //
+ appService.addApp5();
+
+ }
+
+
+ @Mapping("test63")
+ public void test63() throws Exception {
+ //添加会成功
+ //
+ appService.addApp5();
+ }
+
+ @Tran
+ @Mapping("test71")
+ public void test71() throws Exception {
+ //会成功
+ //
+ appService.addApp6();
+
+ }
+
+ @Mapping("test73")
+ public void test73() throws Exception {
+ //会失败
+ //
+ appService.addApp6();
+ }
+}
diff --git a/src/test/java/demo/dso/MetaObjectHandlerImpl.java b/src/test/java/demo/dso/MetaObjectHandlerImpl.java
index 3e7bc842f0d04b602212b7483b5f67dd8a11cbc5..93cc74088458a519ab11abafa8f34c817006d91c 100644
--- a/src/test/java/demo/dso/MetaObjectHandlerImpl.java
+++ b/src/test/java/demo/dso/MetaObjectHandlerImpl.java
@@ -7,6 +7,9 @@ import org.apache.ibatis.reflection.MetaObject;
* @author noear 2022/4/17 created
*/
public class MetaObjectHandlerImpl implements MetaObjectHandler {
+ public MetaObjectHandlerImpl(){
+ System.out.println("....MetaObjectHandlerImpl");
+ }
@Override
public void insertFill(MetaObject metaObject) {
diff --git a/src/test/java/demo/dso/MybatisSqlSessionFactoryBuilderImpl.java b/src/test/java/demo/dso/MybatisSqlSessionFactoryBuilderImpl.java
index 184fc9a7d64d316ec1185df82f0fbdd764f6a730..ac2305a2569db3488a4439c2c9d0b9a7b3193d87 100644
--- a/src/test/java/demo/dso/MybatisSqlSessionFactoryBuilderImpl.java
+++ b/src/test/java/demo/dso/MybatisSqlSessionFactoryBuilderImpl.java
@@ -1,9 +1,16 @@
package demo.dso;
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSessionFactory;
/**
* @author noear 2021/10/20 created
*/
public class MybatisSqlSessionFactoryBuilderImpl extends MybatisSqlSessionFactoryBuilder {
+ @Override
+ public SqlSessionFactory build(Configuration configuration) {
+ System.out.println(".进来了.");
+ return super.build(configuration);
+ }
}
diff --git a/src/test/java/demo/dso/mapper/AppxMapper.java b/src/test/java/demo/dso/mapper/AppxMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..66457c4a272f52801b089373ba4c13ef67ac2b24
--- /dev/null
+++ b/src/test/java/demo/dso/mapper/AppxMapper.java
@@ -0,0 +1,26 @@
+package demo.dso.mapper;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import demo.model.AppxModel;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface AppxMapper {
+ AppxModel appx_get();
+
+ Page appx_get_page(Page page);
+
+ AppxModel appx_get2(int app_id);
+
+ void appx_add();
+
+ Long appx_add2(int v1);
+
+ @Select("SELECT * FROM appx")
+ List