Commit 887f0c70 by fengshuonan

Merge branch 'advanced-master'

# Conflicts:
#	guns-sys/src/main/webapp/assets/modular/system/dept/dept.js
#	guns-sys/src/main/webapp/assets/modular/system/dict/dict.js
#	guns-sys/src/main/webapp/assets/modular/system/dictType/dictType.js
#	guns-sys/src/main/webapp/assets/modular/system/log/login_log.js
#	guns-sys/src/main/webapp/assets/modular/system/notice/notice.js
#	guns-sys/src/main/webapp/assets/modular/system/role/role.js
#	guns-sys/src/main/webapp/assets/modular/system/user/user.js
#	guns-vip-gen/src/main/webapp/assets/db/db.js
#	guns-vip-main/src/main/webapp/assets/form/egForm.js
parents 67128157 61442592
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-vip</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>guns-base-db-container</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--基础组件-->
<dependency>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-base</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
package cn.stylefeng.guns.dbcontainer.core.collector;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
/**
* mybatis的一些配置收集
*
* @author fengshuonan
* @date 2019-06-15-18:30
*/
@Data
@Slf4j
@Configuration
public class SqlSessionFactoryCreator {
private final MybatisPlusProperties properties;
private final Interceptor[] interceptors;
private final DatabaseIdProvider databaseIdProvider;
private final ApplicationContext applicationContext;
public SqlSessionFactoryCreator(MybatisPlusProperties properties,
ObjectProvider<Interceptor[]> interceptorsProvider,
ObjectProvider<DatabaseIdProvider> databaseIdProvider,
ApplicationContext applicationContext) {
this.properties = properties;
this.interceptors = interceptorsProvider.getIfAvailable();
this.databaseIdProvider = databaseIdProvider.getIfAvailable();
this.applicationContext = applicationContext;
}
/**
* 创建SqlSessionFactory
*/
public synchronized SqlSessionFactory createSqlSessionFactory(DataSource dataSource) {
try {
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (!ObjectUtils.isEmpty(this.interceptors)) {
factory.setPlugins(this.interceptors);
}
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
GlobalConfig globalConfig = this.properties.getGlobalConfig();
if (this.applicationContext.getBeanNamesForType(MetaObjectHandler.class,
false, false).length > 0) {
MetaObjectHandler metaObjectHandler = this.applicationContext.getBean(MetaObjectHandler.class);
globalConfig.setMetaObjectHandler(metaObjectHandler);
}
//globalConfig中有缓存sqlSessionFactory,目前还没别的办法
SqlSessionFactory sqlSessionFactory = factory.getObject();
globalConfig.signGlobalConfig(sqlSessionFactory);
factory.setGlobalConfig(globalConfig);
return factory.getObject();
} catch (Exception e) {
log.error("初始化SqlSessionFactory错误!", e);
throw new ServiceException(500, "初始化SqlSessionFactory错误!");
}
}
}
package cn.stylefeng.guns.dbcontainer.core.context;
import cn.stylefeng.guns.dbcontainer.core.dao.DataBaseInfoDao;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 数据源的上下文容器(单例)
*
* @author fengshuonan
* @date 2019-06-12-13:37
*/
public class DataSourceContext {
/**
* 主数据源名称
*/
public static final String MASTER_DATASOURCE_NAME = "master";
/**
* 数据源容器
*/
private static Map<String, DataSource> DATA_SOURCES = new ConcurrentHashMap<>();
/**
* 初始化所有dataSource
*
* @author fengshuonan
* @Date 2019-06-12 13:48
*/
public static void initDataSource(DruidProperties masterDataSourceProperties) {
//清空数据库中的主数据源信息
new DataBaseInfoDao(masterDataSourceProperties).deleteMasterDatabaseInfo();
//初始化主数据源信息
new DataBaseInfoDao(masterDataSourceProperties).createMasterDatabaseInfo();
//从数据库中获取所有的数据源信息
DataBaseInfoDao dataBaseInfoDao = new DataBaseInfoDao(masterDataSourceProperties);
Map<String, DruidProperties> allDataBaseInfo = dataBaseInfoDao.getAllDataBaseInfo();
//根据数据源信息初始化所有的DataSource
for (Map.Entry<String, DruidProperties> entry : allDataBaseInfo.entrySet()) {
String dbName = entry.getKey();
DruidProperties druidProperties = entry.getValue();
//通过property创建DataSource
DataSource dataSource = createDataSource(dbName, druidProperties);
DATA_SOURCES.put(dbName, dataSource);
}
}
/**
* 新增datasource
*
* @author fengshuonan
* @Date 2019-06-12 14:51
*/
public static void addDataSource(String dbName, DataSource dataSource) {
DATA_SOURCES.put(dbName, dataSource);
}
/**
* 获取数据源
*
* @author fengshuonan
* @Date 2019-06-12 13:50
*/
public static Map<String, DataSource> getDataSources() {
return DATA_SOURCES;
}
/**
* 数据源创建模板
*/
public static DataSource createDataSource(String dataSourceName, DruidProperties druidProperties) {
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
atomikosDataSourceBean.setUniqueResourceName(dataSourceName);
atomikosDataSourceBean.setMaxPoolSize(20);
atomikosDataSourceBean.setBorrowConnectionTimeout(60);
atomikosDataSourceBean.setXaProperties(druidProperties.createProperties());
return atomikosDataSourceBean;
}
}
package cn.stylefeng.guns.dbcontainer.core.context;
import cn.stylefeng.guns.dbcontainer.core.collector.SqlSessionFactoryCreator;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.factory.DruidFactory;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import cn.stylefeng.roses.core.util.SpringContextHolder;
import org.apache.ibatis.session.SqlSessionFactory;
import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static cn.stylefeng.guns.dbcontainer.core.context.DataSourceContext.MASTER_DATASOURCE_NAME;
/**
* mybatis的sqlSessionFactory的上下文容器(单例)
*
* @author fengshuonan
* @date 2019-06-12-13:37
*/
public class SqlSessionFactoryContext {
private static Map<Object, SqlSessionFactory> sqlSessionFactories = new ConcurrentHashMap<>();
/**
* 添加sqlSessionFactory
*
* @author fengshuonan
* @Date 2019-06-12 15:28
*/
public static void addSqlSessionFactory(String name, SqlSessionFactory sqlSessionFactory) {
sqlSessionFactories.put(name, sqlSessionFactory);
}
/**
* 添加sqlSessionFactory
*
* @author fengshuonan
* @Date 2019-06-12 15:28
*/
public static void addSqlSessionFactory(String name, DatabaseInfo databaseInfo) {
//创建properties
DruidProperties druidProperties = DruidFactory.createDruidProperties(databaseInfo);
//创建dataSource
DataSource dataSource = DataSourceContext.createDataSource(name, druidProperties);
DataSourceContext.addDataSource(name, dataSource);
//创建sqlSessionFactory
SqlSessionFactoryCreator sqlSessionFactoryCreator = SpringContextHolder.getBean(SqlSessionFactoryCreator.class);
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryCreator.createSqlSessionFactory(dataSource);
SqlSessionFactoryContext.addSqlSessionFactory(name, sqlSessionFactory);
sqlSessionFactories.put(name, sqlSessionFactory);
}
/**
* 获取所有的sqlSessionFactory
*
* @author fengshuonan
* @Date 2019-06-12 13:49
*/
public static Map<Object, SqlSessionFactory> getSqlSessionFactorys() {
return sqlSessionFactories;
}
/**
* 初始化数据库中的数据源的SqlSessionFactory
*
* @author fengshuonan
* @Date 2019-06-15 19:51
*/
public static void initBaseSqlSessionFactory(SqlSessionFactoryCreator sqlSessionFactoryCreator) {
//获取数据库的数据源
Map<String, DataSource> dataSources = DataSourceContext.getDataSources();
//创建数据库中数据源的sqlSessionFactory
for (Map.Entry<String, DataSource> entry : dataSources.entrySet()) {
String dbName = entry.getKey();
DataSource dataSource = entry.getValue();
//如果是主数据源,跳过,否则会冲突
if (MASTER_DATASOURCE_NAME.equals(dbName)) {
continue;
} else {
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryCreator.createSqlSessionFactory(dataSource);
SqlSessionFactoryContext.addSqlSessionFactory(dbName, sqlSessionFactory);
}
}
}
}
package cn.stylefeng.guns.dbcontainer.core.dao;
import cn.hutool.core.date.DateUtil;
import cn.stylefeng.guns.dbcontainer.core.exception.DataSourceInitException;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import java.sql.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import static cn.stylefeng.guns.dbcontainer.core.context.DataSourceContext.MASTER_DATASOURCE_NAME;
/**
* 操作数据源信息的dao
*
* @author fengshuonan
* @date 2019-06-12-14:02
*/
@Slf4j
public class DataBaseInfoDao {
private String MYSQL_SQL_LIST = "select db_name,jdbc_driver,jdbc_url,user_name,password from database_info";
private String MYSQL_INSERT_SQL = "INSERT INTO `database_info`(`db_id`, `db_name`, `jdbc_driver`, `user_name`, `password`, `jdbc_url`, `remarks`, `create_time`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);";
private String MYSQL_DELETE_SQL = "DELETE from database_info where db_name = ?";
private DruidProperties druidProperties;
public DataBaseInfoDao(DruidProperties druidProperties) {
this.druidProperties = druidProperties;
}
/**
* 查询所有数据源列表
*
* @author fengshuonan
* @Date 2019-05-04 20:30
*/
public Map<String, DruidProperties> getAllDataBaseInfo() {
Map<String, DruidProperties> dataSourceList = new HashMap<>();
try {
Class.forName(druidProperties.getDriverClassName());
Connection conn = DriverManager.getConnection(
druidProperties.getUrl(), druidProperties.getUsername(), druidProperties.getPassword());
PreparedStatement preparedStatement = conn.prepareStatement(MYSQL_SQL_LIST);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
DruidProperties druidProperties = createDruidProperties(resultSet);
String dbName = resultSet.getString("db_name");
dataSourceList.put(dbName, druidProperties);
}
return dataSourceList;
} catch (Exception ex) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.QUERY_DATASOURCE_INFO_ERROR);
}
}
/**
* 初始化master的数据源,要和properties配置的数据源一致
*
* @author fengshuonan
* @Date 2019-06-15 10:20
*/
public void createMasterDatabaseInfo() {
try {
Class.forName(druidProperties.getDriverClassName());
Connection conn = DriverManager.getConnection(
druidProperties.getUrl(), druidProperties.getUsername(), druidProperties.getPassword());
PreparedStatement preparedStatement = conn.prepareStatement(MYSQL_INSERT_SQL);
preparedStatement.setLong(1, IdWorker.getId());
preparedStatement.setString(2, MASTER_DATASOURCE_NAME);
preparedStatement.setString(3, druidProperties.getDriverClassName());
preparedStatement.setString(4, druidProperties.getUsername());
preparedStatement.setString(5, druidProperties.getPassword());
preparedStatement.setString(6, druidProperties.getUrl());
preparedStatement.setString(7, "主数据源,项目启动数据源!");
preparedStatement.setString(8, DateUtil.formatDateTime(new Date()));
int i = preparedStatement.executeUpdate();
log.info("初始化master的databaseInfo信息!初始化" + i + "条!");
} catch (Exception ex) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.QUERY_DATASOURCE_INFO_ERROR);
}
}
/**
* 删除master的数据源信息
*
* @author fengshuonan
* @Date 2019-06-15 10:20
*/
public void deleteMasterDatabaseInfo() {
try {
Class.forName(druidProperties.getDriverClassName());
Connection conn = DriverManager.getConnection(
druidProperties.getUrl(), druidProperties.getUsername(), druidProperties.getPassword());
PreparedStatement preparedStatement = conn.prepareStatement(MYSQL_DELETE_SQL);
preparedStatement.setString(1, MASTER_DATASOURCE_NAME);
int i = preparedStatement.executeUpdate();
log.info("初始化master的databaseInfo信息!初始化" + i + "条!");
} catch (Exception ex) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.QUERY_DATASOURCE_INFO_ERROR);
}
}
/**
* 通过查询结果组装druidProperties
*
* @author fengshuonan
* @Date 2019-06-12 14:22
*/
private DruidProperties createDruidProperties(ResultSet resultSet) {
DruidProperties druidProperties = new DruidProperties();
druidProperties.setTestOnBorrow(true);
druidProperties.setTestOnReturn(true);
try {
druidProperties.setDriverClassName(resultSet.getString("jdbc_driver"));
druidProperties.setUrl(resultSet.getString("jdbc_url"));
druidProperties.setUsername(resultSet.getString("user_name"));
druidProperties.setPassword(resultSet.getString("password"));
} catch (SQLException e) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.QUERY_DATASOURCE_INFO_ERROR);
}
return druidProperties;
}
}
package cn.stylefeng.guns.dbcontainer.core.exception;
import cn.stylefeng.roses.kernel.model.exception.AbstractBaseExceptionEnum;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
/**
* 数据源容器初始化失败异常
*
* @author fengshuonan
* @date 2019-06-12-13:53
*/
public class DataSourceInitException extends ServiceException {
public DataSourceInitException(AbstractBaseExceptionEnum exception) {
super(exception);
}
public enum ExEnum implements AbstractBaseExceptionEnum {
DATA_SOURCE_READ_ERROR(500, "获取主数据源异常"),
INIT_DATA_SOURCE_ERROR(500, "初始化数据源异常"),
QUERY_DATASOURCE_INFO_ERROR(500, "查询数据库中数据源信息错误");
ExEnum(int code, String message) {
this.code = code;
this.message = message;
}
private Integer code;
private String message;
@Override
public Integer getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}
}
package cn.stylefeng.guns.generator.core.util;
package cn.stylefeng.guns.dbcontainer.core.util;
import cn.stylefeng.guns.generator.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
......
package cn.stylefeng.guns.generator.modular.controller;
package cn.stylefeng.guns.dbcontainer.modular.controller;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.generator.core.util.DbUtil;
import cn.stylefeng.guns.generator.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.generator.modular.mapper.DatabaseInfoMapper;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import cn.stylefeng.guns.dbcontainer.core.util.DbUtil;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.dbcontainer.modular.service.DatabaseInfoService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
......@@ -19,84 +21,124 @@ import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
import static cn.stylefeng.guns.generator.modular.controller.GeneratorController.CONDITION_FIELDS;
/**
* 代码生成控制器
* 数据库信息表控制器
*
* @author fengshuonan
* @date 2019-01-30-2:39 PM
* @author stylefeng
* @Date 2019-06-15 17:05:23
*/
@Controller
@RequestMapping("/db")
public class DatabaseController {
@RequestMapping("/databaseInfo")
public class DatabaseInfoController extends BaseController {
/**
* session中标识已选择条件字段的key
*/
public static String CONDITION_FIELDS = "CONDITION_FIELDS";
private String PREFIX = "/databaseInfo";
@Autowired
private DatabaseInfoMapper databaseInfoMapper;
private DatabaseInfoService databaseInfoService;
/**
* 数据库管理主页
* 跳转到主页面
*
* @author fengshuonan
* @Date 2019/1/30 2:49 PM
* @author stylefeng
* @Date 2019-06-15
*/
@RequestMapping("")
public String index() {
return "/db/db.html";
return PREFIX + "/databaseInfo.html";
}
/**
* 新增页面
*
* @author fengshuonan
* @Date 2019-01-11
* @author stylefeng
* @Date 2019-06-15
*/
@RequestMapping("/add")
public String add() {
return "/db/db_add.html";
return PREFIX + "/databaseInfo_add.html";
}
/**
* 新增
* 编辑页面
*
* @author fengshuonan
* @Date 2019-01-11
* @author stylefeng
* @Date 2019-06-15
*/
@RequestMapping("/edit")
public String edit() {
return PREFIX + "/databaseInfo_edit.html";
}
/**
* 新增接口
*
* @author stylefeng
* @Date 2019-06-15
*/
@RequestMapping("/addItem")
@ResponseBody
public Object addItem(DatabaseInfo databaseInfo) {
this.databaseInfoMapper.insert(databaseInfo);
return new SuccessResponseData();
public ResponseData addItem(DatabaseInfoParam databaseInfoParam) {
this.databaseInfoService.add(databaseInfoParam);
return ResponseData.success();
}
/**
* 删除
* 编辑接口
*
* @author fengshuonan
* @Date 2019-01-11
* @author stylefeng
* @Date 2019-06-15
*/
@RequestMapping("/delete")
@RequestMapping("/editItem")
@ResponseBody
public Object delete(Long dbId) {
this.databaseInfoMapper.deleteById(dbId);
return new SuccessResponseData();
public ResponseData editItem(DatabaseInfoParam databaseInfoParam) {
//this.databaseInfoService.update(databaseInfoParam);
return ResponseData.success();
}
/**
* 获取数据源列表
* 删除接口
*
* @author fengshuonan
* @Date 2019/1/30 2:49 PM
* @author stylefeng
* @Date 2019-06-15
*/
@RequestMapping("/list")
@RequestMapping("/delete")
@ResponseBody
public Object list() {
List<DatabaseInfo> all = databaseInfoMapper.selectList(new QueryWrapper<>());
public ResponseData delete(DatabaseInfoParam databaseInfoParam) {
this.databaseInfoService.delete(databaseInfoParam);
return ResponseData.success();
}
Page<DatabaseInfo> objectPage = new Page<>();
objectPage.setRecords(all);
/**
* 查看详情接口
*
* @author stylefeng
* @Date 2019-06-15
*/
@RequestMapping("/detail")
@ResponseBody
public ResponseData detail(DatabaseInfoParam databaseInfoParam) {
DatabaseInfo detail = this.databaseInfoService.getById(databaseInfoParam.getDbId());
return ResponseData.success(detail);
}
return LayuiPageFactory.createPageInfo(objectPage);
/**
* 查询列表
*
* @author stylefeng
* @Date 2019-06-15
*/
@ResponseBody
@RequestMapping("/list")
public LayuiPageInfo list(@RequestParam(value = "condition",required = false) String condition) {
DatabaseInfoParam databaseInfoParam = new DatabaseInfoParam();
databaseInfoParam.setDbName(condition);
return this.databaseInfoService.findPageBySpec(databaseInfoParam);
}
/**
......@@ -118,7 +160,7 @@ public class DatabaseController {
session.removeAttribute(CONDITION_FIELDS);
try {
DatabaseInfo databaseInfo = databaseInfoMapper.selectById(dbId);
DatabaseInfo databaseInfo = databaseInfoService.getById(dbId);
List<Map<String, Object>> maps = DbUtil.selectTables(databaseInfo);
Page<Map<String, Object>> objectPage = new Page<>();
objectPage.setRecords(maps);
......@@ -128,5 +170,6 @@ public class DatabaseController {
return LayuiPageFactory.createPageInfo(objectPage);
}
}
}
package cn.stylefeng.guns.generator.modular.entity;
package cn.stylefeng.guns.dbcontainer.modular.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
......@@ -14,7 +11,7 @@ import java.io.Serializable;
* </p>
*
* @author stylefeng
* @since 2019-05-11
* @since 2019-06-15
*/
@TableName("database_info")
public class DatabaseInfo implements Serializable {
......@@ -28,7 +25,7 @@ public class DatabaseInfo implements Serializable {
private Long dbId;
/**
* 数据库名称
* 数据库名称(英文名称)
*/
@TableField("db_name")
private String dbName;
......@@ -58,6 +55,12 @@ public class DatabaseInfo implements Serializable {
private String jdbcUrl;
/**
* 备注,摘要
*/
@TableField("remarks")
private String remarks;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
......@@ -112,6 +115,14 @@ public class DatabaseInfo implements Serializable {
this.jdbcUrl = jdbcUrl;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public Date getCreateTime() {
return createTime;
}
......@@ -129,6 +140,7 @@ public class DatabaseInfo implements Serializable {
", userName=" + userName +
", password=" + password +
", jdbcUrl=" + jdbcUrl +
", remarks=" + remarks +
", createTime=" + createTime +
"}";
}
......
package cn.stylefeng.guns.dbcontainer.modular.factory;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
/**
* 配置文件的创建
*
* @author fengshuonan
* @date 2019-06-15-20:05
*/
public class DruidFactory {
/**
* 创建druid配置
*
* @author fengshuonan
* @Date 2019-06-15 20:05
*/
public static DruidProperties createDruidProperties(DatabaseInfo databaseInfo) {
DruidProperties druidProperties = new DruidProperties();
druidProperties.setDriverClassName(databaseInfo.getJdbcDriver());
druidProperties.setUsername(databaseInfo.getUserName());
druidProperties.setPassword(databaseInfo.getPassword());
druidProperties.setUrl(databaseInfo.getJdbcUrl());
return druidProperties;
}
}
package cn.stylefeng.guns.generator.modular.mapper;
package cn.stylefeng.guns.dbcontainer.modular.mapper;
import cn.stylefeng.guns.generator.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.generator.modular.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.dbcontainer.modular.model.result.DatabaseInfoResult;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
......@@ -16,7 +16,7 @@ import java.util.Map;
* </p>
*
* @author stylefeng
* @since 2019-05-11
* @since 2019-06-15
*/
public interface DatabaseInfoMapper extends BaseMapper<DatabaseInfo> {
......@@ -24,32 +24,32 @@ public interface DatabaseInfoMapper extends BaseMapper<DatabaseInfo> {
* 获取列表
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
List<DatabaseInfoResult> customList(DatabaseInfoParam paramCondition);
List<DatabaseInfoResult> customList(@Param("paramCondition") DatabaseInfoParam paramCondition);
/**
* 获取map列表
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
List<Map<String, Object>> customMapList(DatabaseInfoParam paramCondition);
List<Map<String, Object>> customMapList(@Param("paramCondition") DatabaseInfoParam paramCondition);
/**
* 获取分页实体列表
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
Page<DatabaseInfoResult> customPageList(Page page, DatabaseInfoParam paramCondition);
Page<DatabaseInfoResult> customPageList(@Param("page") Page page, @Param("paramCondition") DatabaseInfoParam paramCondition);
/**
* 获取分页map列表
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
Page<Map<String, Object>> customPageMapList(Page page, DatabaseInfoParam paramCondition);
Page<Map<String, Object>> customPageMapList(@Param("page") Page page, @Param("paramCondition") DatabaseInfoParam paramCondition);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.stylefeng.guns.generator.modular.mapper.DatabaseInfoMapper">
<mapper namespace="cn.stylefeng.guns.dbcontainer.modular.mapper.DatabaseInfoMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.stylefeng.guns.generator.modular.entity.DatabaseInfo">
<id column="db_id" property="dbId"/>
<result column="db_name" property="dbName"/>
<result column="jdbc_driver" property="jdbcDriver"/>
<result column="user_name" property="userName"/>
<result column="password" property="password"/>
<result column="jdbc_url" property="jdbcUrl"/>
<result column="create_time" property="createTime"/>
<resultMap id="BaseResultMap" type="cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo">
<id column="db_id" property="dbId" />
<result column="db_name" property="dbName" />
<result column="jdbc_driver" property="jdbcDriver" />
<result column="user_name" property="userName" />
<result column="password" property="password" />
<result column="jdbc_url" property="jdbcUrl" />
<result column="remarks" property="remarks" />
<result column="create_time" property="createTime" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
db_id AS "dbId", db_name AS "dbName", jdbc_driver AS "jdbcDriver", user_name AS "userName", password AS "password", jdbc_url AS "jdbcUrl", create_time AS "createTime"
db_id AS "dbId", db_name AS "dbName", jdbc_driver AS "jdbcDriver", user_name AS "userName", password AS "password", jdbc_url AS "jdbcUrl", remarks AS "remarks", create_time AS "createTime"
</sql>
<select id="customList" resultType="cn.stylefeng.guns.generator.modular.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam">
<select id="customList" resultType="cn.stylefeng.guns.dbcontainer.modular.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
<if test="paramCondition.dbName != null and paramCondition.dbName != ''">
and db_name like CONCAT('%',#{paramCondition.dbName},'%')
</if>
</select>
<select id="customMapList" resultType="map" parameterType="cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam">
<select id="customMapList" resultType="map" parameterType="cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
<if test="paramCondition.dbName != null and paramCondition.dbName != ''">
and db_name like CONCAT('%',#{paramCondition.dbName},'%')
</if>
</select>
<select id="customPageList" resultType="cn.stylefeng.guns.generator.modular.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam">
<select id="customPageList" resultType="cn.stylefeng.guns.dbcontainer.modular.model.result.DatabaseInfoResult" parameterType="cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
<if test="paramCondition.dbName != null and paramCondition.dbName != ''">
and db_name like CONCAT('%',#{paramCondition.dbName},'%')
</if>
</select>
<select id="customPageMapList" resultType="map" parameterType="cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam">
<select id="customPageMapList" resultType="map" parameterType="cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam">
select
<include refid="Base_Column_List"/>
from database_info where 1 = 1
<if test="paramCondition.dbName != null and paramCondition.dbName != ''">
and db_name like CONCAT('%',#{paramCondition.dbName},'%')
</if>
</select>
</mapper>
package cn.stylefeng.guns.generator.modular.model.params;
package cn.stylefeng.guns.dbcontainer.modular.model.params;
import lombok.Data;
import cn.stylefeng.roses.kernel.model.validator.BaseValidatingParam;
import java.util.Date;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* <p>
......@@ -12,7 +12,7 @@ import java.math.BigDecimal;
* </p>
*
* @author stylefeng
* @since 2019-05-11
* @since 2019-06-15
*/
@Data
public class DatabaseInfoParam implements Serializable, BaseValidatingParam {
......@@ -26,7 +26,7 @@ public class DatabaseInfoParam implements Serializable, BaseValidatingParam {
private Long dbId;
/**
* 数据库名称
* 数据库名称(英文名称)
*/
private String dbName;
......@@ -51,6 +51,11 @@ public class DatabaseInfoParam implements Serializable, BaseValidatingParam {
private String jdbcUrl;
/**
* 备注,摘要
*/
private String remarks;
/**
* 创建时间
*/
private Date createTime;
......
package cn.stylefeng.guns.generator.modular.model.result;
package cn.stylefeng.guns.dbcontainer.modular.model.result;
import lombok.Data;
import java.util.Date;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* <p>
......@@ -11,7 +11,7 @@ import java.math.BigDecimal;
* </p>
*
* @author stylefeng
* @since 2019-05-11
* @since 2019-06-15
*/
@Data
public class DatabaseInfoResult implements Serializable {
......@@ -25,7 +25,7 @@ public class DatabaseInfoResult implements Serializable {
private Long dbId;
/**
* 数据库名称
* 数据库名称(英文名称)
*/
private String dbName;
......@@ -50,6 +50,11 @@ public class DatabaseInfoResult implements Serializable {
private String jdbcUrl;
/**
* 备注,摘要
*/
private String remarks;
/**
* 创建时间
*/
private Date createTime;
......
package cn.stylefeng.guns.generator.modular.service;
package cn.stylefeng.guns.dbcontainer.modular.service;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.generator.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.generator.modular.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.dbcontainer.modular.model.result.DatabaseInfoResult;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
......@@ -14,7 +14,7 @@ import java.util.List;
* </p>
*
* @author stylefeng
* @since 2019-05-11
* @since 2019-06-15
*/
public interface DatabaseInfoService extends IService<DatabaseInfo> {
......@@ -22,7 +22,7 @@ public interface DatabaseInfoService extends IService<DatabaseInfo> {
* 新增
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
void add(DatabaseInfoParam param);
......@@ -30,7 +30,7 @@ public interface DatabaseInfoService extends IService<DatabaseInfo> {
* 删除
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
void delete(DatabaseInfoParam param);
......@@ -38,7 +38,7 @@ public interface DatabaseInfoService extends IService<DatabaseInfo> {
* 更新
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
void update(DatabaseInfoParam param);
......@@ -46,7 +46,7 @@ public interface DatabaseInfoService extends IService<DatabaseInfo> {
* 查询单条数据,Specification模式
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
DatabaseInfoResult findBySpec(DatabaseInfoParam param);
......@@ -54,7 +54,7 @@ public interface DatabaseInfoService extends IService<DatabaseInfo> {
* 查询列表,Specification模式
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
List<DatabaseInfoResult> findListBySpec(DatabaseInfoParam param);
......@@ -62,7 +62,7 @@ public interface DatabaseInfoService extends IService<DatabaseInfo> {
* 查询分页数据,Specification模式
*
* @author stylefeng
* @Date 2019-05-11
* @Date 2019-06-15
*/
LayuiPageInfo findPageBySpec(DatabaseInfoParam param);
......
package cn.stylefeng.guns.generator.modular.service.impl;
package cn.stylefeng.guns.dbcontainer.modular.service.impl;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.generator.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.generator.modular.mapper.DatabaseInfoMapper;
import cn.stylefeng.guns.generator.modular.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.generator.modular.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.generator.modular.service.DatabaseInfoService;
import cn.stylefeng.guns.dbcontainer.core.context.SqlSessionFactoryContext;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.mapper.DatabaseInfoMapper;
import cn.stylefeng.guns.dbcontainer.modular.model.params.DatabaseInfoParam;
import cn.stylefeng.guns.dbcontainer.modular.model.result.DatabaseInfoResult;
import cn.stylefeng.guns.dbcontainer.modular.service.DatabaseInfoService;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.List;
......@@ -22,15 +24,21 @@ import java.util.List;
* </p>
*
* @author stylefeng
* @since 2019-05-11
* @since 2019-06-15
*/
@Service
public class DatabaseInfoServiceImpl extends ServiceImpl<DatabaseInfoMapper, DatabaseInfo> implements DatabaseInfoService {
@Override
@Transactional(rollbackFor = Exception.class)
public void add(DatabaseInfoParam param) {
//数据库中插入记录
DatabaseInfo entity = getEntity(param);
this.save(entity);
//往上下文中添加数据源
SqlSessionFactoryContext.addSqlSessionFactory(param.getDbName(), entity);
}
@Override
......
layui.use(['table', 'admin', 'ax'], function () {
var $ = layui.$;
var table = layui.table;
var $ax = layui.ax;
var admin = layui.admin;
/**
* 数据库信息表管理
*/
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['condition'] = $("#condition").val();
table.reload(DatabaseInfo.tableId, {
where: queryData, page: {curr: 1}
});
};
/**
* 弹出添加对话框
*/
DatabaseInfo.openAddDlg = function () {
window.location.href = Feng.ctxPath + '/databaseInfo/add';
};
/**
* 导出excel按钮
*/
DatabaseInfo.exportExcel = function () {
var checkRows = table.checkStatus(DatabaseInfo.tableId);
if (checkRows.data.length === 0) {
Feng.error("请选择要导出的数据");
} else {
table.exportFile(tableResult.config.id, checkRows.data, 'xls');
}
};
/**
* 点击编辑
*
* @param data 点击按钮时候的行数据
*/
DatabaseInfo.openEditDlg = function (data) {
window.location.href = Feng.ctxPath + '/databaseInfo/edit?dbId=' + data.dbId;
};
/**
* 点击删除
*
* @param data 点击按钮时候的行数据
*/
DatabaseInfo.onDeleteItem = function (data) {
var operation = function () {
var ajax = new $ax(Feng.ctxPath + "/databaseInfo/delete", function (data) {
Feng.success("删除成功!");
table.reload(DatabaseInfo.tableId);
}, function (data) {
Feng.error("删除失败!" + data.responseJSON.message + "!");
});
ajax.set("dbId", data.dbId);
ajax.start();
};
Feng.confirm("是否删除?", operation);
};
// 渲染表格
var tableResult = table.render({
elem: '#' + DatabaseInfo.tableId,
url: Feng.ctxPath + '/databaseInfo/list',
page: true,
height: "full-158",
cellMinWidth: 100,
cols: DatabaseInfo.initColumn()
});
// 搜索按钮点击事件
$('#btnSearch').click(function () {
DatabaseInfo.search();
});
// 添加按钮点击事件
$('#btnAdd').click(function () {
DatabaseInfo.openAddDlg();
});
// 导出excel
$('#btnExp').click(function () {
DatabaseInfo.exportExcel();
});
// 工具条点击事件
table.on('tool(' + DatabaseInfo.tableId + ')', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') {
DatabaseInfo.openEditDlg(data);
} else if (layEvent === 'delete') {
DatabaseInfo.onDeleteItem(data);
}
});
});
/**
* 添加或者修改页面
*/
var DatabaseInfoInfoDlg = {
data: {
dbName: "",
jdbcDriver: "",
userName: "",
password: "",
jdbcUrl: "",
remarks: "",
createTime: ""
}
};
layui.use(['form', 'admin', 'ax'], function () {
var $ = layui.jquery;
var $ax = layui.ax;
var form = layui.form;
var admin = layui.admin;
//让当前iframe弹层高度适应
admin.iframeAuto();
//表单提交事件
form.on('submit(btnSubmit)', function (data) {
var ajax = new $ax(Feng.ctxPath + "/databaseInfo/addItem", function (data) {
Feng.success("添加成功!");
window.location.href = Feng.ctxPath + '/databaseInfo'
}, function (data) {
Feng.error("添加失败!" + data.responseJSON.message)
});
ajax.set(data.field);
ajax.start();
return false;
});
//返回按钮
$("#backupPage").click(function () {
window.location.href = Feng.ctxPath + '/databaseInfo'
});
});
\ No newline at end of file
/**
* 详情对话框
*/
var DatabaseInfoInfoDlg = {
data: {
dbName: "",
jdbcDriver: "",
userName: "",
password: "",
jdbcUrl: "",
remarks: "",
createTime: ""
}
};
layui.use(['form', 'admin', 'ax'], function () {
var $ = layui.jquery;
var $ax = layui.ax;
var form = layui.form;
var admin = layui.admin;
//让当前iframe弹层高度适应
admin.iframeAuto();
//获取详情信息,填充表单
var ajax = new $ax(Feng.ctxPath + "/databaseInfo/detail?dbId=" + Feng.getUrlParam("dbId"));
var result = ajax.start();
form.val('databaseInfoForm', result.data);
//表单提交事件
form.on('submit(btnSubmit)', function (data) {
var ajax = new $ax(Feng.ctxPath + "/databaseInfo/editItem", function (data) {
Feng.success("更新成功!");
window.location.href = Feng.ctxPath + '/databaseInfo'
}, function (data) {
Feng.error("更新失败!" + data.responseJSON.message)
});
ajax.set(data.field);
ajax.start();
return false;
});
//返回按钮
$("#backupPage").click(function () {
window.location.href = Feng.ctxPath + '/databaseInfo'
});
});
\ No newline at end of file
@layout("/common/_container.html",{js:["/assets/databaseInfo/databaseInfo.js"]}){
<div class="layui-body-header">
<span class="layui-body-header-title">数据库信息表管理</span>
</div>
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-sm12 layui-col-md12 layui-col-lg12">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-form toolbar">
<div class="layui-form-item">
<div class="layui-inline">
<input id="condition" class="layui-input" type="text" placeholder="名称"/>
</div>
<div class="layui-inline">
<button id="btnSearch" class="layui-btn icon-btn"><i class="layui-icon">&#xe615;</i>搜索</button>
<button id="btnAdd" class="layui-btn icon-btn"><i class="layui-icon">&#xe654;</i>添加</button>
<button id="btnExp" class="layui-btn icon-btn"><i class="layui-icon">&#xe67d;</i>导出</button>
</div>
</div>
</div>
<table class="layui-table" id="databaseInfoTable" lay-filter="databaseInfoTable"></table>
</div>
</div>
</div>
</div>
</div>
<script type="text/html" id="tableBar">
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete">删除</a>
</script>
@}
\ No newline at end of file
@layout("/common/_container.html",{js:["/assets/databaseInfo/databaseInfo_add.js"]}){
<div class="layui-body-header">
<span class="layui-body-header-title">添加</span>
</div>
<div class="layui-fluid " style="">
<div class="layui-card">
<div class="layui-card-body">
<form id="databaseInfoForm" lay-filter="databaseInfoForm" class="layui-form model-form" style="max-width: 700px;margin: 40px auto;">
<input name="dbId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">数据库名称<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="dbName" name="dbName" placeholder="数据库名称" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC驱动<span style="color: red;">*</span></label>
<div class="layui-input-block">
<select name="jdbcDriver">
<option value="com.mysql.cj.jdbc.Driver">com.mysql.cj.jdbc.Driver</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC账号<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="userName" name="userName" placeholder="账号" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC密码<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="password" name="password" placeholder="密码" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC URL<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="jdbcUrl" name="jdbcUrl" placeholder="jdbc的url" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<input id="remarks" name="remarks" placeholder="备注" type="text" class="layui-input" autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-filter="btnSubmit" lay-submit>&emsp;提交&emsp;</button>
<button class="layui-btn layui-btn-primary" type="button" id="backupPage">&emsp;返回&emsp;</button>
</div>
</div>
</form>
</div>
</div>
</div>
@}
\ No newline at end of file
@layout("/common/_container.html",{js:["/assets/databaseInfo/databaseInfo_edit.js"]}){
<div class="layui-body-header">
<span class="layui-body-header-title">修改</span>
</div>
<div class="layui-fluid " style="">
<div class="layui-card">
<div class="layui-card-body">
<form id="databaseInfoForm" lay-filter="databaseInfoForm" class="layui-form model-form" style="max-width: 700px;margin: 40px auto;">
<input name="dbId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">数据库名称<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="dbName" name="dbName" placeholder="数据库名称" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC驱动<span style="color: red;">*</span></label>
<div class="layui-input-block">
<select name="jdbcDriver">
<option value="com.mysql.cj.jdbc.Driver">com.mysql.cj.jdbc.Driver</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC账号<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="userName" name="userName" placeholder="账号" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC密码<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="password" name="password" placeholder="密码" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">JDBC URL<span style="color: red;">*</span></label>
<div class="layui-input-block">
<input id="jdbcUrl" name="jdbcUrl" placeholder="jdbc的url" type="text" class="layui-input" lay-verify="required" required autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">备注</label>
<div class="layui-input-block">
<input id="remarks" name="remarks" placeholder="备注" type="text" class="layui-input" autocomplete="off"/>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-filter="btnSubmit" lay-submit>&emsp;提交&emsp;</button>
<button class="layui-btn layui-btn-primary" type="button" id="backupPage">&emsp;返回&emsp;</button>
</div>
</div>
</form>
</div>
</div>
</div>
@}
\ No newline at end of file
/**
* Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.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 cn.stylefeng.guns.sys.config.datasource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* 多数据源配置,多数据源配置因为和单数据源冲突,所以现在默认版本删除了多数据源配置
* <p>
* 可参考 https://gitee.com/stylefeng/guns/tree/multi-datasource/
*
* @author stylefeng
* @Date 2017/5/20 21:58
*/
@Configuration
@ConditionalOnProperty(prefix = "guns.muti-datasource", name = "open", havingValue = "false", matchIfMissing = true)
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan(basePackages = {"cn.stylefeng.guns.sys.modular.*.mapper",
"cn.stylefeng.guns.generator.modular.mapper",
"cn.stylefeng.guns.modular.*.mapper",
"cn.stylefeng.guns.sms.modular.mapper",
"cn.stylefeng.guns.oauth.modular.mapper"})
public class SingleDataSourceConfig {
}
......@@ -60,7 +60,16 @@ public interface Const {
/**
* 不需要权限验证的资源表达式
*/
List<String> NONE_PERMISSION_RES = CollectionUtil.newLinkedList("/assets/**", "/gunsApi/**", "/login", "/global/sessionError", "/kaptcha", "/error", "/global/error", "/oauth/**");
List<String> NONE_PERMISSION_RES = CollectionUtil.newLinkedList(
"/assets/**",
"/gunsApi/**",
"/login",
"/global/sessionError",
"/kaptcha",
"/error",
"/global/error",
"/oauth/**",
"/tran/**");
/**
* OAuth2登录用户的账号标识
......
......@@ -23,9 +23,9 @@ layui.use(['table', 'admin', 'ax', 'ztree'], function () {
{type: 'checkbox'},
{field: 'deptId', hide: true, sort: true, title: 'id'},
{field: 'simpleName', align: "center", sort: true, title: '部门简称'},
{field: 'fullName',align: "center", sort: true, title: '部门全称'},
{field: 'sort',align: "center", sort: true, title: '排序'},
{field: 'description',align: "center", sort: true, title: '备注'},
{field: 'fullName', align: "center", sort: true, title: '部门全称'},
{field: 'sort', align: "center", sort: true, title: '排序'},
{field: 'description', align: "center", sort: true, title: '备注'},
{align: 'center', toolbar: '#tableBar', title: '操作', minWidth: 200}
]];
};
......@@ -83,7 +83,15 @@ layui.use(['table', 'admin', 'ax', 'ztree'], function () {
* @param data 点击按钮时候的行数据
*/
Dept.onEditDept = function (data) {
window.location.href = Feng.ctxPath + "/dept/dept_update?deptId="+ data.deptId;
admin.putTempData('formOk', false);
top.layui.admin.open({
type: 2,
title: '修改部门',
content: Feng.ctxPath + '/dept/dept_update?deptId=' + data.deptId,
end: function () {
admin.getTempData('formOk') && table.reload(Dept.tableId);
}
});
};
/**
......@@ -127,7 +135,7 @@ layui.use(['table', 'admin', 'ax', 'ztree'], function () {
// 添加按钮点击事件
$('#btnAdd').click(function () {
window.location.href = Feng.ctxPath + "/dept/dept_add";
Dept.openAddDept();
});
// 导出excel
......
......@@ -17,7 +17,7 @@ layui.use(['table', 'ax', 'treetable'], function () {
Dict.initColumn = function () {
return [[
{type: 'checkbox'},
{field: 'dictId', hide: true, title: '字典id'},
{field: 'dictId', align: "center", hide: true, title: '字典id'},
{field: 'name', align: "center", sort: true, title: '字典名称'},
{field: 'code', align: "center", sort: true, title: '字典编码'},
{field: 'description', align: "center", sort: true, title: '字典的描述'},
......
......@@ -24,7 +24,7 @@ layui.use(['table', 'ax'], function () {
}
},
{
field: 'code', align: "center", sort: true, title: '类型编码', minWidth:166 , templet: function (d) {
field: 'code', align: "center", sort: true, title: '类型编码', minWidth: 166 , templet: function (d) {
var url = Feng.ctxPath + '/dict?dictTypeId=' + d.dictTypeId;
return '<a style="color: #01AAED;" href="' + url + '">' + d.code + '</a>';
}
......@@ -40,7 +40,7 @@ layui.use(['table', 'ax'], function () {
},
{field: 'description', align: "center", sort: true, title: '字典描述'},
{
field: 'status', align: "center", sort: true, title: '状态', templet: function (d) {
field: 'status', sort: true, align: "center", title: '状态', templet: function (d) {
if (d.status === 'ENABLE') {
return "启用";
} else {
......@@ -48,7 +48,7 @@ layui.use(['table', 'ax'], function () {
}
}
},
{field: 'createTime', align: "center", minWidth:161 , sort: true, title: '添加时间'},
{field: 'createTime', align: "center", sort: true, title: '添加时间', minWidth: 161 },
{field: 'createUser', align: "center", sort: true, title: '创建人'},
{align: 'center', toolbar: '#tableBar', title: '操作'}
]];
......
......@@ -19,7 +19,7 @@ layui.use(['layer', 'form', 'table', 'admin', 'ax'], function () {
Notice.initColumn = function () {
return [[
{type: 'checkbox'},
{field: 'noticeId', align: "center", hide: true, sort: true, title: 'id'},
{field: 'noticeId', hide: true, sort: true, title: 'id'},
{field: 'title', align: "center", sort: true, title: '标题'},
{field: 'content', align: "center", sort: true, title: '内容'},
{field: 'createrName', align: "center", sort: true, title: '发布者'},
......@@ -60,7 +60,15 @@ layui.use(['layer', 'form', 'table', 'admin', 'ax'], function () {
* @param data 点击按钮时候的行数据
*/
Notice.onEditNotice = function (data) {
window.location.href = Feng.ctxPath + "/notice/notice_update/"+ data.noticeId;
admin.putTempData('formOk', false);
top.layui.admin.open({
type: 2,
title: '通知详情',
content: Feng.ctxPath + '/notice/notice_update/' + data.noticeId,
end: function () {
admin.getTempData('formOk') && table.reload(Notice.tableId);
}
});
};
/**
......@@ -99,7 +107,7 @@ layui.use(['layer', 'form', 'table', 'admin', 'ax'], function () {
// 添加按钮点击事件
$('#btnAdd').click(function () {
window.location.href = Feng.ctxPath + "/notice/notice_add";
Notice.openAddNotice();
});
// 工具条点击事件
......
......@@ -74,7 +74,15 @@ layui.use(['layer', 'form', 'table', 'admin', 'ax'], function () {
* @param data 点击按钮时候的行数据
*/
Role.onEditRole = function (data) {
window.location.href = Feng.ctxPath + "/role/role_edit?roleId="+ data.roleId;
admin.putTempData('formOk', false);
top.layui.admin.open({
type: 2,
title: '修改角色',
content: Feng.ctxPath + '/role/role_edit?roleId=' + data.roleId,
end: function () {
admin.getTempData('formOk') && table.reload(Role.tableId);
}
});
};
/**
......@@ -132,7 +140,7 @@ layui.use(['layer', 'form', 'table', 'admin', 'ax'], function () {
// 添加按钮点击事件
$('#btnAdd').click(function () {
window.location.href = Feng.ctxPath + "/role/role_add";
Role.openAddRole();
});
// 导出excel
......
......@@ -93,7 +93,15 @@ layui.use(['layer', 'form', 'table', 'ztree', 'laydate', 'admin', 'ax'], functio
* @param data 点击按钮时候的行数据
*/
MgrUser.onEditUser = function (data) {
window.location.href = Feng.ctxPath + "/mgr/user_edit?userId="+ data.userId;
admin.putTempData('formOk', false);
top.layui.admin.open({
type: 2,
title: '编辑用户',
content: Feng.ctxPath + '/mgr/user_edit?userId=' + data.userId,
end: function () {
admin.getTempData('formOk') && table.reload(MgrUser.tableId);
}
});
};
/**
......@@ -206,8 +214,7 @@ layui.use(['layer', 'form', 'table', 'ztree', 'laydate', 'admin', 'ax'], functio
// 添加按钮点击事件
$('#btnAdd').click(function () {
//MgrUser.openAddUser();
window.location.href = Feng.ctxPath + "/mgr/user_add";
MgrUser.openAddUser();
});
// 导出excel
......
......@@ -24,6 +24,13 @@
<version>1.0.0</version>
</dependency>
<!--基础组件-->
<dependency>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-base-db-container</artifactId>
<version>1.0.0</version>
</dependency>
<!--mp代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
......
......@@ -3,13 +3,13 @@ package cn.stylefeng.guns.generator.modular.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.mapper.DatabaseInfoMapper;
import cn.stylefeng.guns.generator.core.generator.base.model.ContextParam;
import cn.stylefeng.guns.generator.core.generator.guns.GunsExecutor;
import cn.stylefeng.guns.generator.core.generator.restful.mybatisplus.param.MpParam;
import cn.stylefeng.guns.generator.core.util.ConcatUtil;
import cn.stylefeng.guns.generator.core.util.MapperConditionMapHolder;
import cn.stylefeng.guns.generator.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.generator.modular.mapper.DatabaseInfoMapper;
import cn.stylefeng.guns.generator.modular.service.TableService;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
......
package cn.stylefeng.guns.generator.modular.service;
import cn.stylefeng.guns.generator.core.util.DbUtil;
import cn.stylefeng.guns.generator.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.generator.modular.mapper.DatabaseInfoMapper;
import cn.stylefeng.guns.dbcontainer.core.util.DbUtil;
import cn.stylefeng.guns.dbcontainer.modular.entity.DatabaseInfo;
import cn.stylefeng.guns.dbcontainer.modular.mapper.DatabaseInfoMapper;
import cn.stylefeng.roses.core.util.HttpContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......
......@@ -31,7 +31,7 @@ layui.use(['layer', 'ax', 'form', 'laydate', 'element', 'table'], function () {
, {field: 'jdbcDriver', align: "center", title: 'jdbc的驱动类型', minWidth: 168}
, {field: 'userName', align: "center", title: '数据库连接的账号'}
, {field: 'password', align: "center", title: '密码'}
, {field: 'jdbcUrl', align: "center", title: 'jdbc的url'}
, {field: 'jdbcUrl', align: "center", title: 'jdbc的url', minWidth: 1184}
, {field: 'createTime', align: "center", title: '创建时间', minWidth: 159}
, {align: 'center', toolbar: '#tableBar', title: '操作'}
]]
......
......@@ -27,7 +27,7 @@ layui.use(['layer', 'ax', 'form', 'laydate', 'element', 'table'], function () {
table.render({
elem: '#dbTableList'
, url: Feng.ctxPath + '/db/tableList'
, url: Feng.ctxPath + '/databaseInfo/tableList'
, page: false
, cols: [[
{type: 'checkbox'}
......
@layout("/common/_container.html",{title:"代码生成",bg:"bg-white",js:["/assets/gen/gen.js"]}){
@layout("/common/_container.html",{title:"代码生成",js:["/assets/gen/gen.js"]}){
<div class="layui-body-header">
<span class="layui-body-header-title">代码生成</span>
</div>
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
<ul class="layui-tab-title">
<li class="layui-this" id="code_gen">代码生成</li>
<li id="db_config">数据库配置</li>
<li id="add_db">添加数据源</li>
</ul>
<div class="layui-tab-content" style="height: 100px;">
<div class="layui-tab-item layui-show">
<div class="layui-fluid">
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-xs12">
<div class="layui-col-lg12">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-form">
......@@ -70,11 +62,6 @@
</div>
</div>
</div>
</div>
</div>
<div class="layui-tab-item">加载中...</div>
<div class="layui-tab-item">加载中...</div>
</div>
</div>
<script type="text/html" id="tableBar">
......
......@@ -38,6 +38,13 @@
<version>1.0.0</version>
</dependency>
<!-- 数据源容器-->
<dependency>
<groupId>cn.stylefeng</groupId>
<artifactId>guns-base-db-container</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 分布式job -->
<!-- <dependency>-->
<!-- <groupId>cn.stylefeng</groupId>-->
......
......@@ -15,12 +15,12 @@
*/
package cn.stylefeng.guns;
import cn.stylefeng.roses.core.config.MybatisDataSourceAutoConfiguration;
import cn.stylefeng.roses.core.config.WebAutoConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* SpringBoot方式启动类
......@@ -28,8 +28,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* @author stylefeng
* @Date 2017/5/21 12:06
*/
@SpringBootApplication(exclude = {WebAutoConfiguration.class})
@EnableScheduling
@SpringBootApplication(exclude = {WebAutoConfiguration.class, MybatisDataSourceAutoConfiguration.class})
public class GunsApplication {
private final static Logger logger = LoggerFactory.getLogger(GunsApplication.class);
......
package cn.stylefeng.guns.sys.config.properties;
package cn.stylefeng.guns.config;
import cn.stylefeng.guns.sys.core.properties.BeetlProperties;
import cn.stylefeng.guns.sys.core.properties.GunsProperties;
......@@ -15,12 +15,24 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class GunsPropertiesConfig {
/**
* beetl模板的配置
*
* @author fengshuonan
* @Date 2019-06-13 08:55
*/
@Bean
@ConfigurationProperties(prefix = BeetlProperties.BEETLCONF_PREFIX)
public BeetlProperties beetlProperties() {
return new BeetlProperties();
}
/**
* Guns的属性配置
*
* @author fengshuonan
* @Date 2019-06-13 08:56
*/
@Bean
@ConfigurationProperties(prefix = GunsProperties.PREFIX)
public GunsProperties gunsProperties() {
......
......@@ -13,6 +13,7 @@ import org.springframework.scheduling.quartz.SchedulerFactoryBean;
* @Date 2019/2/24 16:23
*/
//@Configuration
//@EnableScheduling
public class SchedulingConfig {
/**
......
......@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config;
package cn.stylefeng.guns.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
......@@ -36,7 +35,6 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
*/
@Configuration
@EnableSwagger2
@ConditionalOnProperty(prefix = "guns", name = "swagger-open", havingValue = "true")
public class SwaggerConfig {
@Bean
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config;
package cn.stylefeng.guns.config.cache;
import net.sf.ehcache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
......
/**
* Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.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 cn.stylefeng.guns.config.datasource;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import cn.stylefeng.roses.core.mutidatasource.aop.MultiSourceExAop;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import static cn.stylefeng.guns.dbcontainer.core.context.DataSourceContext.MASTER_DATASOURCE_NAME;
/**
* 多数据源配置<br/>
* <p>
* 注:由于引入多数据源,所以让spring事务的aop要在多数据源切换aop的后面
*
* @author stylefeng
* @Date 2017/5/20 21:58
*/
@Configuration
public class DataSourceConfig {
/**
* 默认主数据源配置
*/
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DruidProperties druidProperties() {
return new DruidProperties();
}
/**
* 主数据源实例
*/
@Primary
@Bean
public DataSource dataSourcePrimary(@Qualifier("druidProperties") DruidProperties druidProperties) {
AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
atomikosDataSourceBean.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
atomikosDataSourceBean.setUniqueResourceName(MASTER_DATASOURCE_NAME);
atomikosDataSourceBean.setMaxPoolSize(100);
atomikosDataSourceBean.setBorrowConnectionTimeout(60);
atomikosDataSourceBean.setXaProperties(druidProperties.createProperties());
return atomikosDataSourceBean;
}
/**
* 多数据源切换的aop
*/
@Bean
public MultiSourceExAop multiSourceExAop() {
return new MultiSourceExAop();
}
}
\ No newline at end of file
package cn.stylefeng.guns.sys.config.datasource;
package cn.stylefeng.guns.config.datasource;
import cn.stylefeng.guns.sys.core.shiro.ShiroKit;
import cn.stylefeng.roses.core.metadata.CustomMetaObjectHandler;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* mp的插件拓展
* mp的插件拓展和资源扫描
*
* @author fengshuonan
* @Date 2019/5/10 21:33
*/
@Configuration
public class MpPluginsConfig {
@MapperScan(basePackages = {"cn.stylefeng.guns.sys.modular.*.mapper",
"cn.stylefeng.guns.modular.*.mapper",
"cn.stylefeng.guns.sms.modular.mapper",
"cn.stylefeng.guns.oauth.modular.mapper",
"cn.stylefeng.guns.dbcontainer.modular.mapper"})
public class PluginsConfig {
/**
* 拓展核心包中的字段包装器
......
/**
* Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.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 cn.stylefeng.guns.config.datasource;
import cn.stylefeng.guns.dbcontainer.core.collector.SqlSessionFactoryCreator;
import cn.stylefeng.guns.dbcontainer.core.context.DataSourceContext;
import cn.stylefeng.guns.dbcontainer.core.context.SqlSessionFactoryContext;
import cn.stylefeng.guns.dbcontainer.core.exception.DataSourceInitException;
import cn.stylefeng.roses.core.config.properties.DruidProperties;
import cn.stylefeng.roses.core.mutidatasource.mybatis.OptionalSqlSessionTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import static cn.stylefeng.guns.dbcontainer.core.context.DataSourceContext.MASTER_DATASOURCE_NAME;
/**
* 多数据源配置<br/>
* <p>
* 注:由于引入多数据源,所以让spring事务的aop要在多数据源切换aop的后面
*
* @author stylefeng
* @Date 2017/5/20 21:58
*/
@Slf4j
@Configuration
@Import(SqlSessionFactoryCreator.class)
public class SqlSessionFactoryConfig {
/**
* 主sqlSessionFactory
*/
@Primary
@Bean
public SqlSessionFactory sqlSessionFactoryPrimary(@Qualifier("dataSourcePrimary") DataSource dataSource,
SqlSessionFactoryCreator sqlSessionFactoryCreator) {
return sqlSessionFactoryCreator.createSqlSessionFactory(dataSource);
}
/**
* 多数据源sqlSessionTemplate切换模板
*/
@Bean(name = "gunsSqlSessionTemplate")
public OptionalSqlSessionTemplate gunsSqlSessionTemplate(@Qualifier("sqlSessionFactoryPrimary") SqlSessionFactory sqlSessionFactoryPrimary,
SqlSessionFactoryCreator sqlSessionFactoryCreator,
DruidProperties druidProperties) {
//初始化数据源容器
try {
DataSourceContext.initDataSource(druidProperties);
} catch (Exception e) {
throw new DataSourceInitException(DataSourceInitException.ExEnum.INIT_DATA_SOURCE_ERROR);
}
//添加主数据源的SqlSessionFactory
SqlSessionFactoryContext.addSqlSessionFactory(MASTER_DATASOURCE_NAME, sqlSessionFactoryPrimary);
//初始化其他数据源的SqlSessionFactory的容器
SqlSessionFactoryContext.initBaseSqlSessionFactory(sqlSessionFactoryCreator);
return new OptionalSqlSessionTemplate(sqlSessionFactoryPrimary, SqlSessionFactoryContext.getSqlSessionFactorys());
}
}
\ No newline at end of file
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config.web;
package cn.stylefeng.guns.config.web;
import cn.stylefeng.guns.sys.core.beetl.BeetlConfiguration;
import cn.stylefeng.guns.sys.core.properties.BeetlProperties;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.config;
package cn.stylefeng.guns.config.web;
import cn.stylefeng.guns.oauth.core.shiro.matcher.WithOAuthTokenMatcher;
import cn.stylefeng.guns.sys.core.constant.Const;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.config;
package cn.stylefeng.guns.config.web;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
......
package cn.stylefeng.guns.sys.config.web;
package cn.stylefeng.guns.config.web;
import cn.hutool.core.date.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
......
......@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.stylefeng.guns.sys.config.web;
package cn.stylefeng.guns.config.web;
import cn.stylefeng.guns.sys.core.attribute.AttributeSetInteceptor;
import cn.stylefeng.guns.sys.core.constant.Const;
......
......@@ -15,7 +15,7 @@
*/
package cn.stylefeng.guns.modular.demos.controller;
import cn.stylefeng.guns.modular.demos.service.TestMultiDbService;
import cn.stylefeng.guns.modular.demos.service.TranTestService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -29,17 +29,23 @@ import org.springframework.web.bind.annotation.RestController;
* @Date 2018/7/20 23:39
*/
@RestController
@RequestMapping("/multi")
public class TestMultiController extends BaseController {
@RequestMapping("/tran/multi")
public class TestMultiTranController extends BaseController {
@Autowired
private TestMultiDbService testMultiDbService;
private TranTestService testMultiDbService;
@RequestMapping("")
public Object auth() {
@RequestMapping("/success")
public Object testSuccess() {
testMultiDbService.beginTest();
return SuccessResponseData.success();
}
@RequestMapping("/fail")
public Object testFail() {
testMultiDbService.beginTestFail();
return SuccessResponseData.success();
}
}
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <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 cn.stylefeng.guns.modular.demos.controller;
import cn.stylefeng.guns.modular.demos.service.TranTestService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试单数据源回滚
*
* @author stylefeng
* @Date 2018/7/20 23:39
*/
@RestController
@RequestMapping("/tran/single")
public class TestSingleTranController extends BaseController {
@Autowired
private TranTestService testMultiDbService;
@RequestMapping("/success")
public Object testSuccess() {
testMultiDbService.testSingleSuccess();
return SuccessResponseData.success();
}
@RequestMapping("/fail")
public Object testFail() {
testMultiDbService.testSingleFail();
return SuccessResponseData.success();
}
}
......@@ -25,7 +25,7 @@ public class GunsDbService extends ServiceImpl<UserMapper, User> {
@Autowired
private UserService userService;
@DataSource(name = "gunsdb")
@DataSource(name = "master")
public void gunsdb() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
......
......@@ -25,7 +25,7 @@ public class OtherDbService extends ServiceImpl<UserMapper, User> {
@Autowired
private UserService userService;
@DataSource(name = "otherdb")
@DataSource(name = "test")
public void otherdb() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
......
package cn.stylefeng.guns.modular.demos.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 测试多数据源回滚的例子
* </p>
*
* @author stylefeng
* @since 2018-12-07
*/
@Service
public class TestMultiDbService {
@Autowired
private GunsDbService gunsDbService;
@Autowired
private OtherDbService otherDbService;
@Transactional(rollbackFor = Exception.class)
public void beginTest() {
gunsDbService.gunsdb();
otherDbService.otherdb();
// int i = 1 / 0;
}
}
package cn.stylefeng.guns.modular.demos.service;
import cn.hutool.core.util.RandomUtil;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
/**
* <p>
* 测试数据源能否回滚的例子
* </p>
*
* @author stylefeng
* @since 2018-12-07
*/
@Service
public class TranTestService {
@Autowired
private GunsDbService gunsDbService;
@Autowired
private OtherDbService otherDbService;
@Transactional(rollbackFor = Exception.class)
public void testSingleSuccess() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
user.setPassword(RandomUtil.randomString(5));
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
user.setCreateUser(1L);
user.setUpdateUser(1L);
gunsDbService.save(user);
User user2 = new User();
user2.setAccount(RandomUtil.randomString(5));
user2.setPassword(RandomUtil.randomString(5));
user2.setCreateTime(new Date());
user2.setUpdateTime(new Date());
user2.setCreateUser(1L);
user2.setUpdateUser(1L);
gunsDbService.save(user2);
}
@Transactional(rollbackFor = Exception.class)
public void testSingleFail() {
User user = new User();
user.setAccount(RandomUtil.randomString(5));
user.setPassword(RandomUtil.randomString(5));
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
user.setCreateUser(1L);
user.setUpdateUser(1L);
gunsDbService.save(user);
User user2 = new User();
user2.setAccount(RandomUtil.randomString(5));
user2.setPassword(RandomUtil.randomString(5));
user2.setCreateTime(new Date());
user2.setUpdateTime(new Date());
user2.setCreateUser(1L);
user2.setUpdateUser(1L);
gunsDbService.save(user2);
int i = 1 / 0;
}
@Transactional(rollbackFor = Exception.class)
public void beginTest() {
gunsDbService.gunsdb();
otherDbService.otherdb();
}
@Transactional(rollbackFor = Exception.class)
public void beginTestFail() {
gunsDbService.gunsdb();
otherDbService.otherdb();
int i = 1 / 0;
}
}
......@@ -6,7 +6,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
#SQLServer配置
#spring:
......@@ -16,7 +15,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
#PostgreSQL配置
#spring:
......@@ -26,7 +24,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
# Mysql数据库
spring:
......@@ -36,7 +33,6 @@ spring:
username: root
password: root
filters: wall,mergeStat
data-source-name: gunsdb
# 邮件发送配置(改为自己的账号和密码)
mail:
......@@ -45,16 +41,6 @@ spring:
username: sn93@qq.com
password: xxxpassword
# 多数据源情况的配置
guns:
muti-datasource:
open: false
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/guns_test_db?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT
username: root
password: root
data-source-name: otherdb
# 阿里云短信发送配置
aliyun:
sms:
......
......@@ -6,7 +6,6 @@
# username: GUNS
# password: GUNS
# filters: wall,mergeStat
# data-source-name: gunsdb
#SQLServer配置
#spring:
......@@ -16,7 +15,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
#PostgreSQL配置
#spring:
......@@ -26,7 +24,6 @@
# username: root
# password: root
# filters: wall,mergeStat
# data-source-name: gunsdb
# Mysql数据库
spring:
......@@ -36,7 +33,6 @@ spring:
username: root
password: root
filters: wall,mergeStat
data-source-name: gunsdb
# 邮件发送配置(改为自己的账号和密码)
mail:
......@@ -45,16 +41,6 @@ spring:
username: sn93@qq.com
password: xxxpassword
# 多数据源情况的配置
guns:
muti-datasource:
open: false
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/guns_test_db?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=CTT
username: root
password: root
data-source-name: otherdb
# 阿里云短信发送配置
aliyun:
sms:
......
com.atomikos.icatch.max_actives=-1
\ No newline at end of file
......@@ -17,7 +17,7 @@ layui.use(['table', 'admin', 'ax'], function () {
EgForm.initColumn = function () {
return [[
{type: 'checkbox'},
{field: 'formId', hide: true, title: '主键id'},
{field: 'formId', align: "center", hide: true, title: '主键id'},
{field: 'name', align: "center", sort: true, title: '名称'},
{field: 'singleTime', align: "center", sort: true, title: '单个时间', minWidth: 160},
{field: 'betweenTime', align: "center", sort: true, title: '时间段', minWidth: 187},
......
......@@ -21,6 +21,7 @@
<modules>
<module>guns-base</module>
<module>guns-base-db-container</module>
<module>guns-base-sms</module>
<module>guns-base-email</module>
<module>guns-base-timers</module>
......@@ -63,7 +64,7 @@
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-core</artifactId>
<version>1.2.2</version>
<version>1.2.4</version>
</dependency>
<!--数据库驱动,可根据自己需要自行删减-->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment