yun-zuoyi
nies 3 years ago
commit 261d494d24

@ -0,0 +1,85 @@
package cn.estsh.i3plus.core.api.iservice.base;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.platform.bean.CoreDataSource;
import io.swagger.annotations.ApiOperation;
import java.util.List;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 10:38
* @Modify:
**/
public interface ICoreDataSourceService {
/**
*
*
* @param dataObject
* @return
*/
@ApiOperation(value = "修改数据对象接口")
CoreDataSource updateDataObject(CoreDataSource dataObject);
/**
*
*
* @param source
* @return
*/
@ApiOperation(value = "保存数据对象属性接口")
CoreDataSource saveDataSource(CoreDataSource source);
/**
*
*
* @param id ID
* @return
*/
@ApiOperation(value = "获取数据对象信息")
CoreDataSource getCoreDatasourceObject(Long id);
/**
*
*
* @param source
*/
@ApiOperation(value = "数据源唯一检查")
void checkBfDataSourceOnly(CoreDataSource source);
/**
*
*
* @param pager
* @return
*/
@ApiOperation(value = "查询所有数据对象接口")
ListPager<CoreDataSource> queryDataObjectByPager(CoreDataSource coreDataSource, Pager pager);
/**
*
*
* @return
*/
@ApiOperation(value = "获取所有数据源对象")
List<CoreDataSource> listAll();
/**
*
* @param id
*/
void delete(Long id);
/**
* datasourcecodeid
* @return
*/
List<CoreDataSource> list();
}

@ -14,6 +14,10 @@
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- 微服调用 -->
<dependency>
<groupId>i3plus.icloud</groupId>

@ -0,0 +1,141 @@
package cn.estsh.i3plus.core.apiservice.configuration;
import cn.estsh.i3plus.pojo.wms.bean.datasource.CusDatasource;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import java.sql.*;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 11:43
* @Modify:
**/
@Slf4j
@Data
public class CoreJdbcTemplate {
private CusDatasource source;
private NamedParameterJdbcTemplate coreJdbcTemplate;
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
return coreJdbcTemplate;
}
/**
*
*
* @return
*/
public Connection getJdbcTempConnection() {
Connection conn;
try {
conn = coreJdbcTemplate.getJdbcTemplate().getDataSource().getConnection();
} catch (SQLException e) {
log.error("wmsJdbcTemplate获取数据源连接失败:{}", e.getMessage());
throw ImppExceptionBuilder.newInstance().setErrorDetail("wmsJdbcTemplate获取数据源连接失败:" + e.getMessage()).build();
}
return conn;
}
/**
* 使
*
* @param conn
*/
public void beginTransaction(Connection conn) {
try {
if (conn != null) {
conn.setAutoCommit(false);
}
} catch (SQLException e) {
log.error("【开启事务connection】开启事务异常Error Message:{}", e.getMessage());
throw ImppExceptionBuilder.newInstance().setErrorDetail("【开启事务connection】开启事务异常Error Message:" + e.getMessage()).build();
}
}
/**
*
*
* @param conn
*/
public void commit(Connection conn) {
try {
if (conn != null) {
conn.commit();
}
} catch (SQLException e) {
log.error("【提交事务connection】提交事务异常Error Message:{}", e.getMessage());
throw ImppExceptionBuilder.newInstance().setErrorDetail("【开启事务connection】开启事务异常Error Message:" + e.getMessage()).build();
}
}
/**
*
*
* @param conn
* @param pstmt
* @param stmt
* @param resultSet
*/
public static void clean(Connection conn, PreparedStatement pstmt, Statement stmt, ResultSet resultSet) {
try {
if (resultSet != null && !resultSet.isClosed()) {
resultSet.close();
}
} catch (SQLException e) {
log.error("【数据库连接 Connection】 关闭连接异常 Error Message:{}", e.getMessage());
}
try {
if (stmt != null && !stmt.isClosed()) {
stmt.close();
}
} catch (SQLException e) {
log.error("【数据库连接 Connection】 关闭连接异常 Error Message:{}", e.getMessage());
}
try {
if (pstmt != null && !pstmt.isClosed()) {
pstmt.close();
}
} catch (SQLException e) {
log.error("【数据库连接 Connection】 关闭连接异常 Error Message:{}", e.getMessage());
}
try {
if (conn != null && !conn.isClosed()) {
log.info("【数据库连接 Connection】 关闭连接");
conn.close();
}
} catch (SQLException e) {
log.error("【数据库连接 Connection】 关闭连接异常 Error Message:{}", e.getMessage());
}
}
/**
* isRead or Transaction
* @param isRead
* @return
* @throws SQLException
*/
public Connection getJdbcTempConnection(boolean isRead) throws SQLException {
Connection conn;
if(isRead){
log.info("【数据库】 事物提示ReadOnly ");
conn = coreJdbcTemplate.getJdbcTemplate().getDataSource().getConnection();
conn.setReadOnly(true);
log.info("【表单数据源切换,只读:{}】", conn);
}else{
log.info("【数据库】 事物提示beginTransaction ");
conn = coreJdbcTemplate.getJdbcTemplate().getDataSource().getConnection();
//开启事务
beginTransaction(conn);
log.info("【表单数据源切换,只写:{}】", conn);
}
return conn;
}
}

