最简单可配置的多数据源dataSource

编程入门 行业动态 更新时间:2024-10-18 14:22:29

<a href=https://www.elefans.com/category/jswz/34/1769011.html style=最简单可配置的多数据源dataSource"/>

最简单可配置的多数据源dataSource

场景

公司需要从数量不定,类型可能不同的第三方数据库读取数据。

需求

数据库信息需要动态配置(如从数据库读取),需要动态设置DataSource,且考虑到线程安全。

所以写死的多数据源满足不了。

下面代码已满足基本要求,便捷性自行扩展。

解释:ComRecord  它是个自定义的map。

数据源代码:

package com.tyl.localhis.dao;import com.tylm.basic.ComRecord;
import com.tylm.util.StringUtils;
import com.tyl.localhis.dao.dto.ProcedureDto;
import com.tyl.localhis.entity.config.SyncConfigDb;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.stereotype.Service;import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/**
* @description 通用访问数据库类,该类可实现动态多数据源,且线程安全
* @author tangyaliang* @time 2021/12/11 22:56
*/
@Service
public class ComDao {private final ThreadLocal<MyJdbcTemplate> local = new ThreadLocal<>();private final Map<String, HikariDataSource> map = new HashMap<>();private final MyJdbcTemplate template = new MyJdbcTemplate();/*** 没有默认数据源*/public ComDao(){}/*** 支持配置默认数据源,一般用不上* @param dataSource 默认数据源*/public ComDao(DataSource dataSource){template.setDataSource(dataSource);local.set(template);}/*** @param config 数据库链接配置,db_id,db_url,db_name,db_pwd* @description 根据不同数据库用户名切换DataSource* @author tangyaliang  线程安全* @time 2021/12/11 22:56*/public void setDataSource(SyncConfigDb config) {HikariDataSource dataSource = map.get(config.getDbId());if (dataSource == null) {dataSource = new HikariDataSource();//数据库urldataSource.setJdbcUrl(config.getDbUrl());//数据库用户名dataSource.setUsername(config.getDbName());//数据库密码dataSource.setPassword(config.getDbPwd());if (!StringUtils.isEmpry(config.getDbDriverName())) {dataSource.setDriverClassName(config.getDbDriverName());}//DataSource放入map中,等待使用map.put(config.getDbId(), dataSource);}template.setDataSource(dataSource);local.set(template);}/*** 执行sql语句* @param sql sql* @return 结果集*/public List<ComRecord> query(String sql) {return local.get().query(sql, new ComRowMapper(local.get().getDbEnCoding()));}/*** 调用存储过程返回结果集* 目前可以调用oracle游标结果集,mysql结果集,其他微测试* @return 结果集*/public List<ComRecord> queryProcedureByRefcursor(ProcedureDto dto) {//参数名称不区分大小写local.get().setResultsMapCaseInsensitive(true);SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(local.get());//设置储存过程名称simpleJdbcCall.withProcedureName(dto.getProcedurName());//设置存储过程游标或数据集名称,如果参数名称与存储过程中out名称相对应则返回ComRowMapper类型,名称对应不上返回linkdlistsimpleJdbcCall.returningResultSet(dto.getRefcursorName(), new ComRowMapper(local.get().getDbEnCoding()));//.returningResultSet("data", BeanPropertyRowMapper.newInstance(Clazz.class));Clazz.class可以直接转化为实体类型//设置输入参数Map<String, Object> map;if (dto.getInParames() == null || dto.getInParames().size() == 0) {map = simpleJdbcCall.execute(new HashMap<>(0));} else {map = simpleJdbcCall.execute(dto.getInParames());}return (List<ComRecord>) map.get(dto.getRefcursorName());}/*** @description 通用RowMapper,其他地方用不到,所以定义为成员内部类* @author tangyaliang* @time 2021/12/11*/class ComRowMapper implements RowMapper {String charSet;public ComRowMapper(){}public ComRowMapper(String charSet){this.charSet = charSet;}@Overridepublic ComRecord mapRow(ResultSet rs, int rowNum) throws SQLException {ComRecord record = new ComRecord();ResultSetMetaData red = rs.getMetaData();DefaultLobHandler handler = new DefaultLobHandler();String columnName, value;try {for (int i = 1; i <= red.getColumnCount(); i++) {columnName = red.getColumnName(i);if (red.getColumnTypeName(i).equalsIgnoreCase("CLOB")) {value = handler.getClobAsString(rs, i);} else {value = rs.getString(i);}//如果数据库字符集不是GBK,修改为GBKif (!"GBK".equalsIgnoreCase(charSet) && charSet != null) {if (value == null) continue;value = new String(value.getBytes(charSet), "GBK");}record.put(columnName, value);}} catch (Exception e) {e.printStackTrace();}return record;}}
}

测试代码:用的定时任务,一秒钟执行一次

    private final ComDao comDao;@Scheduled(cron = "0/1 * * * * ?")public void data1() {SyncConfigDb db = new SyncConfigDb();db.setDbId("COMM");db.setDbUrl("jdbc:oracle:thin:@192.168.1.115:1521:orcl");db.setDbName("COMM");db.setDbPwd("123");comDao.setDataSource(db);List<ComRecord> list = comDao.query("select * from tablename1");System.out.println("data1==" + list.size());}@Scheduled(cron = "0/1 * * * * ?")public void data2() {SyncConfigDb db = new SyncConfigDb();db.setDbId("TYL");db.setDbUrl("jdbc:oracle:thin:@192.168.1.115:1521:orcl");db.setDbName("TYL");db.setDbPwd("123");comDao.setDataSource(db);List<ComRecord> list = comDao.query("select * from tablename2");System.out.println("data2==" + list.size());}

牛逼,真他么想给自己点个赞。

更多推荐

最简单可配置的多数据源dataSource

本文发布于:2024-02-11 19:31:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1682945.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:最简单   dataSource

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!