diff --git a/pom.xml b/pom.xml index 3f158baf..ea1fcbc0 100644 --- a/pom.xml +++ b/pom.xml @@ -127,6 +127,13 @@ 1.0.0 + + + cn.stylefeng.roses + ds-container-spring-boot-starter + 1.0.0 + + mysql diff --git a/src/main/java/cn/stylefeng/guns/GunsApplication.java b/src/main/java/cn/stylefeng/guns/GunsApplication.java index 310128cb..0893bf14 100644 --- a/src/main/java/cn/stylefeng/guns/GunsApplication.java +++ b/src/main/java/cn/stylefeng/guns/GunsApplication.java @@ -1,5 +1,6 @@ package cn.stylefeng.guns; +import cn.stylefeng.roses.kernel.db.starter.GunsDataSourceAutoConfiguration; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -12,7 +13,7 @@ import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; * @date 2020/12/1 17:50 */ @Slf4j -@SpringBootApplication(scanBasePackages = {"cn.stylefeng"}, exclude = FlywayAutoConfiguration.class) +@SpringBootApplication(scanBasePackages = {"cn.stylefeng"}, exclude = {FlywayAutoConfiguration.class, GunsDataSourceAutoConfiguration.class}) public class GunsApplication { public static void main(String[] args) { diff --git a/src/main/java/cn/stylefeng/guns/modular/datasource/DataSourceViewController.java b/src/main/java/cn/stylefeng/guns/modular/datasource/DataSourceViewController.java new file mode 100644 index 00000000..22393a0d --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/datasource/DataSourceViewController.java @@ -0,0 +1,40 @@ +package cn.stylefeng.guns.modular.datasource; + +import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource; +import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource; +import org.springframework.stereotype.Controller; + +/** + * 多数据源界面 + * + * @author fengshuonan + * @date 2021/1/23 21:45 + */ +@Controller +@ApiResource(name = "多数据源界面") +public class DataSourceViewController { + + /** + * 多数据源列表界面 + * + * @author fengshuonan + * @date 2021/1/23 21:45 + */ + @GetResource(name = "多数据源列表界面", path = "/view/datasource") + public String indexView() { + return "/modular/datasource/datasource.html"; + } + + /** + * 多数据源新增界面 + * + * @author fengshuonan + * @date 2021/1/23 21:59 + */ + @GetResource(name = "多数据源新增界面", path = "/view/datasource/add") + public String addView() { + return "/modular/datasource/datasource_add.html"; + } + + +} diff --git a/src/main/java/cn/stylefeng/guns/modular/datasource/test/TestMultiTranController.java b/src/main/java/cn/stylefeng/guns/modular/datasource/test/TestMultiTranController.java new file mode 100644 index 00000000..249f96a8 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/datasource/test/TestMultiTranController.java @@ -0,0 +1,37 @@ +package cn.stylefeng.guns.modular.datasource.test; + +import cn.stylefeng.guns.modular.datasource.test.service.TranTestService; +import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource; +import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource; +import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 测试多数据源 + * + * @author stylefeng + * @date 2018/7/20 23:39 + */ +@RestController +@ApiResource(name = "测试多数据源") +public class TestMultiTranController { + + @Resource + private TranTestService testMultiDbService; + + @GetResource(name = "测试多数据源成功", path = "/tran/multi/success") + public Object testSuccess() { + testMultiDbService.beginTest(); + return new SuccessResponseData(); + } + + @GetResource(name = "测试多数据源失败", path = "/tran/multi/fail") + public Object testFail() { + testMultiDbService.beginTestFail(); + return new SuccessResponseData(); + } + +} + diff --git a/src/main/java/cn/stylefeng/guns/modular/datasource/test/TestSingleTranController.java b/src/main/java/cn/stylefeng/guns/modular/datasource/test/TestSingleTranController.java new file mode 100644 index 00000000..06fbbdb9 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/datasource/test/TestSingleTranController.java @@ -0,0 +1,37 @@ +package cn.stylefeng.guns.modular.datasource.test; + +import cn.stylefeng.guns.modular.datasource.test.service.TranTestService; +import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource; +import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource; +import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * 测试单数据源回滚 + * + * @author stylefeng + * @date 2018/7/20 23:39 + */ +@RestController +@ApiResource(name = "测试单数据源") +public class TestSingleTranController { + + @Resource + private TranTestService testMultiDbService; + + @GetResource(name = "测试单数据源事务成功", path = "/tran/single/success") + public Object testSuccess() { + testMultiDbService.testSingleSuccess(); + return new SuccessResponseData(); + } + + @GetResource(name = "测试单数据源事务失败", path = "/tran/single/fail") + public Object testFail() { + testMultiDbService.testSingleFail(); + return new SuccessResponseData(); + } + +} + diff --git a/src/main/java/cn/stylefeng/guns/modular/datasource/test/factory/NormalUserFactory.java b/src/main/java/cn/stylefeng/guns/modular/datasource/test/factory/NormalUserFactory.java new file mode 100644 index 00000000..4f96a262 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/datasource/test/factory/NormalUserFactory.java @@ -0,0 +1,35 @@ +package cn.stylefeng.guns.modular.datasource.test.factory; + +import cn.hutool.core.util.RandomUtil; +import cn.stylefeng.roses.kernel.system.modular.user.entity.SysUser; + +import java.util.Date; + +/** + * 创建一个用于测试数据源的用户 + * + * @author fengshuonan + * @date 2021/1/23 23:29 + */ +public class NormalUserFactory { + + /** + * 创建一个用于测试数据源的用户 + * + * @author fengshuonan + * @date 2021/1/23 23:29 + */ + public static SysUser createAnUser() { + SysUser user = new SysUser(); + user.setAccount(RandomUtil.randomString(5)); + user.setPassword(RandomUtil.randomString(5)); + user.setCreateTime(new Date()); + user.setUpdateTime(new Date()); + user.setCreateUser(1L); + user.setSex("M"); + user.setUpdateUser(1L); + user.setRealName(RandomUtil.randomString(5)); + return user; + } + +} diff --git a/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/GunsDbService.java b/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/GunsDbService.java new file mode 100644 index 00000000..1121a410 --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/GunsDbService.java @@ -0,0 +1,30 @@ +package cn.stylefeng.guns.modular.datasource.test.service; + +import cn.stylefeng.guns.modular.datasource.test.factory.NormalUserFactory; +import cn.stylefeng.roses.kernel.dsctn.api.annotation.DataSource; +import cn.stylefeng.roses.kernel.system.modular.user.entity.SysUser; +import cn.stylefeng.roses.kernel.system.modular.user.mapper.SysUserMapper; +import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * Guns数据库操作 + * + * @author fengshuonan + * @date 2021/1/23 23:29 + */ +@Service +public class GunsDbService extends ServiceImpl { + + @Resource + private SysUserService sysUserService; + + @DataSource(name = "master") + public void gunsDb() { + sysUserService.save(NormalUserFactory.createAnUser()); + } + +} diff --git a/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/OtherDbService.java b/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/OtherDbService.java new file mode 100644 index 00000000..4bb66d9d --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/OtherDbService.java @@ -0,0 +1,30 @@ +package cn.stylefeng.guns.modular.datasource.test.service; + +import cn.stylefeng.guns.modular.datasource.test.factory.NormalUserFactory; +import cn.stylefeng.roses.kernel.dsctn.api.annotation.DataSource; +import cn.stylefeng.roses.kernel.system.modular.user.entity.SysUser; +import cn.stylefeng.roses.kernel.system.modular.user.mapper.SysUserMapper; +import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 其他数据库操作 + * + * @author fengshuonan + * @date 2021/1/23 23:30 + */ +@Service +public class OtherDbService extends ServiceImpl { + + @Resource + private SysUserService sysUserService; + + @DataSource(name = "test") + public void otherDb() { + sysUserService.save(NormalUserFactory.createAnUser()); + } + +} diff --git a/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/TranTestService.java b/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/TranTestService.java new file mode 100644 index 00000000..0ecc9eed --- /dev/null +++ b/src/main/java/cn/stylefeng/guns/modular/datasource/test/service/TranTestService.java @@ -0,0 +1,46 @@ +package cn.stylefeng.guns.modular.datasource.test.service; + +import cn.stylefeng.guns.modular.datasource.test.factory.NormalUserFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; + +/** + * 测试多数据源操作 + * + * @author fengshuonan + * @date 2021/1/23 23:30 + */ +@Service +public class TranTestService { + + @Resource + private GunsDbService gunsDbService; + + @Resource + private OtherDbService otherDbService; + + @Transactional(rollbackFor = Exception.class) + public void testSingleSuccess() { + gunsDbService.save(NormalUserFactory.createAnUser()); + } + + @Transactional(rollbackFor = Exception.class) + public void testSingleFail() { + gunsDbService.save(NormalUserFactory.createAnUser()); + int i = 1 / 0; + } + + public void beginTest() { + gunsDbService.gunsDb(); + otherDbService.otherDb(); + } + + public void beginTestFail() { + gunsDbService.gunsDb(); + otherDbService.otherDb(); + int i = 1 / 0; + } + +} diff --git a/src/main/resources/db/migration/V1.0_20210123_0001__add_meun_table.sql b/src/main/resources/db/migration/V1.0_20210123_0001__add_meun_table.sql index e7d6eedc..e2e67e4f 100644 --- a/src/main/resources/db/migration/V1.0_20210123_0001__add_meun_table.sql +++ b/src/main/resources/db/migration/V1.0_20210123_0001__add_meun_table.sql @@ -1,4 +1,4 @@ -INSERT INTO `sys_menu` VALUES (1352966403623342082, 1339550467939639317, '[-1],[1339550467939639317],', '多数据源', 'datasources', 'system', 'Y', 50.50, 1, NULL, '/view/datasources', 'layui-icon-star-fill', NULL, 'icon-default', NULL, 0, NULL, 'N', '2021-01-23 21:08:22', 1339550467939639299, NULL, NULL); +INSERT INTO `sys_menu` VALUES (1352966403623342082, 1339550467939639317, '[-1],[1339550467939639317],', '多数据源', 'datasources', 'system', 'Y', 50.50, 1, NULL, '/view/datasource', 'layui-icon-star-fill', NULL, 'icon-default', NULL, 0, NULL, 'N', '2021-01-23 21:08:22', 1339550467939639299, NULL, NULL); INSERT INTO `sys_role_menu` VALUES (1352966446510100482, 1339550467939639303, 1352966403623342082, '2021-01-23 21:08:32', 1339550467939639299, NULL, NULL); INSERT INTO `sys_menu` VALUES (1352968673144459265, 1339550467939639317, '[-1],[1339550467939639317],', '多语言配置', 'languages', 'system', 'Y', 50.60, 1, NULL, '/view/languages', 'layui-icon-star-fill', NULL, 'icon-default', NULL, 0, NULL, 'N', '2021-01-23 21:17:23', 1339550467939639299, NULL, NULL); diff --git a/src/main/webapp/assets/expand/css/form.css b/src/main/webapp/assets/expand/css/form.css index 070b1db7..21370c26 100644 --- a/src/main/webapp/assets/expand/css/form.css +++ b/src/main/webapp/assets/expand/css/form.css @@ -16,4 +16,13 @@ padding: 10px 20px; background-color: #fff; box-shadow: 0 -1px 2px 0 rgba(0, 0, 0, .05); -} \ No newline at end of file +} + +.layui-fluid { + padding-bottom: 70px +} + +.layui-card { + padding-bottom: 20px +} + diff --git a/src/main/webapp/assets/modular/datasource/datasource.js b/src/main/webapp/assets/modular/datasource/datasource.js new file mode 100644 index 00000000..155e9329 --- /dev/null +++ b/src/main/webapp/assets/modular/datasource/datasource.js @@ -0,0 +1,105 @@ +layui.use(['table', 'admin', 'HttpRequest', 'func'], function () { + var $ = layui.$; + var table = layui.table; + var HttpRequest = layui.HttpRequest; + var admin = layui.admin; + var func = layui.func; + + /** + * 数据库信息表管理 + */ + var DatabaseInfo = { + tableId: "databaseInfoTable" + }; + + /** + * 初始化表格的列 + */ + DatabaseInfo.initColumn = function () { + return [[ + {type: 'checkbox'}, + {field: 'dbId', hide: true, title: '主键id'}, + {field: 'dbName', align: "center", sort: true, title: '数据库名称'}, + {field: 'jdbcDriver', align: "center", sort: true, title: '驱动类型', minWidth: 182}, + {field: 'username', align: "center", sort: true, title: '账号'}, + {field: 'password', align: "center", sort: true, title: '密码'}, + {field: 'jdbcUrl', align: "center", sort: true, title: 'jdbc的url'}, + {field: 'remarks', align: "center", sort: true, title: '备注'}, + {field: 'createTime', align: "center", sort: true, title: '创建时间', minWidth: 160}, + {align: 'center', toolbar: '#tableBar', title: '操作'} + ]]; + }; + + /** + * 点击查询按钮 + */ + DatabaseInfo.search = function () { + var queryData = {}; + queryData['dbName'] = $("#dbName").val(); + table.reload(DatabaseInfo.tableId, { + where: queryData, page: {curr: 1} + }); + }; + + /** + * 弹出添加对话框 + */ + DatabaseInfo.openAddDlg = function () { + func.open({ + height: 680, + title: '添加数据源', + content: Feng.ctxPath + '/view/datasource/add', + tableId: DatabaseInfo.tableId + }); + }; + + /** + * 点击删除 + * + * @param data 点击按钮时候的行数据 + */ + DatabaseInfo.onDeleteItem = function (data) { + var operation = function () { + var request = new HttpRequest(Feng.ctxPath + "/databaseInfo/delete", 'post', function (data) { + Feng.success("删除成功!"); + table.reload(DatabaseInfo.tableId); + }, function (data) { + Feng.error("删除失败!" + data.message + "!"); + }); + request.set("dbId", data.dbId); + request.start(true); + }; + Feng.confirm("是否删除?", operation); + }; + + // 渲染表格 + var tableResult = table.render({ + elem: '#' + DatabaseInfo.tableId, + url: Feng.ctxPath + '/databaseInfo/page', + page: true, + height: "full-158", + cellMinWidth: 100, + parseData: Feng.parseData, + cols: DatabaseInfo.initColumn() + }); + + // 搜索按钮点击事件 + $('#btnSearch').click(function () { + DatabaseInfo.search(); + }); + + // 添加按钮点击事件 + $('#btnAdd').click(function () { + DatabaseInfo.openAddDlg(); + }); + + // 工具条点击事件 + table.on('tool(' + DatabaseInfo.tableId + ')', function (obj) { + var data = obj.data; + var layEvent = obj.event; + + if (layEvent === 'delete') { + DatabaseInfo.onDeleteItem(data); + } + }); +}); diff --git a/src/main/webapp/assets/modular/datasource/datasource_add.js b/src/main/webapp/assets/modular/datasource/datasource_add.js new file mode 100644 index 00000000..27a40a1b --- /dev/null +++ b/src/main/webapp/assets/modular/datasource/datasource_add.js @@ -0,0 +1,23 @@ +layui.use(['form', 'admin', 'HttpRequest'], function () { + var $ = layui.jquery; + var HttpRequest = layui.HttpRequest; + var form = layui.form; + var admin = layui.admin; + + //表单提交事件 + form.on('submit(btnSubmit)', function (data) { + var request = new HttpRequest(Feng.ctxPath + "/databaseInfo/add", 'post', function (data) { + admin.closeThisDialog(); + Feng.success("添加成功!"); + admin.putTempData('formOk', true); + }, function (data) { + admin.closeThisDialog(); + Feng.error("添加失败!" + data.message) + }); + request.set(data.field); + request.start(true); + + return false; + }); + +}); diff --git a/src/main/webapp/pages/modular/datasource/datasource.html b/src/main/webapp/pages/modular/datasource/datasource.html new file mode 100644 index 00000000..d131a5f0 --- /dev/null +++ b/src/main/webapp/pages/modular/datasource/datasource.html @@ -0,0 +1,33 @@ +@layout("/layout/_container.html",{js:["/assets/modular/datasource/datasource.js"]}){ + + + 数据库信息表管理 + + + + + + + + + + + + + + 搜索 + 添加 + + + + + + + + + + + +@} diff --git a/src/main/webapp/pages/modular/datasource/datasource_add.html b/src/main/webapp/pages/modular/datasource/datasource_add.html new file mode 100644 index 00000000..ee8a2577 --- /dev/null +++ b/src/main/webapp/pages/modular/datasource/datasource_add.html @@ -0,0 +1,63 @@ +@layout("/layout/_form.html",{js:["/assets/modular/datasource/datasource_add.js"]}){ + + + + + + + 数据库名称* + + + + + + JDBC驱动* + + + Mysql + Oracle + Sql Server + Postgre Sql + + + + + JDBC账号* + + + + + + JDBC密码* + + + + + + JDBC URL* + + + + 参考: + oracle:jdbc:oracle:thin:\@127.0.0.1:1521:ORCLCDB + sql server:jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=guns + pg sql:jdbc:postgresql://127.0.0.1:5432/guns + mysql:jdbc:mysql://127.0.0.1:3306/guns?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT + + + + 备注 + + + + + + + + + 提交 + 取消 + + + +@}