@ -0,0 +1,207 @@
package cn.estsh.i3plus.core.apiservice.configuration;
import cn.estsh.i3plus.core.api.iservice.base.ICoreDataSourceService;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.CoreDataSource;
import cn.estsh.i3plus.pojo.wms.bean.datasource.CusDatasource;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 11:41
* @Modify:
**/
@Component
@Slf4j
public class CoreJdbcTemplateConfig {
public static final String IOC_CORE_DATASOURCE_PREFIX = "CORE_DATA_SOURCE_";
public static final String CORE_CACHE_POOL_PREFIX = "CORE_DATA_SOURCE:";
/**
*
*/
private static final Integer MININUM_IDLE = 10;
/**
*
*/
private static final Integer MAXIMUN_POOL_SIZE = 100;
/**
* max-lifetime
*/
private static final Integer MAX_LIFT_TIME = 200000;
/**
* borrow-connection
*/
private static final Integer BORROW_CONNECTION_TIMEOUT = 10000;
/**
*
*/
private static final Integer MAX_IDLE_TIME = 10000;
private static final ConcurrentHashMap<Long, CoreDataSource> CACHE_SOURCE_MAP = new ConcurrentHashMap<>();
@Autowired
private AnnotationConfigServletWebServerApplicationContext context;
@Resource(name = CommonConstWords.IMPP_REDIS_WMS)
private ImppRedis redis;
@Autowired
private ICoreDataSourceService datasourceService;
public void setSpringIocJdbcTemplate(CoreDataSource coreDatasource) {
try {
if (CACHE_SOURCE_MAP.containsKey(coreDatasource.getId())) {
log.info("remove the older coreDataSource:{}", coreDatasource);
removeJdbcTemplateBean(coreDatasource);
}
} catch (Exception e) {
log.error("Error occurred when removing the older cusDataSource", e);
}
log.info("Spring Ioc Init CusDatasource to Ioc:{}", coreDatasource);
NamedParameterJdbcTemplate namedParameterJdbcTemplate = getNamedParameterJdbcTemplate(coreDatasource);
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CoreJdbcTemplate.class);
beanDefinitionBuilder.addPropertyValue("source", coreDatasource);
beanDefinitionBuilder.addPropertyValue("wmsJdbcTemplate", namedParameterJdbcTemplate);
//存入redis
redis.putObject(CORE_CACHE_POOL_PREFIX + coreDatasource.getId(), coreDatasource);
//手动注册bean
context.getDefaultListableBeanFactory().registerBeanDefinition(IOC_CORE_DATASOURCE_PREFIX + coreDatasource.getId(), beanDefinitionBuilder.getBeanDefinition());
CACHE_SOURCE_MAP.put(coreDatasource.getId(), coreDatasource);
log.info(" Spring IOC Init Bean WMSJdbcTemplate.class Successful key:{}", IOC_CORE_DATASOURCE_PREFIX + coreDatasource.getId());
}
/**
* wmsredis
*
* @param key
* @return
*/
public CoreJdbcTemplate getCoreJdbcTemplate(Long key) {
try {
CoreDataSource cacheDatasource = (CoreDataSource) redis.getObject(CORE_CACHE_POOL_PREFIX + key);
if (Objects.isNull(cacheDatasource)) {
return (CoreJdbcTemplate) context.getBean(IOC_CORE_DATASOURCE_PREFIX + key);
}
CoreDataSource coreDatasource = datasourceService.getCoreDatasourceObject(key);
if (!cacheDatasource.equals(coreDatasource)) {
resetJdbcTemplateBean(coreDatasource);
}
return (CoreJdbcTemplate) context.getBean(IOC_CORE_DATASOURCE_PREFIX + key);
} catch (BeansException e) {
throw ImppExceptionBuilder.newInstance()
.setSystemID(CommonEnumUtil.SOFT_TYPE.WMS.getCode())
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
.setErrorDetail("【数据源】数据库 [" + key + "]数据源不在系统控制当中")
.setErrorSolution("请检查数据源配置信息")
.build();
}
}
/**
* bean
*
* @param coreDatasource
*/
public void removeJdbcTemplateBean(CoreDataSource coreDatasource) {
Object bean;
try {
bean = context.getBean(IOC_CORE_DATASOURCE_PREFIX + coreDatasource.getId());
} catch (BeansException e) {
log.error("无法获取到该数据源的Bean {}", coreDatasource.getId());
throw ImppExceptionBuilder.newInstance()
.setErrorCode(ImppExceptionEnum.SYSTEM_EXCEPTION.getCode())
.setErrorDetail("无法获取该数据源的bean").build();
}
//关闭连接池
((HikariDataSource) ((CoreJdbcTemplate) bean).getNamedParameterJdbcTemplate().getJdbcTemplate().getDataSource()).close();
//销毁bean
context.getDefaultListableBeanFactory().removeBeanDefinition(IOC_CORE_DATASOURCE_PREFIX + coreDatasource.getId());
redis.deleteKey(CORE_CACHE_POOL_PREFIX + coreDatasource.getId());
}
/**
* NamedParameterJdbcTemplate
*
* @param cusDataSource
* @return
*/
private NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(CoreDataSource cusDataSource) {
log.info("【数据源】创建数据源cusDatasource{}", cusDataSource);
CommonEnumUtil.DATA_SOURCE_TYPE type = CommonEnumUtil.DATA_SOURCE_TYPE.valueOf(cusDataSource.getSourceType());
DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.type(HikariDataSource.class);
dataSourceBuilder.driverClassName(type.getDriverClassName());
dataSourceBuilder.url(type.getJDBCUrl(cusDataSource.getSourceDataBaseName(), cusDataSource.getSourceHost(), cusDataSource.getSourcePort()));
dataSourceBuilder.username(cusDataSource.getSourceUserName());
dataSourceBuilder.password(cusDataSource.getSourcePassword());
HikariDataSource dataSource = (HikariDataSource) dataSourceBuilder.build();
//连接池大小
dataSource.setMaximumPoolSize(MAXIMUN_POOL_SIZE);
dataSource.setMinimumIdle(MININUM_IDLE);
return new NamedParameterJdbcTemplate(dataSource);
}
/**
*
*
* @param coreDataSource
* @return
*/
public boolean checkConnection(CoreDataSource coreDataSource) {
NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate(coreDataSource);
try {
Connection connection = Objects.requireNonNull(template.getJdbcTemplate().getDataSource()).getConnection();
boolean isConn = connection != null;
if (isConn) {
if (!connection.isClosed()) {
connection.close();
}
}
setSpringIocJdbcTemplate(coreDataSource);
return isConn;
} catch (SQLException e) {
log.error("【数据源】 数据源连接检查失败 Error Message:{}", e.getMessage());
}
return false;
}
private void resetJdbcTemplateBean(CoreDataSource coreDataSource) {
removeJdbcTemplateBean(coreDataSource);
setSpringIocJdbcTemplate(coreDataSource);
}
}

