From c24ecd29564d9f297a2727411136445d207ef48a Mon Sep 17 00:00:00 2001 From: sglmsn <2450572350@qq.com> Date: Thu, 1 Apr 2021 13:57:21 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E9=9B=86=E6=88=90=E5=A4=9A=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90dynamic-datasource-spring-boot-starter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 31 +++- .../quickstart/service/DynamicService.java | 26 +++ .../quickstart/service/OrganInfoService.java | 9 ++ .../service/TransLedgerService.java | 9 ++ .../service/impl/DynamicServiceImpl.java | 68 ++++++++ .../service/impl/InitDBServiceImpl.java | 18 +-- .../service/impl/InitDBServiceImplLog.java | 105 +++++++++++++ .../service/impl/OrganInfoServiceImpl.java | 13 +- .../service/impl/TransLedgerServiceImpl.java | 20 ++- src/main/resources/application-local.yml | 148 ++++++++++++++++++ src/main/resources/application-server.yml | 147 +++++++++++++++++ src/main/resources/application.yml | 36 +---- src/main/resources/log4j2.xml | 2 +- src/main/resources/spy.properties | 2 + .../sqltoy/quickstart/DynamicQueryTest.java | 46 ++++++ .../sqltoy/quickstart/InitDataBaseTest.java | 21 ++- 16 files changed, 643 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/sqltoy/quickstart/service/DynamicService.java create mode 100644 src/main/java/com/sqltoy/quickstart/service/impl/DynamicServiceImpl.java create mode 100644 src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImplLog.java create mode 100644 src/main/resources/application-local.yml create mode 100644 src/main/resources/application-server.yml create mode 100644 src/main/resources/spy.properties create mode 100644 src/test/java/com/sqltoy/quickstart/DynamicQueryTest.java diff --git a/pom.xml b/pom.xml index 6ba8350..b9401c5 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,8 @@ 2.1.7 + + org.springframework.boot spring-boot-starter @@ -70,21 +72,44 @@ aspectjweaver ${aspectjweaver.version} + com.alibaba druid-spring-boot-starter ${druid.version} + + + org.mariadb.jdbc + mariadb-java-client + 2.7.2 + + + com.baomidou + dynamic-datasource-spring-boot-starter + 3.3.1 + + + p6spy + p6spy + 3.9.1 + com.sagframe sagacity-sqltoy ${sqltoy-starter.version} + + mysql + mysql-connector-java + ${mysql.version} + com.sagframe sagacity-sqltoy-starter ${sqltoy-starter.version} + org.junit.jupiter junit-jupiter-api @@ -98,11 +123,7 @@ test - - mysql - mysql-connector-java - ${mysql.version} - + org.slf4j slf4j-api diff --git a/src/main/java/com/sqltoy/quickstart/service/DynamicService.java b/src/main/java/com/sqltoy/quickstart/service/DynamicService.java new file mode 100644 index 0000000..ceb2ff0 --- /dev/null +++ b/src/main/java/com/sqltoy/quickstart/service/DynamicService.java @@ -0,0 +1,26 @@ +package com.sqltoy.quickstart.service; + +/** + * 多数据源server + * + * @author sglmsn + * @date 2021/04/01 + */ +public interface DynamicService { + + /** + * 换库查询 + */ + void changeDatabaseQuery(); + + /** + * 查询主库 + */ + void queryTheMainLibrary(); + + + /** + * 事务 + */ + void affair(); +} diff --git a/src/main/java/com/sqltoy/quickstart/service/OrganInfoService.java b/src/main/java/com/sqltoy/quickstart/service/OrganInfoService.java index 76aaa79..bd9a8b2 100644 --- a/src/main/java/com/sqltoy/quickstart/service/OrganInfoService.java +++ b/src/main/java/com/sqltoy/quickstart/service/OrganInfoService.java @@ -19,4 +19,13 @@ public interface OrganInfoService { * @return */ public void saveOrganInfo(OrganInfoVO organInfoVO); + + + /** + * 更新 + * + * @param organInfoVO + * @return {@link Long} + */ + Long update(OrganInfoVO organInfoVO); } diff --git a/src/main/java/com/sqltoy/quickstart/service/TransLedgerService.java b/src/main/java/com/sqltoy/quickstart/service/TransLedgerService.java index 690972a..900ec69 100644 --- a/src/main/java/com/sqltoy/quickstart/service/TransLedgerService.java +++ b/src/main/java/com/sqltoy/quickstart/service/TransLedgerService.java @@ -14,4 +14,13 @@ import com.sqltoy.quickstart.vo.TransLedgerVO; */ public interface TransLedgerService { public TransLedgerVO updateTrans(TransLedgerVO transVO); + + + /** + * 记录流水 + * + * @param transLedgerVO + * @return {@link TransLedgerVO} + */ + TransLedgerVO recordFlow(TransLedgerVO transLedgerVO); } diff --git a/src/main/java/com/sqltoy/quickstart/service/impl/DynamicServiceImpl.java b/src/main/java/com/sqltoy/quickstart/service/impl/DynamicServiceImpl.java new file mode 100644 index 0000000..4ffd02f --- /dev/null +++ b/src/main/java/com/sqltoy/quickstart/service/impl/DynamicServiceImpl.java @@ -0,0 +1,68 @@ +package com.sqltoy.quickstart.service.impl; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.dynamic.datasource.annotation.DSTransactional; +import com.sqltoy.quickstart.service.DynamicService; +import com.sqltoy.quickstart.service.TransLedgerService; +import com.sqltoy.quickstart.vo.OrganInfoVO; +import com.sqltoy.quickstart.vo.TransLedgerVO; +import org.sagacity.sqltoy.dao.SqlToyLazyDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +@Service +public class DynamicServiceImpl implements DynamicService { + + @Autowired + OrganInfoServiceImpl organInfoService; + + @Autowired + TransLedgerService transLedgerService; + + @Autowired + SqlToyLazyDao sqlToyLazyDao; + + @DS("log") + @Override + public void changeDatabaseQuery() { + List all = sqlToyLazyDao.findAll(OrganInfoVO.class); + OrganInfoVO serializable = all.get(0); + serializable.setCostNo(serializable.getCostNo() + "_ds"); + sqlToyLazyDao.saveOrUpdate(serializable); + } + + @Override + public void queryTheMainLibrary() { + List all = sqlToyLazyDao.findAll(OrganInfoVO.class); + OrganInfoVO serializable = all.get(0); + serializable.setCostNo(serializable.getCostNo() + "_ds"); + sqlToyLazyDao.saveOrUpdate(serializable); + } + + @Override + @DSTransactional + @DS("log") + public void affair() { + { + TransLedgerVO transLedgerVO = new TransLedgerVO(); + transLedgerVO.setAmt(new BigDecimal("1")) + .setCreateBy("多数据源").setCreateTime(LocalDateTime.now()).setUpdateTime(LocalDateTime.now()).setOrderId("1").setQuantity(3); + transLedgerService.recordFlow(transLedgerVO); + } + + { + List all = sqlToyLazyDao.findAll(OrganInfoVO.class); + OrganInfoVO serializable = all.get(0); + serializable.setCostNo(serializable.getCostNo() + "多数据源测试"); + organInfoService.update(serializable); + } + int f = 1 / 0; + } + + + +} diff --git a/src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImpl.java b/src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImpl.java index 43edc44..eb09456 100644 --- a/src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImpl.java +++ b/src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImpl.java @@ -3,12 +3,9 @@ */ package com.sqltoy.quickstart.service.impl; -import java.math.BigDecimal; -import java.sql.Connection; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; - +import com.sqltoy.quickstart.service.InitDBService; +import com.sqltoy.quickstart.vo.DeviceOrderVO; +import com.sqltoy.quickstart.vo.StaffInfoVO; import org.sagacity.sqltoy.callback.DataSourceCallbackHandler; import org.sagacity.sqltoy.dao.SqlToyLazyDao; import org.sagacity.sqltoy.model.EntityQuery; @@ -22,9 +19,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.sqltoy.quickstart.service.InitDBService; -import com.sqltoy.quickstart.vo.DeviceOrderVO; -import com.sqltoy.quickstart.vo.StaffInfoVO; +import java.math.BigDecimal; +import java.sql.Connection; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; /** * @project sqltoy-quickstart @@ -34,6 +33,7 @@ import com.sqltoy.quickstart.vo.StaffInfoVO; * @modify 2020年7月17日,修改说明 */ @Service("initDBService") + public class InitDBServiceImpl implements InitDBService { @Autowired private SqlToyLazyDao sqlToyLazyDao; diff --git a/src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImplLog.java b/src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImplLog.java new file mode 100644 index 0000000..a79da1e --- /dev/null +++ b/src/main/java/com/sqltoy/quickstart/service/impl/InitDBServiceImplLog.java @@ -0,0 +1,105 @@ +/** + * + */ +package com.sqltoy.quickstart.service.impl; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.dynamic.datasource.annotation.DSTransactional; +import com.sqltoy.quickstart.service.InitDBService; +import com.sqltoy.quickstart.vo.DeviceOrderVO; +import com.sqltoy.quickstart.vo.StaffInfoVO; +import org.sagacity.sqltoy.callback.DataSourceCallbackHandler; +import org.sagacity.sqltoy.dao.SqlToyLazyDao; +import org.sagacity.sqltoy.model.EntityQuery; +import org.sagacity.sqltoy.utils.DataSourceUtils; +import org.sagacity.sqltoy.utils.DateUtil; +import org.sagacity.sqltoy.utils.FileUtil; +import org.sagacity.sqltoy.utils.NumberUtil; +import org.sagacity.sqltoy.utils.SqlUtil; +import org.sagacity.sqltoy.utils.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.sql.Connection; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +/** + * @project sqltoy-quickstart + * @description 请在此说明类的功能 + * @author zhongxuchen + * @version v1.0, Date:2020年7月17日 + * @modify 2020年7月17日,修改说明 + */ +@Service("initDBServiceLog") +@DS("log") +public class InitDBServiceImplLog implements InitDBService { + @Autowired + private SqlToyLazyDao sqlToyLazyDao; + @DSTransactional + @Override + public void initDatabase(String dataSqlFile) { + // 加载初始化数据脚本(最好手工执行数据初始化,便于演示缓存翻译功能) + final String sqlContent = FileUtil.readFileAsStr(dataSqlFile, "UTF-8"); + if (StringUtil.isBlank(sqlContent)) { + return; + } + DataSourceUtils.processDataSource(sqlToyLazyDao.getSqlToyContext(), sqlToyLazyDao.getDataSource(), + new DataSourceCallbackHandler() { + @Override + public void doConnection(Connection conn, Integer dbType, String dialect) throws Exception { + // executeBatchSql可以根据数据库类型将大的sql字符进行分割循环执行 + SqlUtil.executeBatchSql(conn, sqlContent, 100, true); + // 返回结果 + // this.setResult(result); + } + }); + + } + + @Transactional + public Long initOrderData() { + // 第一步清除数据(deleteByQuery 不允许无条件删除,简易方式跳过) + sqlToyLazyDao.deleteByQuery(DeviceOrderVO.class, EntityQuery.create().where("1=?").values(1)); + + // 模拟订单信息 + List orderInfos = new ArrayList(); + int max = 1000; + // 查询全部员工(空条件,sqltoy强制约束需要设置条件) + List staffs = sqlToyLazyDao.findEntity(StaffInfoVO.class, + EntityQuery.create().where("").values("")); + StaffInfoVO staff; + int[] days = { 10, 15, 20, 30, 60 }; + LocalDate nowTime = DateUtil.getDate(); + // 直接通过sqltoy的缓存获取字典数据,避免查询数据库 + List deviceTypes = new ArrayList( + sqlToyLazyDao.getTranslateCache("dictKeyName", "DEVICE_TYPE").values()); + // 采购、销售标志 + String[] psTypes = { "PO", "SO" }; + for (int i = 0; i < max; i++) { + DeviceOrderVO orderVO = new DeviceOrderVO(); + staff = staffs.get(NumberUtil.getRandomNum(staffs.size() - 1)); + orderVO.setBuyer("C000" + i); + orderVO.setSaler("S000" + i); + orderVO.setStaffId(staff.getStaffId()); + orderVO.setOrganId(staff.getOrganId()); + orderVO.setTransDate(nowTime); + // 随机设置相关参数 + orderVO.setDeliveryTerm(DateUtil.asLocalDate(DateUtil.addDay(nowTime, days[NumberUtil.getRandomNum(4)]))); + orderVO.setDeviceType(deviceTypes.get(NumberUtil.getRandomNum(deviceTypes.size() - 1))[0].toString()); + orderVO.setPsType(psTypes[NumberUtil.getRandomNum(1)]); + orderVO.setTotalCnt(new BigDecimal(NumberUtil.getRandomNum(100, 400))); + orderVO.setTotalAmt(orderVO.getTotalCnt().multiply(BigDecimal.valueOf(500))); + orderVO.setStatus(1); + orderVO.setCreateBy("S0001"); + orderVO.setUpdateBy("S0001"); + orderInfos.add(orderVO); + } + // 事务控制在service层上面的 + return sqlToyLazyDao.saveAll(orderInfos); + } + +} diff --git a/src/main/java/com/sqltoy/quickstart/service/impl/OrganInfoServiceImpl.java b/src/main/java/com/sqltoy/quickstart/service/impl/OrganInfoServiceImpl.java index 9830c7b..db9a4cb 100644 --- a/src/main/java/com/sqltoy/quickstart/service/impl/OrganInfoServiceImpl.java +++ b/src/main/java/com/sqltoy/quickstart/service/impl/OrganInfoServiceImpl.java @@ -3,15 +3,15 @@ */ package com.sqltoy.quickstart.service.impl; +import com.baomidou.dynamic.datasource.annotation.DS; +import com.sqltoy.quickstart.service.OrganInfoService; +import com.sqltoy.quickstart.vo.OrganInfoVO; import org.sagacity.sqltoy.dao.SqlToyLazyDao; import org.sagacity.sqltoy.model.TreeTableModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.sqltoy.quickstart.service.OrganInfoService; -import com.sqltoy.quickstart.vo.OrganInfoVO; - /** * @project sqltoy-quickstart * @description 请在此说明类的功能 @@ -20,6 +20,7 @@ import com.sqltoy.quickstart.vo.OrganInfoVO; * @modify 2020-7-22,修改说明 */ @Service("organInfoService") +@DS("master") public class OrganInfoServiceImpl implements OrganInfoService { @Autowired SqlToyLazyDao sqlToyLazyDao; @@ -35,4 +36,10 @@ public class OrganInfoServiceImpl implements OrganInfoService { sqlToyLazyDao.wrapTreeTableRoute(new TreeTableModel(organInfoVO).idField("organCode").pidField("organPid")); } + @Override + public Long update(OrganInfoVO organInfoVO) { + Long aLong = sqlToyLazyDao.saveOrUpdate(organInfoVO); + return aLong; + } + } diff --git a/src/main/java/com/sqltoy/quickstart/service/impl/TransLedgerServiceImpl.java b/src/main/java/com/sqltoy/quickstart/service/impl/TransLedgerServiceImpl.java index e2cd9fd..531328d 100644 --- a/src/main/java/com/sqltoy/quickstart/service/impl/TransLedgerServiceImpl.java +++ b/src/main/java/com/sqltoy/quickstart/service/impl/TransLedgerServiceImpl.java @@ -3,11 +3,9 @@ */ package com.sqltoy.quickstart.service.impl; -import java.math.BigDecimal; -import java.sql.ResultSet; -import java.time.LocalDateTime; -import java.util.List; - +import com.baomidou.dynamic.datasource.annotation.DS; +import com.sqltoy.quickstart.service.TransLedgerService; +import com.sqltoy.quickstart.vo.TransLedgerVO; import org.sagacity.sqltoy.callback.UpdateRowHandler; import org.sagacity.sqltoy.dao.SqlToyLazyDao; import org.sagacity.sqltoy.executor.QueryExecutor; @@ -16,8 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.sqltoy.quickstart.service.TransLedgerService; -import com.sqltoy.quickstart.vo.TransLedgerVO; +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.util.List; /** * @project sqltoy-quickstart @@ -55,4 +54,11 @@ public class TransLedgerServiceImpl implements TransLedgerService { return result.get(0); } + @DS("log") + @Override + public TransLedgerVO recordFlow(TransLedgerVO transLedgerVO) { + sqlToyLazyDao.saveOrUpdate(transLedgerVO); + return transLedgerVO; + } + } diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml new file mode 100644 index 0000000..1c46931 --- /dev/null +++ b/src/main/resources/application-local.yml @@ -0,0 +1,148 @@ +spring: + thymeleaf: + cache: false + sqltoy: + debug: false + autoconfigure: + exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure + datasource: + druid: + stat-view-servlet: + enabled: true + loginUsername: wt + loginPassword: wangtao + web-stat-filter: + enabled: true + url-pattern: /* + profile-enable: true + dynamic: + druid: #以下是全局默认值,可以全局更改 + initial-size: 3 + max-active: 5 + min-idle: 2 + max-wait: 12000 + time-between-eviction-runs-millis: 6000 + time-between-log-stats-millis: + stat-sqlmax-size: + min-evictable-idle-time-millis: 600000 + max-evictable-idle-time-millis: 900000 + test-while-idle: true + test-on-borrow: false + test-on-return: false + validation-query: select 1 + validation-query-timeout: 5 + use-global-datasource-stat: + async-init: + clear-filters-enable: + reset-stat-enable: + not-full-timeout-retry-count: + max-wait-thread-count: + fail-fast: + phyTimeout-millis: 500 + keep-alive: true + pool-prepared-statements: + init-variants: + init-global-variants: + use-unfair-lock: + kill-when-socket-read-timeout: + connection-properties: + max-pool-prepared-statement-per-connection-size: + init-connection-sqls: + share-prepared-statements: + connection-errorretry-attempts: + break-after-acquire-failure: + filters: stat,wall # 注意这个值和druid原生不一致,默认启动了stat,wall + wall: + noneBaseStatementAllow: + callAllow: + selectAllow: + selectIntoAllow: + selectIntoOutfileAllow: + selectWhereAlwayTrueCheck: + selectHavingAlwayTrueCheck: + selectUnionCheck: + selectMinusCheck: + selectExceptCheck: + selectIntersectCheck: + createTableAllow: + dropTableAllow: + alterTableAllow: + renameTableAllow: + hintAllow: + lockTableAllow: + startTransactionAllow: + blockAllow: + conditionAndAlwayTrueAllow: + conditionAndAlwayFalseAllow: + conditionDoubleConstAllow: + conditionLikeTrueAllow: + selectAllColumnAllow: + deleteAllow: + deleteWhereAlwayTrueCheck: + deleteWhereNoneCheck: + updateAllow: + updateWhereAlayTrueCheck: + updateWhereNoneCheck: + insertAllow: + mergeAllow: + minusAllow: + intersectAllow: + replaceAllow: + setAllow: + commitAllow: + rollbackAllow: + useAllow: + multiStatementAllow: + truncateAllow: + commentAllow: + strictSyntaxCheck: + constArithmeticAllow: + limitZeroAllow: + describeAllow: + showAllow: + schemaCheck: + tableCheck: + functionCheck: + objectCheck: + variantCheck: + mustParameterized: + doPrivilegedAllow: + dir: + tenantTablePattern: + tenantColumn: + wrapAllow: + metadataAllow: + conditionOpXorAllow: + conditionOpBitwseAllow: + caseConditionConstAllow: + completeInsertValuesCheck: + insertValuesCheckSize: + selectLimit: + stat: + merge-sql: true + log-slow-sql: true + slow-sql-millis: 1000 + datasource: + master: + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://t.sglmsn.top:3306/sqltoy_system?characterEncoding=utf8&useSSL=false&useAffectedRows=true&useCompression=true&serverTimezone=Asia/Shanghai + username: test + password: test + druid: + type: mariadb + filters: stat,wall # 注意这个值和druid原生不一致,默认启动了stat,wall + log: + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://t.sglmsn.top:3306/sqltoy_log?characterEncoding=utf8&useSSL=false&useAffectedRows=true&useCompression=true&serverTimezone=Asia/Shanghai + username: test + password: test + druid: + type: mariadb + filters: stat,wall # 注意这个值和druid原生不一致,默认启动了stat,wall + p6spy: true +# sqliteDb: +# driver-class-name: org.sqlite.JDBC +# url: jdbc:sqlite:./wx.db +# druid: +# type: sqlite +# filters: \ No newline at end of file diff --git a/src/main/resources/application-server.yml b/src/main/resources/application-server.yml new file mode 100644 index 0000000..6891d41 --- /dev/null +++ b/src/main/resources/application-server.yml @@ -0,0 +1,147 @@ +spring: + thymeleaf: + cache: false + sqltoy: + debug: false + autoconfigure: + exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure + datasource: + druid: + stat-view-servlet: + enabled: true + loginUsername: wt + loginPassword: wangtao + web-stat-filter: + enabled: true + url-pattern: /* + profile-enable: true + dynamic: + druid: #以下是全局默认值,可以全局更改 + initial-size: 3 + max-active: 5 + min-idle: 2 + max-wait: 12000 + time-between-eviction-runs-millis: 6000 + time-between-log-stats-millis: + stat-sqlmax-size: + min-evictable-idle-time-millis: 600000 + max-evictable-idle-time-millis: 900000 + test-while-idle: true + test-on-borrow: false + test-on-return: false + validation-query: select 1 + validation-query-timeout: 5 + use-global-datasource-stat: + async-init: + clear-filters-enable: + reset-stat-enable: + not-full-timeout-retry-count: + max-wait-thread-count: + fail-fast: + phyTimeout-millis: 500 + keep-alive: true + pool-prepared-statements: + init-variants: + init-global-variants: + use-unfair-lock: + kill-when-socket-read-timeout: + connection-properties: + max-pool-prepared-statement-per-connection-size: + init-connection-sqls: + share-prepared-statements: + connection-errorretry-attempts: + break-after-acquire-failure: + filters: stat,wall # 注意这个值和druid原生不一致,默认启动了stat,wall + wall: + noneBaseStatementAllow: + callAllow: + selectAllow: + selectIntoAllow: + selectIntoOutfileAllow: + selectWhereAlwayTrueCheck: + selectHavingAlwayTrueCheck: + selectUnionCheck: + selectMinusCheck: + selectExceptCheck: + selectIntersectCheck: + createTableAllow: + dropTableAllow: + alterTableAllow: + renameTableAllow: + hintAllow: + lockTableAllow: + startTransactionAllow: + blockAllow: + conditionAndAlwayTrueAllow: + conditionAndAlwayFalseAllow: + conditionDoubleConstAllow: + conditionLikeTrueAllow: + selectAllColumnAllow: + deleteAllow: + deleteWhereAlwayTrueCheck: + deleteWhereNoneCheck: + updateAllow: + updateWhereAlayTrueCheck: + updateWhereNoneCheck: + insertAllow: + mergeAllow: + minusAllow: + intersectAllow: + replaceAllow: + setAllow: + commitAllow: + rollbackAllow: + useAllow: + multiStatementAllow: + truncateAllow: + commentAllow: + strictSyntaxCheck: + constArithmeticAllow: + limitZeroAllow: + describeAllow: + showAllow: + schemaCheck: + tableCheck: + functionCheck: + objectCheck: + variantCheck: + mustParameterized: + doPrivilegedAllow: + dir: + tenantTablePattern: + tenantColumn: + wrapAllow: + metadataAllow: + conditionOpXorAllow: + conditionOpBitwseAllow: + caseConditionConstAllow: + completeInsertValuesCheck: + insertValuesCheckSize: + selectLimit: + stat: + merge-sql: true + log-slow-sql: true + slow-sql-millis: 1000 + datasource: + master: + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://t.sglmsn.top:3306/sqltoy_system?characterEncoding=utf8&useSSL=false&useAffectedRows=true&useCompression=true&serverTimezone=Asia/Shanghai + username: test + password: test + druid: + type: mariadb + filters: stat,wall # 注意这个值和druid原生不一致,默认启动了stat,wall + log: + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://t.sglmsn.top:3306/sqltoy_log?characterEncoding=utf8&useSSL=false&useAffectedRows=true&useCompression=true&serverTimezone=Asia/Shanghai + username: test + password: test + druid: + type: mariadb + filters: stat,wall # 注意这个值和druid原生不一致,默认启动了stat,wall +# sqliteDb: +# driver-class-name: org.sqlite.JDBC +# url: jdbc:sqlite:./wx.db +# druid: +# type: sqlite +# filters: \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2f7bf76..1ae3ecb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,5 @@ + + spring: #将sqltoy 放于开始位置,避免很多开发者忽视了spring.sqltoy 开头,变成了sqltoy开头导致无法加载 sqltoy: @@ -9,8 +11,6 @@ spring: typeHandler: com.sqltoy.plugins.JsonTypeHandler # 跨数据库函数自适配功能,默认是关闭的 #functionConverts: default - # 默认为false,debug模式将打印执行sql,并自动检测sql文件更新并重新加载 - debug: true # 如果是单一类型数据库填写有利于减少一些判断(即排除类似于:mysql\oracle多种类型混用场景) #dialect: mysql # 设置默认使用的datasource(可选配置) @@ -29,31 +29,7 @@ spring: #cacheType: caffeine #自定义缓存框架设定 #translateCacheManager: com.xxxx.xxxCacheImpl - datasource: - name: dataSource - type: com.alibaba.druid.pool.DruidDataSource - driver-class-name: com.mysql.cj.jdbc.Driver - username: quickstart - password: quickstart - defaultAutoCommit: false - # 注意characterEncoding=utf-8 参数,在mysql6~7 版本下不设置like 中文时会无法匹配 - url: jdbc:mysql://192.168.56.101:3306/quickstart?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true - druid: - initial-size: 5 - min-idle: 5 - maxActive: 20 - # 配置获取连接等待超时的时间 - maxWait: 60000 - numTestsPerEvictionRun: 3 - keepAlive: true - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 - timeBetweenEvictionRunsMillis: 120000 - # 配置一个连接在池中最小生存的时间,单位是毫秒 - minEvictableIdleTimeMillis: 600000 - validationQuery: SELECT 1 FROM DUAL - testWhileIdle: true - testOnBorrow: true - testOnReturn: false - removeAbandoned: true - removeAbandonedTimeout: 300 - \ No newline at end of file + profiles: + active: local + + diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index f570768..bb7145d 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -18,7 +18,7 @@ - + diff --git a/src/main/resources/spy.properties b/src/main/resources/spy.properties new file mode 100644 index 0000000..b4dac4a --- /dev/null +++ b/src/main/resources/spy.properties @@ -0,0 +1,2 @@ +appender=com.p6spy.engine.spy.appender.Slf4JLogger +customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine) \ No newline at end of file diff --git a/src/test/java/com/sqltoy/quickstart/DynamicQueryTest.java b/src/test/java/com/sqltoy/quickstart/DynamicQueryTest.java new file mode 100644 index 0000000..c6f832c --- /dev/null +++ b/src/test/java/com/sqltoy/quickstart/DynamicQueryTest.java @@ -0,0 +1,46 @@ +package com.sqltoy.quickstart; + +import com.sqltoy.quickstart.service.DynamicService; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +/** + * 多数据源测试 + * 请先初始化数据 {@link InitDataBaseTest} + * @author sglmsn + * @date 2021/04/01 + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = SqlToyApplication.class) +public class DynamicQueryTest { + + @Autowired + DynamicService dynamicService; + + /** + * 查询其他数据源 + */ + @Test + public void changeDatabaseQuery() { + dynamicService.changeDatabaseQuery(); + } + + /** + * 查询的主数据源 + */ + @Test + public void queryTheMainLibrary() { + dynamicService.queryTheMainLibrary(); + } + + /** + * 多数据源事务 + */ + @Test + public void affair() { + dynamicService.affair(); + } +} diff --git a/src/test/java/com/sqltoy/quickstart/InitDataBaseTest.java b/src/test/java/com/sqltoy/quickstart/InitDataBaseTest.java index 8c4cf91..f9aa8e7 100644 --- a/src/test/java/com/sqltoy/quickstart/InitDataBaseTest.java +++ b/src/test/java/com/sqltoy/quickstart/InitDataBaseTest.java @@ -1,13 +1,13 @@ package com.sqltoy.quickstart; +import com.sqltoy.quickstart.service.impl.InitDBServiceImpl; +import com.sqltoy.quickstart.service.impl.InitDBServiceImplLog; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.sqltoy.quickstart.service.InitDBService; - /** * @project sqltoy-quickstart * @description 初始化数据库 @@ -19,12 +19,27 @@ import com.sqltoy.quickstart.service.InitDBService; public class InitDataBaseTest { @Autowired - private InitDBService initDBService; + private InitDBServiceImplLog initDBServiceImplLog; + @Autowired + private InitDBServiceImpl initDBService; + /** + * 初始化主数据库 + */ @Test public void testInitDB() { String dbSqlFile = "classpath:mock/quickstart_init.sql"; System.err.println("开始执行数据库初始化!"); initDBService.initDatabase(dbSqlFile); } + + /** + * 初始化日志数据库 + */ + @Test + public void testInitDbLog(){ + String dbSqlFile = "classpath:mock/quickstart_init.sql"; + System.err.println("开始执行数据库初始化!"); + initDBServiceImplLog.initDatabase(dbSqlFile); + } } -- Gitee From a3845b3a65eb85f1a49d6cc9aadab9e095270afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=A1=E7=84=B6=E6=BC=94=E7=BB=8E=E7=9D=80=E4=BC=A4?= <2450572350@qq.com> Date: Thu, 1 Apr 2021 14:09:48 +0800 Subject: [PATCH 2/2] update README.md. --- README.md | 440 ++++-------------------------------------------------- 1 file changed, 28 insertions(+), 412 deletions(-) diff --git a/README.md b/README.md index db4a185..18cd85c 100644 --- a/README.md +++ b/README.md @@ -1,426 +1,42 @@ -# sqltoy-orm 快速上手项目 -* quickstart只演示了部分功能,核心是让大家快速上手,详细功能参见文档 -* 理论上来sqltoy可以解决您项目上全部数据库交互,我们的erp、数据平台、电商平台已经验证了这一点 - -# 学习步骤 -## 1. 配置pom引入sqltoy的依赖 - -```xml - - com.sagframe - sagacity-sqltoy-starter - 4.18.10 - -``` - -## 2. 配置正确pom build避免sql文件无法编译到classes下面 -* 核心配置:src/main/java 下面的**/*.xml - -```xml - - src/main/java - - **/*.java - - - **/*.xml - - - - src/main/resources - - **/*.xml - **/*.properties - **/*.yml - **/*.sql - **/*.jpg - - - - - - src/test/java - - **/*.java - - - **/*.xml - - - - src/test/resources - - **/*.xml - **/*.properties - **/*.yml - **/*.sql - - - -``` - -## 3. 配置application.yml,注意阅读配置上的备注 -* 注意要点:sqlResourcesDir 是路径名,多个路径用逗号分隔,不要填错 -* spring.sqltoy千万不要写成sqltoy漏掉spring开头 - -``` -#完整路径:spring.sqltoy -spring: - sqltoy: - # 多个路径用逗号分隔(这里要注意是路径,sqltoy会自动向下寻找以sql.xml结尾的文件,不要写成classpath:com/**/*.sql.xml) - sqlResourcesDir: classpath:com/sqltoy/quickstart - # 默认值为classpath:sqltoy-translate.xml,一致则可以不用设置 - translateConfig: classpath:sqltoy-translate.xml - # 默认开启跨数据库函数自动适配(如oracle的nvl,当数据库切到mysql时会自动替换成ifnull) - #functionConverts: default - # 默认为false,debug模式将打印执行sql,并自动检测sql文件更新并重新加载 - debug: true - # 提供统一字段:createBy createTime updateBy updateTime 等字段补漏性(为空时)赋值(可选配置) - unifyFieldsHandler: com.sqltoy.plugins.SqlToyUnifyFieldsHandler - # sql执行超过多长时间则进行日志输出,用于监控哪些慢sql(可选配置:默认30秒) - printSqlTimeoutMillis: 300000 - # 数据库保留字兼容处理(原则上不要使用数据库保留字,多个用逗号分隔) - #reservedWords: maxvalue,minvalue -``` - -* 最简单配置(注意:spring.sqltoy开头) - -``` -#完整路径:spring.sqltoy -spring: - sqltoy: - # 多个路径用逗号分隔(注意这里填路径、路径!会自动相信寻找) - sqlResourcesDir: classpath:com/sqltoy/quickstart -``` -* properties 模式 - -``` -# sqltoy config -spring.sqltoy.sqlResourcesDir=classpath:com/sqltoy/quickstart -# 默认配置就是classpath:sqltoy-translate.xml,一致情况下无需配置 -spring.sqltoy.translateConfig=classpath:sqltoy-translate.xml -# 默认开启函数自动替换功能 ,4.15.7设置为close会关闭,之前版本可以填trim只开通单个函数模式 -#spring.sqltoy.functionConverts=default -# 是否开启debug模式,在开发阶段建议为true,会打印sql -spring.sqltoy.debug=true -#项目中用到的数据库保留字定义,这里是举例,正常情况下不用定义 -#spring.sqltoy.reservedWords=status,sex_type -#obtainDataSource: org.sagacity.sqltoy.plugins.datasource.impl.DefaultObtainDataSourc -#spring.sqltoy.defaultDataSource=dataSource -spring.sqltoy.unifyFieldsHandler=com.sqltoy.plugins.SqlToyUnifyFieldsHandler -#spring.sqltoy.printSqlTimeoutMillis=200000 -``` - -## 4. 编写springboot 主程序,注意@ComponentScan配置 -* 参见:src/main/java 下面的SqlToyApplication - +详细使用请查看源库 +这里只做多数据源演示 ```java -package com.sqltoy.quickstart; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.transaction.annotation.EnableTransactionManagement; /** - * - * @project sqltoy-quickstart - * @description quickstart 主程序入口 - * @author zhongxuchen - * @version v1.0, Date:2020年7月17日 - * @modify 2020年7月17日,修改说明 + * 多数据源测试 + * 请先初始化数据 {@link InitDataBaseTest} + * @author sglmsn + * @date 2021/04/01 */ -@SpringBootApplication -@ComponentScan(basePackages = { "com.sqltoy.config", "com.sqltoy.quickstart" }) -@EnableTransactionManagement -public class SqlToyApplication { - /** - * @param args - */ - public static void main(String[] args) { - SpringApplication.run(SqlToyApplication.class, args); - } -} - -``` - -## 5. 初始化数据库 -* 参见src/test/java 下面的InitDataBaseTest,生成数据库表结构和初始化数据 - -```java @ExtendWith(SpringExtension.class) @SpringBootTest(classes = SqlToyApplication.class) -public class InitDataBaseTest { - - @Autowired - private InitDBService initDBService; - - @Test - public void testInitDB() { - String dbSqlFile = "classpath:mock/quickstart_init.sql"; - System.err.println("开始执行数据库初始化!"); - initDBService.initDatabase(dbSqlFile); - } -} -``` - -## 6. 利用quickvo生产VO(或POJO) -* 在出问题时关注dataSource中的schema、catalog配置,其他问题请参见quickvo.xml中的注释 -* 将数据库驱动类放于tools/quickvo/libs下面 -* 配置tools/quickvo/db.properties 文件 - -```properties -############# db config #################### -jdbc.driver_class=com.mysql.cj.jdbc.Driver -# url characterEncoding=utf-8 param is need -jdbc.url=jdbc:mysql://192.168.56.109:3306/quickstart?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false -# mysql schema=dbname,oracle schema=username -jdbc.schema=quickstart -jdbc.username=quickstart -jdbc.password=quickstart -``` - -* 配置tools/quickvo/quickvo.xml 中的任务,关键部分如下 - -```xml - - - - - - - - - - - - - - - - - - - - -``` - -* 点击quickvo.bat 即可生产VO了,linux 或 mac 则执行quickvo.sh -* windows环境下: - -``` -java -cp ./libs/* org.sagacity.quickvo.QuickVOStart quickvo.xml -``` - -* mac电脑: - -``` -java -cp ./libs/\* org.sagacity.quickvo.QuickVOStart ./quickvo.xml -``` +public class DynamicQueryTest { -# 源码导航 -* 阅读的入口 src/test/java com.sqltoy.quickstart -* InitDataBaseTest 数据库初始化测试调用 -* StaffInfoServiceTest 演示常规的CRUD -* TreeTableTest 演示树形表结构的构建和查询 -* ShardingSearchTest 演示分表记录保存和查询(Sharding策略请参见src/main/java com.sqltoy.config.ShardingStrategyConfig ) -* AdvanceQueryTest 查询相关的演示 -* UniqueCaseTest 演示唯一性验证 -* CascadeCaseTest 演示级联操作 -* LockCaseTest 演示锁记录修改操作 -* StoreTest 演示存储过程调用 -* JavaCodeSqlTest 演示在代码中写sql实现原本xml中的功能 -* DTOConvertPOJOTest 演示在严格分层场景下DTO和POJO互转的范例 -* LinkOptCaseTest 演示链式操作 -* EntityOptsCaseTest 基于POJO类型的单表操作演示 -* JsonTypeCaseTest 演示json等特殊类型的支持 -* TransLedgerConcurrentTest 演示类似订单交易台账高并发事务处理 + @Autowired + DynamicService dynamicService; -# 疑问解答 -## 为什么要将*.sql.xml 放在java路径下? -* sqltoy推荐大家项目按照业务划分先分模块(消息中心、系统管理、订单管理等)后分层(web层、service),sql文件放于模块中便于模块整体迁移和产品化 -* 有利于开发过程,一般项目按模块分工,让开发者不需要不断的切换目录 -* 当然这个是sqltoy推荐做法,开发者则可以根据自身实际情况而定,并非强制! - -## 为什么缓存不用redis? -* 这里的缓存主要用于频繁的结果字段翻译,一旦你用了缓存翻译后你就会发现会在极为广泛的范围内使用,只有本地内存级缓存才能经得起频繁任意反复的调用,没有必要再来一个redis的IO消耗 -* 你可以通过扩展实现ehcache+redis模式,来提升缓存的刷新实时性,但代价比较大造成了项目的复杂性,sqltoy提供的增量更新模式基本可以控制秒级更新 - -## 为什么quickvo任务不是一个,而是按模块分多个任务 -* sqltoy强调项目模块化,便于开发提炼出相对产品化的功能模块,逐步减少每次项目重复性工作,让不通过业务代码集中于一个模块下便于模块成熟后的抽离 - -## 如何分VO和POJO -* 请参见sqltoy-strict项目 https://github.com/sagframe/sqltoy-strict - -## 如何分库分表 -* 在本项目里面已经演示了分表 -* 分库分表含事务型的范例: https://github.com/sagframe/sqltoy-showcase/tree/master/trunk/sqltoy-sharding - -## 为什么dao不采用mybatis plus的接口模式? -* mybatis dao采用接口模式,是其向jpa方向靠拢的一种模式,而sqltoy本身就是jpa+查询模式,也就是说jpa向查询方向加强,正好相反! -* 什么接口?能够用接口来完成就是意味着可以用一个通用方法来代替!因此接口式dao的存在必要性就值得商榷! - -```java -@Service("organInfoService") -public class OrganInfoServiceImpl implements OrganInfoService { - //sqltoyLazyDao 就可以代替接口式的dao - @Autowired - SqlToyLazyDao sqlToyLazyDao; - - @Transactional - public void saveOrganInfo(OrganInfoVO organInfoVO) { - // 先保存机构 - sqlToyLazyDao.saveOrUpdate(organInfoVO); - // 设置树形表的节点路径等字段值,便于统一树形查询 - // id字段根据vo找表的主键会自动匹配上,其它的NODE_ROUTE\NODE_LEVEL\IS_LEAF 为标准命名无需额外设置 - //idField 如果是主键则无需设置 - sqlToyLazyDao.wrapTreeTableRoute(new TreeTableModel(organInfoVO).pidField("organPid")); - } -} - -``` -* 考虑一些场景下dao仍然要做一些数据的封装处理(简化service层,将service尽量体现业务逻辑,减少一些dao的数据组装干扰),sqltoy仍然可以写dao,但dao时实体类! - -如下:实体类又有何不妥呢!清晰又可以针对一些特殊情况自己完善一些小处理,mybatis那种接口通过aop方式谈不上什么酷和高技术,不要被带到沟里去了,清晰、可维护、好拓展才是正道! - -```java -@Repository("staffInfoDao") -public class StaffInfoDao extends SqlToyDaoSupport { - /** - * @TODO 提供一个分页并动态设置缓存翻译的演示 - * @param pageModel - * @param staffInfoVO - * @return - */ - public PaginationModel findStaff(PaginationModel pageModel, StaffInfoVO staffInfoVO) { - // sql可以直接在代码中编写,复杂sql建议在xml中定义 - // 单表entity查询场景下sql字段可以写成java类的属性名称 - // 单表查询一般适用于接口内部查询 - String sql = "#[staffName like :staffName]#[and createTime>=:beginDate]#[and createTime<=:endDate]"; - return findEntity(StaffInfoVO.class, pageModel, EntityQuery.create().where(sql).values(staffInfoVO) - // 字典缓存必须要设置cacheType - // 单表对象查询需设置keyColumn构成select keyColumn as column模式 - .translates(new Translate("dictKeyName").setColumn("sexTypeName").setCacheType("SEX_TYPE") - .setKeyColumn("sexType")) - .translates(new Translate("organIdName").setColumn("organName").setKeyColumn("organId"))); - } -``` - -## 多数据源怎么弄? -* 如果是同类单据根据特定规则分多个库,请参见分库策略进行 -* 通过多个lazyDao模式 - -```java - @Bean(name = "sqlToySkylineDao") - public SqlToyLazyDao sqlToySkylineDao(@Qualifier("dataSourceSkyline") DataSource dataSource){ - SqlToyLazyDaoImpl dao = new SqlToyLazyDaoImpl(); - dao.setDataSource(dataSource); - return dao; - } - - @Bean(name = "sqlToyLazyDao") - public SqlToyLazyDao sqlToyLazyDao(@Qualifier("dataSource") DataSource dataSource) { - SqlToyLazyDaoImpl dao = new SqlToyLazyDaoImpl(); - dao.setDataSource(dataSource); - return dao; + /** + * 查询其他数据源 + */ + @Test + public void changeDatabaseQuery() { + dynamicService.changeDatabaseQuery(); } -``` -* 通过lazyDao里面调用时指定dataSource,save、update、load等都有链式操作 - -```java -sqlToyLazyDao.save().dataSource(dataSource).saveMode(SaveMode.IGNORE).many(entities); -sqlToyLazyDao.query().sql("qstart_fastPage").dataSource(dataSource).entity(staffVO).findPage(pageModel); -``` - -## 我想通过包路径来实现不同数据库访问 -* 请扩展实现org.sagacity.sqltoy.plugins.datasource.ObtainDataSource 接口 -* 当前默认实现(你可以通过aop+ThreadLocal来修改实现) - -```java -public class DefaultObtainDataSource implements ObtainDataSource { - /** - * 定义日志 - */ - protected final Logger logger = LoggerFactory.getLogger(DefaultObtainDataSource.class); - - private DataSource dataSource; - - @Override - public DataSource getDataSource(ApplicationContext applicationContext, DataSource defaultDataSource) { - // 避免每次去查找(适用于固定数据源场景) - if (this.dataSource != null) { - return this.dataSource; - } - Map result = applicationContext.getBeansOfType(DataSource.class); - // 只有一个dataSource,直接使用 - if (result.size() == 1) { - this.dataSource = result.values().iterator().next(); - } - // 非单一数据源,通过sqltoyContext中定义的默认dataSource来获取 - if (this.dataSource == null) { - this.dataSource = defaultDataSource; - } - // 理论上应该先获取primary的数据源,目前不知道如何获取 - // 多数据源情况下没有指定默认dataSource则返回名称为dataSource的数据源 - if (this.dataSource == null && applicationContext.containsBean("dataSource")) { - this.dataSource = (DataSource) applicationContext.getBean("dataSource"); - } - if (this.dataSource == null) { - logger.error("在多数据源场景下,请为dao正确指定dataSource,或配置spring.sqltoy.defaultDataSource=默认数据源名称!"); - } - return this.dataSource; - } -} -``` -## sqltoy传参支持map吗? -* sqltoy传参可以三种 - -```java /** - * @todo 通过对象传参数,简化paramName[],paramValue[] 模式传参 - * @param - * @param sqlOrNamedSql 可以是具体sql也可以是对应xml中的sqlId - * @param entity 通过对象传参数,并按对象类型返回结果 - * @return - */ - public List findBySql(final String sqlOrNamedSql, final T entity); - - /** - * @todo 通过给定sql、sql中的参数名、参数的数值以及返回结果的对象类型进行条件查询 - */ - public List findBySql(final String sqlOrSqlId, final String[] paramsNamed, final Object[] paramsValue, - final Class voClass); - /** - * @todo 通过map传参 - */ - public List findBySql(final String sqlOrSqlId, final Map paramsMap, final Class voClass); -``` - -## sqltoy必须返回VO吗? -* sqltoy返回结果可以是VO、map、二维List,List + * 查询的主数据源 + */ + @Test + public void queryTheMainLibrary() { + dynamicService.queryTheMainLibrary(); + } -```java /** - * @todo 通过给定sql、sql中的参数、参数的数值以及返回结果的对象类型进行条件查询 - * @param sqlOrSqlId - * @param paramsNamed 如果sql是select * from table where xxx=? - * 问号传参模式,paramNamed设置为null - * @param paramsValue 对应Named参数的值 - * @param voClass 返回结果List中的对象类型(可以是VO、null:表示返回List;HashMap.class,Array.class 返回List List findBySql(final String sqlOrSqlId, final String[] paramsNamed, final Object[] paramsValue, - final Class voClass); -``` - -## sqltoy 的sql必须写在xml中吗? -* sqltoy强调复杂sql放于xml中,但不限制您,如下面的代码第一个参数是sql或者sqlId,你可以直接传sql语句 + * 多数据源事务 + */ + @Test + public void affair() { + dynamicService.affair(); + } +} -```java -public List findBySql(final String sqlOrSqlId, final String[] paramsNamed, final Object[] paramsValue, - final Class voClass); ``` - -## 还有?? -* 请阅读sqltoy下面的word文档说明 -- Gitee