内容简介:动态管理数据源的基本功能:数据源加载,容器维护,持久化管理。不同厂商的关系型数据库,提供的链接方式,驱动包,驱动类名都是不一样的,Java数据库连接API,JDBC是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法,且适配大部分关系型数据库。
一、关系型数据源
1、动态数据源
动态管理数据源的基本功能:数据源加载,容器维护,持久化管理。
2、关系型数据库
不同厂商的关系型数据库,提供的链接方式,驱动包,驱动类名都是不一样的,Java数据库连接API,JDBC是 Java 语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法,且适配大部分关系型数据库。
3、适配要素
核心要素:驱动包、驱动类名、URL格式、默认端口。
关系型数据库很多,这里一定是不全的,根据需要自行完善即可。
public enum DataSourceType {
MySql("MySql", "com.mysql.jdbc.Driver"),
Oracle("Oracle", "oracle.jdbc.OracleDriver"),
DB2("DB2", "com.ibm.db2.jcc.DB2Driver");
private String dataSourceName;
private String driverClassName;
public static String getDriver (String dataSourceName) {
DataSourceType[] types = DataSourceType.values();
for (DataSourceType type : types) {
if (type.getDataSourceName().equals(dataSourceName)) {
return type.getDriverClassName();
}
}
return null;
}
DataSourceType (String dataSourceName,String driverClassName){
this.dataSourceName = dataSourceName ;
this.driverClassName = driverClassName ;
}
}
4、JDBC基础API
DriverManager
管理JDBC驱动程序的基本服务API。调用方法Class.forName,显式地加载驱动程序类,正好适用于动态数据源的业务场景,数据源类型未知情况。加载Driver类并在DriverManager类注册后,即可用来与数据库建立连接。
DataSource
DataSource接口,由驱动程序供应商实现,负责建立与数据库的连接,当在应用程序中访问数据库时,常用于获取操作数据的Connection对象。
Connection
Connection接口代表与特定的数据库的连接,要对数据库数据进行操作,首先要获取数据库连接,Connection实现就像在应用程序中与数据库之间开通了一条通道,通过DriverManager类或DataSource类都可获取Connection实例。
二、链接和管理
这里几个核心类的封装思路:模块化功能,API分开封装,如果需要适配处理各类数据源类型,则分别可以向上抽象提取,向下自定义适配策略,设计模式影响下的基本意识。
1、链接工具
基于DriverManager管理数据源的驱动加载,链接获取等。
public class ConnectionUtil {
public static synchronized Connection getConnect(String driverClassName,String userName,
String passWord,String jdbcUrl) {
Properties prop = new Properties();
prop.put("user", userName);
prop.put("password", passWord);
return connect(driverClassName,prop,jdbcUrl) ;
}
private static synchronized Connection connect(String driverClassName,
Properties prop,String jdbcUrl) {
try {
Class.forName(driverClassName);
DriverManager.setLoginTimeout(JdbcConstant.LOGIN_TIMEOUT);
return DriverManager.getConnection(jdbcUrl, prop);
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
}
2、API工具类
提供API配置获取类,加载需要的数据源API,关闭资源等基本操作。
@Component
public class JdbcConfig {
/**
* 获取数据源连接
*/
public Connection getConnection (ConnectionEntity connectionEntity){
String dataTypeName = connectionEntity.getDataTypeName();
String driverClassName = DataSourceType.getDriver(dataTypeName) ;
if (driverClassName == null){
throw new RuntimeException("不支持该数据源类型") ;
}
connectionEntity.setDriverClassName(driverClassName);
return ConnectionUtil.getConnect(connectionEntity.getDriverClassName(),
connectionEntity.getUserName(),
connectionEntity.getPassWord(),
connectionEntity.getJdbcUrl()) ;
}
}
3、数据源容器
维护一个Map容器,管理数据源的添加,删除,动态获取等基本需求。
@Component
public class DataSourceFactory {
private volatile Map<Integer, DataSource> dataSourceMap = new HashMap<>();
@Resource
private JdbcConfig jdbcConfig ;
@Resource
private ConnectionMapper connectionMapper ;
/**
* 数据源API包装
*/
private static DataSource getDataSource (ConnectionEntity connectionEntity){
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(connectionEntity.getJdbcUrl());
datasource.setUsername(connectionEntity.getUserName());
datasource.setPassword(connectionEntity.getPassWord());
datasource.setDriverClassName(connectionEntity.getDriverClassName());
return datasource ;
}
/**
* 获取 JDBC 链接
*/
public JdbcTemplate getById (Integer id){
return new JdbcTemplate(dataSourceMap.get(id)) ;
}
/**
* 移除 数据源
*/
public void removeById (Integer id) {
dataSourceMap.remove(id) ;
}
/**
* 添加数据源管理
* 注意这里的方法,连接验证之后直接调用
*/
public void addDataSource (ConnectionEntity connectionEntity){
DataSource dataSource = getDataSource(connectionEntity);
dataSourceMap.put(connectionEntity.getId(),dataSource) ;
}
}
4、流程测试
基于动态的数据源,查询表数据,这里操作的表示已知的表结构,实际上动态数据源的表结构都是需要再次动态获取表字段,才能操作。(下节数据动态读取和写入会详说)
@Api(value = "JdbcQueryController")
@RestController
public class JdbcQueryController {
@Resource
private DataSourceFactory dataSourceFactory ;
@GetMapping("getList")
public List<ConnectionEntity> getList (@RequestParam("id") Integer id){
String sql = "SELECT * FROM jm_connection WHERE state='1'" ;
JdbcTemplate jdbcTemplate = dataSourceFactory.getById(id);
List<ConnectionEntity> connectionEntities = jdbcTemplate.query(sql,
new BeanPropertyRowMapper<>(ConnectionEntity.class));
return connectionEntities ;
}
}
三、批量管理
持久化数据源的配置信息,多了一步配置信息入库,和入库信息加载到容器,使用时动态获取。
1、库表Mapper结构
存储配置信息的表结构,转换Mapper文件。
<mapper namespace="com.dynamic.add.mapper.ConnectionMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.dynamic.add.entity.ConnectionEntity">
<id column="id" property="id" />
<result column="data_type_name" property="dataTypeName" />
<result column="driver_class_name" property="driverClassName" />
<result column="jdbc_url" property="jdbcUrl" />
<result column="user_name" property="userName" />
<result column="pass_word" property="passWord" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="state" property="state" />
</resultMap>
<select id="getAllList" resultMap="BaseResultMap" >
SELECT * FROM jm_connection WHERE state='1'
</select>
</mapper>
2、持久化管理
测试数据源链接是否成功,可用的数据源链接,配置信息入库保存。
@Service
public class ConnectionServiceImpl implements ConnectionService {
@Resource
private ConnectionMapper connectionMapper ;
@Resource
private JdbcConfig jdbcConfig ;
@Resource
private DataSourceFactory dataSourceFactory ;
@Override
public boolean testConnection(ConnectionEntity connectionEntity) {
return jdbcConfig.getConnection(connectionEntity) !=null ;
}
@Override
public boolean addConnection(ConnectionEntity connectionEntity) {
Connection connection = jdbcConfig.getConnection(connectionEntity) ;
if (connection !=null){
int addFlag = connectionMapper.insert(connectionEntity);
if (addFlag > 0){
dataSourceFactory.addDataSource(connectionEntity) ;
return true ;
}
}
return false ;
}
}
3、动态加载
容器工厂类中,添加一个初始化的方法,加载入库的数据源配置信息。
@Component
public class DataSourceFactory {
/**
* 初始化 JDBC 链接API
*/
@PostConstruct
public void init (){
List<ConnectionEntity> connectionList = connectionMapper.getAllList();
if (connectionList != null && connectionList.size()>0){
for (ConnectionEntity connectionEntity:connectionList) {
Connection connection = jdbcConfig.getConnection(connectionEntity) ;
if (connection != null){
DataSource dataSource = getDataSource(connectionEntity);
dataSourceMap.put(connectionEntity.getId(),dataSource) ;
}
}
}
}
}
四、源代码地址
GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 搞定 Spring Boot 多数据源(二):动态数据源
- 苞米豆-多数据源 3.4.0 发布:本地多数据源事务优化
- 苞米豆-多数据源 3.3.0 重磅更新:本地多数据源事务方案
- 苞米豆-多数据源 2.3.2 发布:支持 spel 从参数获取数据源
- Spring项目中使用两种方法动态切换数据源,多数据源切换
- 数据源管理 | 基于DataX组件,同步数据和源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Pattern Recognition and Machine Learning
Christopher Bishop / Springer / 2007-10-1 / USD 94.95
The dramatic growth in practical applications for machine learning over the last ten years has been accompanied by many important developments in the underlying algorithms and techniques. For example,......一起来看看 《Pattern Recognition and Machine Learning》 这本书的介绍吧!