@ -0,0 +1,176 @@
package cn.estsh.i3plus.core.apiservice.controller.base;
import cn.estsh.i3plus.core.api.iservice.base.ICoreDataSourceService;
import cn.estsh.i3plus.core.apiservice.configuration.CoreJdbcTemplateConfig;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.util.PlatformConstWords;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.WmsEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.CoreDataSource;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.LocaleUtils;
import cn.estsh.impp.framework.boot.util.ResultBean;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 10:37
* @Modify:
**/
@Api(value = "冷热数据分离数据源管理", tags = "冷热数据分离数据源管理")
@RestController
@RequestMapping(PlatformConstWords.BASE_URL + "/datasource")
public class DataSourceController {
@Autowired
private ICoreDataSourceService datasourceService;
@Autowired
private CoreJdbcTemplateConfig jdbcTemplateConfig;
/**
*
*
* @return
*/
@PostMapping("/add")
@ApiOperation(value = "添加数据源", notes = "添加数据源")
public ResultBean addDataSource(@RequestBody CoreDataSource coreDatasource) {
try {
ValidatorBean.beginValid(coreDatasource)
.numberCheck("sourcePort", coreDatasource.getSourcePort())
.notNull("sourceCode", coreDatasource.getSourceCode())
.notNull("sourceName", coreDatasource.getSourceName())
.notNull("sourceHost", coreDatasource.getSourceHost())
.notNull("sourceUserName", coreDatasource.getSourceUserName())
.notNull("sourcePassword", coreDatasource.getSourcePassword())
.notNull("sourceDataBaseName", coreDatasource.getSourceDataBaseName());
ConvertBean.modelInitialize(coreDatasource, AuthUtil.getSessionUser());
datasourceService.checkBfDataSourceOnly(coreDatasource);
coreDatasource = datasourceService.saveDataSource(coreDatasource);
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultObject(coreDatasource);
} catch (ImppBusiException exception) {
return ResultBean.fail(exception).build();
} catch (Exception e) {
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
}
}
/**
*
*
* @return
*/
@DeleteMapping("/delete/{id}")
@ApiOperation(value = "删除数据源", notes = "删除数据源")
public ResultBean deleteDataSource(@PathVariable("id") Long id) {
try {
ValidatorBean.checkNotNull(id, "数据对象id不能为空");
datasourceService.delete(id);
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
} catch (ImppBusiException exception) {
return ResultBean.fail(exception).build();
} catch (Exception e) {
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
}
}
/**
*
*
* @return
*/
@PutMapping("/update")
@ApiOperation(value = "修改数据源", notes = "修改数据源")
public ResultBean updateDataSource(@RequestBody CoreDataSource coreDataSource) {
try {
ValidatorBean.beginValid(coreDataSource)
.notNull("id", coreDataSource.getId())
.notNull("sourceName", coreDataSource.getSourceName());
ConvertBean.modelUpdate(coreDataSource, AuthUtil.getSessionUser());
datasourceService.updateDataObject(coreDataSource);
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
} catch (ImppBusiException busExcep) {
return ResultBean.fail(busExcep);
} catch (Exception e) {
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
}
}
/**
*
*
* @return
*/
@PostMapping("/query")
@ApiOperation(value = "查询数据源", notes = "查询数据源")
public ResultBean list(CoreDataSource cusDatasource, Pager pager) {
try {
ListPager<CoreDataSource> listPager = datasourceService.queryDataObjectByPager(cusDatasource, pager);
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setListPager(listPager);
} catch (ImppBusiException busExcep) {
return ResultBean.fail(busExcep);
} catch (Exception e) {
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
}
}
@PutMapping("/connection/{id}")
@ApiOperation(value = "数据源链接", notes = "数据源连接测试")
public ResultBean connectionDataSource(@PathVariable("id") Long id) {
try {
ValidatorBean.checkNotNull(id, "数据对象id不能为空");
CoreDataSource datasource = datasourceService.getCoreDatasourceObject(id);
ValidatorBean.checkNotNull(datasource, "不存在的数据源信息");
boolean isConn = jdbcTemplateConfig.checkConnection(datasource);
if (isConn) {
if (WmsEnumUtil.DATA_SOURCE_STATUS.CONN_SUCCESS.getValue() != datasource.getSourceStatus()) {
datasource.setSourceStatus(WmsEnumUtil.DATA_SOURCE_STATUS.CONN_SUCCESS.getValue());
datasourceService.updateDataObject(datasource);
}
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setMsg("连接成功");
}
return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode()).setMsg("连接失败");
} catch (ImppBusiException busiException) {
return ResultBean.fail(busiException);
} catch (Exception e) {
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
}
}
@GetMapping("/list")
@ApiOperation(value = "获取所有数据源的code和id", notes = "获取所有数据源的code和id")
public ResultBean listAll() {
try {
List<CoreDataSource> list = datasourceService.list();
return ResultBean.success().setResultList(list);
} catch (Exception e) {
return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
}
}
@GetMapping("/data-source-type")
@ApiOperation(value = "数据源类型", notes = "数据源类型")
public ResultBean getDataSourceType() {
return new ResultBean(true, "操作成功",
LocaleUtils.getEnumLocaleResValuesToList(CommonEnumUtil.DATA_SOURCE_TYPE.values()));
}
}

@ -0,0 +1,21 @@
package cn.estsh.i3plus.core.apiservice.dao;
import cn.estsh.i3plus.pojo.platform.bean.CoreDataSource;
import java.util.List;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 13:36
* @Modify:
**/
public interface ICoreDataSourceDao {
/**
*
* @return
*/
List<CoreDataSource> listAllIdAndSourceName();
}

@ -0,0 +1,36 @@
package cn.estsh.i3plus.core.apiservice.daoimpl;
import cn.estsh.i3plus.core.apiservice.dao.ICoreDataSourceDao;
import cn.estsh.i3plus.core.apiservice.util.PlatformEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.WmsEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.CoreDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 13:38
* @Modify:
**/
@Component
public class CoreDataSourceDao implements ICoreDataSourceDao {
@Autowired
private EntityManager entityManager;
@Override
public List<CoreDataSource> listAllIdAndSourceName() {
String hql = "select new CusDatasource(id,sourceName) from CoreDatasource where isDeleted = :is_deleted and isValid = :is_valid and sourceStatus = :sourceStatus";
Query query = entityManager.createQuery(hql);
query.setParameter("is_deleted", CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
query.setParameter("is_valid", CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
query.setParameter("sourceStatus", PlatformEnumUtil.DATA_SOURCE_STATUS.CONN_SUCCESS.getValue());
return query.getResultList();
}
}

@ -0,0 +1,128 @@
package cn.estsh.i3plus.core.apiservice.serviceimpl.base;
import cn.estsh.i3plus.core.api.iservice.base.ICoreDataSourceService;
import cn.estsh.i3plus.core.apiservice.configuration.CoreJdbcTemplateConfig;
import cn.estsh.i3plus.core.apiservice.util.PlatformEnumUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.WmsEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.platform.bean.CoreDataSource;
import cn.estsh.i3plus.pojo.platform.repository.CoreDataSourceRepository;
import cn.estsh.i3plus.pojo.wms.bean.datasource.CusDatasource;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 11:12
* @Modify:
**/
@Service
public class CoreDataSourceServiceImpl implements ICoreDataSourceService{
@Autowired
private CoreDataSourceRepository coreDataSourceRepository;
@Autowired
private CoreJdbcTemplateConfig jdbcConfig;
@Override
public CoreDataSource updateDataObject(CoreDataSource dataObject) {
coreDataSourceRepository.update(dataObject);
return dataObject;
}
@Override
public CoreDataSource saveDataSource(CoreDataSource source) {
ConvertBean.saveOrUpdate(source, AuthUtil.getSessionUser().getUserName());
coreDataSourceRepository.insert(source);
if (jdbcConfig.checkConnection(source)) {
source.setSourceStatus(PlatformEnumUtil.DATA_SOURCE_STATUS.CONN_SUCCESS.getValue());
} else {
source.setSourceStatus(PlatformEnumUtil.DATA_SOURCE_STATUS.CONN_FAILURE.getValue());
}
coreDataSourceRepository.update(source);
return source;
}
@Override
public CoreDataSource getCoreDatasourceObject(Long id) {
return coreDataSourceRepository.getById(id);
}
@Override
public void checkBfDataSourceOnly(CoreDataSource source) {
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean();
DdlPreparedPack.getStringEqualPack(source.getSourceCode(), "sourceCode", ddlPackBean);
int count = coreDataSourceRepository.findByHqlWhereCount(ddlPackBean);
if (count > 0) {
throw ImppExceptionBuilder.newInstance()
.setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
.setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
.setErrorDetail("【唯一校验】数据源编码重复")
.setErrorSolution("请重新输入数据源编码")
.build();
}
}
@Override
public ListPager<CoreDataSource> queryDataObjectByPager(CoreDataSource coreDataSource, Pager pager) {
if (coreDataSource == null) {
pager = PagerHelper.getPager(pager, coreDataSourceRepository.listCount());
return new ListPager(coreDataSourceRepository.listPager(pager), pager);
} else {
DdlPackBean hqlPack = DdlPackBean.getDdlPackBean();
if (coreDataSource.getSourceCode() != null) {
DdlPreparedPack.getStringLeftLikerPack(coreDataSource.getSourceCode(), "sourceCode", hqlPack);
}
if (coreDataSource.getSourceType() != null) {
DdlPreparedPack.getNumEqualPack(coreDataSource.getSourceType(), "sourceType", hqlPack);
}
if (coreDataSource.getSourceStatus() != null) {
DdlPreparedPack.getNumEqualPack(coreDataSource.getSourceStatus(), "sourceStatus", hqlPack);
}
if (coreDataSource.getSourceDataBaseName() != null) {
DdlPreparedPack.getStringLeftLikerPack(coreDataSource.getSourceDataBaseName(), "sourceDataBaseName", hqlPack);
}
if (coreDataSource.getSourceHost() != null) {
DdlPreparedPack.getStringLeftLikerPack(coreDataSource.getSourceHost(), "sourceHost", hqlPack);
}
if (coreDataSource.getSourceName() != null) {
DdlPreparedPack.getStringLeftLikerPack(coreDataSource.getSourceName(), "sourceName", hqlPack);
}
pager = PagerHelper.getPager(pager, coreDataSourceRepository.findByHqlWhereCount(hqlPack));
return new ListPager(coreDataSourceRepository.findByHqlWherePage(hqlPack, pager), pager);
}
}
@Override
public List<CoreDataSource> listAll() {
return coreDataSourceRepository.list();
}
@Override
public void delete(Long id) {
CoreDataSource coreDatasource = coreDataSourceRepository.getById(id);
coreDataSourceRepository.deleteWeaklyById(id, AuthUtil.getSessionUser().getUserName());
jdbcConfig.removeJdbcTemplateBean(coreDatasource);
}
@Override
public List<CoreDataSource> list() {
return null;
}
}

@ -1,28 +1,37 @@
package cn.estsh.i3plus.core.apiservice.serviceimpl.base;
import cn.estsh.i3plus.core.api.iservice.base.IDataSeparatorService;
import cn.estsh.i3plus.core.apiservice.util.strategy.IDataSeparatorStrategy;
import cn.estsh.i3plus.core.apiservice.configuration.CoreJdbcTemplate;
import cn.estsh.i3plus.core.apiservice.configuration.CoreJdbcTemplateConfig;
import cn.estsh.i3plus.core.apiservice.util.SeparatorDataUtil;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil;
import cn.estsh.i3plus.pojo.base.jpa.dao.BaseRepository;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.platform.bean.DataSeparatorMessage;
import cn.estsh.i3plus.pojo.platform.bean.DataSeparatorRule;
import cn.estsh.i3plus.pojo.platform.repository.DataSeparatorRepository;
import cn.estsh.i3plus.pojo.platform.sqlpack.CoreHqlPack;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.visitor.ExportParameterizedOutputVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description :
@ -40,16 +49,26 @@ public class DataSeparatorServiceImpl implements IDataSeparatorService {
@Resource
private DataSeparatorRepository dataSeparatorRepository;
@Resource
private CoreJdbcTemplateConfig coreJdbcTemplateConfig;
@Autowired
private SeparatorDataUtil separatorDataUtil;
@Override
public void doSeparate(BaseRepository baseRepository, DataSeparatorMessage msg) {
//获取数据
Long id = msg.getId();
Object bean = baseRepository.getById(id);
//获取策略
String strategy = ImppEnumUtil.DATA_SEPARATOR_STRATEGY.codeOfStrategyName(msg.getClassification());
IDataSeparatorStrategy separator = (IDataSeparatorStrategy) SpringContextsUtil.getBean(strategy);
//获取目的地的数据源
CoreJdbcTemplate coreJdbcTemplate = coreJdbcTemplateConfig.getCoreJdbcTemplate(msg.getDestDataSourceId());
//迁移数据
separator.execute(bean, msg);
try {
execute(bean, msg,coreJdbcTemplate);
} catch (Exception e) {
throw ImppExceptionBuilder.newInstance().setErrorDetail(e.getMessage()+":separate data failed").build();
}
//删除原数据
baseRepository.deleteById(id);
}
@ -84,18 +103,11 @@ public class DataSeparatorServiceImpl implements IDataSeparatorService {
@Override
public ListPager<DataSeparatorRule> query(DataSeparatorRule rule, Pager pager) {
DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(rule.getOrganizeCode());
if (Strings.isNullOrEmpty(rule.getClassification())) {
DdlPreparedPack.getStringEqualPack(rule.getClassification(), "classification", ddlPackBean);
}
if (Strings.isNullOrEmpty(rule.getRefBeanName())) {
DdlPreparedPack.getStringLeftLikerPack(rule.getRefBeanName(), "refBeanName", ddlPackBean);
}
if (Strings.isNullOrEmpty(rule.getDatabaseName())) {
DdlPreparedPack.getStringLeftLikerPack(rule.getDatabaseName(), "databaseName", ddlPackBean);
}
if (Strings.isNullOrEmpty(rule.getRuleColumn())) {
DdlPreparedPack.getStringLeftLikerPack(rule.getRuleColumn(), "ruleColumn", ddlPackBean);
}
@ -114,4 +126,56 @@ public class DataSeparatorServiceImpl implements IDataSeparatorService {
redisRes.putObject(redisKey, item, -1);
});
}
private void execute(Object bean,DataSeparatorMessage msg,CoreJdbcTemplate coreJdbcTemplate) throws Exception {
String insertSql = separatorDataUtil.packSql(bean, msg.getDestTableName());
NamedParameterJdbcTemplate jdbcTemplate = coreJdbcTemplate.getNamedParameterJdbcTemplate();
boolean isSqlServer = isMSSQLSERVER(jdbcTemplate);
DbType dbType;
if (isSqlServer) {
dbType = JdbcConstants.SQL_SERVER;
} else {
dbType = JdbcConstants.MYSQL;
}
Map<String, Object> resultMap = parseSQL(insertSql, dbType);
String preparedSql = resultMap.get("preparedSql").toString();
@SuppressWarnings("unchecked")
List<Object> parameters = (List<Object>) resultMap.get("parameters");
jdbcTemplate.getJdbcTemplate().update(preparedSql,parameters.toArray());
}
/**
* sqlsql
*
* @param sql
* @param dbType
* @return
*/
private Map<String, Object> parseSQL(String sql, DbType dbType) {
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, dbType);
ExportParameterizedOutputVisitor visitor = new ExportParameterizedOutputVisitor();
for (SQLStatement statement : sqlStatements) {
statement.accept(visitor);
}
String preparedSql = visitor.getAppender().toString();
List<Object> parameters = visitor.getParameters();
HashMap<String, Object> resultMap = new HashMap<>();
resultMap.put("preparedSql", preparedSql);
resultMap.put("parameters", parameters);
return resultMap;
}
/**
* MSSQLSERVER
*
* @return
* @throws Exception
*/
private boolean isMSSQLSERVER(NamedParameterJdbcTemplate srcJdbcTemplate) throws Exception {
return srcJdbcTemplate.getJdbcTemplate().getDataSource().getConnection().getMetaData().getURL().contains("sqlserver");
}
}

@ -1,103 +0,0 @@
package cn.estsh.i3plus.core.apiservice.serviceimpl.base;
import cn.estsh.i3plus.core.apiservice.util.strategy.IDataSeparatorStrategy;
import cn.estsh.i3plus.platform.plugin.datasource.DynamicDataSourceProxy;
import cn.estsh.i3plus.pojo.platform.bean.DataSeparatorMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.persistence.Column;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2021/12/3 14:02
* @Modify:
**/
@Component
@Slf4j
public class DataSeparatorStrategyMysql implements IDataSeparatorStrategy {
/**
* url+key
*/
public static final Map<String, DynamicDataSourceProxy> DYNAMIC_DATA_SOURCE_PROXY_MAP = new HashMap<>();
@Override
public void execute(Object bean, DataSeparatorMessage msg) {
//获取动态数据源
DynamicDataSourceProxy dynamicDataSource = getDynamicDataSource(msg);
//封装Map<columnName,value>
HashMap<String, Object> objMap = getObjMap(bean);
//执行sql
String insertSQL = dynamicDataSource.packInsertSQL(msg.getDestTableName(), objMap);
try {
dynamicDataSource.execute(insertSQL);
} catch (SQLException e) {
log.error("执行sql:{}失败,失败原因:{}", insertSQL, e.getMessage());
}
}
/**
*
*
* @param msg
* @return
*/
private DynamicDataSourceProxy getDynamicDataSource(DataSeparatorMessage msg) {
DynamicDataSourceProxy dataSourceProxy;
String destUrl = msg.getDestUrl();
String dataBaseName = msg.getDatabaseName();
String mapKey = destUrl + ":" + dataBaseName;
if (!DYNAMIC_DATA_SOURCE_PROXY_MAP.containsKey(mapKey)) {
String url = "jdbc:mysql://" + destUrl + "/" + dataBaseName + "?autoReconnect=true&useSSL=false&characterEncoding=utf-8";
dataSourceProxy = DynamicDataSourceProxy.initDataSourceFactory("com.mysql.jdbc.Driver",url,msg.getUserName(),msg.getPassword());
DYNAMIC_DATA_SOURCE_PROXY_MAP.put(mapKey, dataSourceProxy);
}
dataSourceProxy = DYNAMIC_DATA_SOURCE_PROXY_MAP.get(mapKey);
return dataSourceProxy;
}
/**
* k-v
*
* @param bean
* @return
*/
private HashMap<String, Object> getObjMap(Object bean) {
Field[] declaredFields = bean.getClass().getDeclaredFields();
Field[] parentFields = bean.getClass().getSuperclass().getDeclaredFields();
HashMap<String, Object> objMap = new HashMap<>(declaredFields.length);
List<Field[]> list = new ArrayList<>();
list.add(declaredFields);
list.add(parentFields);
list.forEach(item -> {
for (Field field : item) {
field.setAccessible(true);
if (null != field.getAnnotation(Column.class)) {
Column annotation = field.getAnnotation(Column.class);
String columnName = annotation.name();
try {
Object value = field.get(bean);
objMap.put(columnName, value);
} catch (IllegalAccessException e) {
log.error("冷热分离Mysql封装数据错误:{}!", columnName);
}
}
}
});
return objMap;
}
}

@ -0,0 +1,91 @@
package cn.estsh.i3plus.core.apiservice.util;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 13:14
* @Modify:
**/
public class PlatformEnumUtil {
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum DATA_SOURCE_STATUS {
CONN_SUCCESS(10, "连接成功", "连接成功"),
CONN_FAILURE(20, "连接失败", "连接失败");
private int value;
private String code;
private String description;
private DATA_SOURCE_STATUS(int value, String code, String description) {
this.value = value;
this.code = code;
this.description = description;
}
public int getValue() {
return value;
}
public String getCode() {
return code;
}
public String getDescription() {
return description;
}
public static String valueOfCode(int val) {
String tmp = null;
for (int i = 0; i < values().length; i++) {
if (values()[i].value == val) {
tmp = values()[i].code;
}
}
return tmp;
}
public static int codeOfValue(String code) {
int tmp = 1;
for (int i = 0; i < values().length; i++) {
if (values()[i].code.equals(code)) {
tmp = values()[i].value;
}
}
return tmp;
}
public static String valueOfDescription(int val) {
String tmp = null;
for (int i = 0; i < values().length; i++) {
if (values()[i].value == val) {
tmp = values()[i].description;
}
}
return tmp;
}
public static DATA_SOURCE_STATUS valueOf(int val) {
String tmp = null;
for (int i = 0; i < values().length; i++) {
if (values()[i].value == val) {
return values()[i];
}
}
return null;
}
public static String codeOfDescription(String code) {
String tmp = null;
for (int i = 0; i < values().length; i++) {
if (values()[i].code.equals(code)) {
tmp = values()[i].description;
}
}
return tmp;
}
}
}

@ -0,0 +1,70 @@
package cn.estsh.i3plus.core.apiservice.util;
import cn.estsh.i3plus.platform.plugin.sqltool.IBaseSqlService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.persistence.Column;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2022/1/7 14:19
* @Modify:
**/
@Component
@Slf4j
public class SeparatorDataUtil {
@Autowired
private IBaseSqlService baseSqlService;
/**
* sql
*
* @param bean
* @param destTableName
* @return
*/
public String packSql(Object bean, String destTableName) {
HashMap<String, Object> objMap = getObjMap(bean);
String insertSQL = baseSqlService.packInsertSQL(destTableName, objMap);
return insertSQL;
}
/**
* k-v
*
* @param bean
* @return
*/
private HashMap<String, Object> getObjMap(Object bean) {
Field[] declaredFields = bean.getClass().getDeclaredFields();
Field[] parentFields = bean.getClass().getSuperclass().getDeclaredFields();
HashMap<String, Object> objMap = new HashMap<>(declaredFields.length);
List<Field[]> list = new ArrayList<>();
list.add(declaredFields);
list.add(parentFields);
list.forEach(item -> {
for (Field field : item) {
field.setAccessible(true);
if (null != field.getAnnotation(Column.class)) {
Column annotation = field.getAnnotation(Column.class);
String columnName = annotation.name();
try {
Object value = field.get(bean);
objMap.put(columnName, value);
} catch (IllegalAccessException e) {
log.error("冷热分离Mysql封装数据错误:{}!", columnName);
}
}
}
});
return objMap;
}
}

@ -1,20 +0,0 @@
package cn.estsh.i3plus.core.apiservice.util.strategy;
import cn.estsh.i3plus.pojo.platform.bean.DataSeparatorMessage;
/**
* @Description :
* @Reference :
* @Author : Castle
* @CreateDate : 2021/12/3 13:59
* @Modify:
**/
public interface IDataSeparatorStrategy {
/**
*
* @param bean
* @param msg
*/
void execute(Object bean, DataSeparatorMessage msg);
}

@ -46,6 +46,11 @@
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- impp framework -->
<dependency>
<groupId>impp.framework</groupId>

Loading…
Cancel
Save