这个是我写的第一个随手小记,一晃眼做后端开发也有7年多了,现在也准备将一些杂七杂八的资料整理下。也算是回顾这7年中做的比较有意思的东西了。

这个需求是我17年做的,当时的应用场景是仓储库比较多,随时会动态的开启和关闭。好在数据库的表结构是一致的。需要针对不同的库将商品进行有效的管理起来。考虑到数据源是动态变化的,那么使用spring架构下的多数据源配置是行不通。因为表名一致,而且数据源是动态变化的,最少也有90多家的数据,手工配置会死人的。那换成java的jdbc管理呢,最基本的那个,考虑到现在都到mybatis进行数据库管理了。往回退也不好。那么就花了几天出了这个方案。废话不说了,开工...... 第一次写博客还是有点小激动啊。

首先需要手动获取spring的application,从而手动进行资源的注入。将代码的独立性做起来。

/**
* Created by Dean on 2017/10/19.
* 获取SpringApplicationContext信息获取 该方法可以不用通过注入形式获取相关数据
*/
@Component
public class SpringApplictionAuto implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringApplictionAuto.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}

图1: Mybatis的大致结构

1 public SqlSessionTemplate getLocalMybatislSession() {
2 ApplicationContext applicationContext = SpringApplictionAuto.getApplicationContext();
3 SqlSessionFactory defaultSqlSessionFactory = (SqlSessionFactory) applicationContext.getBean("sqlSessionFactory");
4 SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(defaultSqlSessionFactory);
5 return sqlSessionTemplate;
6 }

获取本地SqlSessionTemplate

本地SqlSession获取好后那么后面就是重头戏了。

我们首先需要获取的有以下几点:

  • 数据库连接说明
  • 数据库账号信息(没有相关信息也连不上数据库,当然数据库密码小伙伴们打算用密文还是明文,都是随意的。密文的话需要双向加密方式,明文吗,倒是随时可以查其他系统数据库了)
  • 数据库mapper组信息
  • 数据库mapper具体地址
  • 数据库mapper组和mapper的具体关联
  • 数据库配置参数表,其中还有类型处理器

后面就是依次创建SqlSessionFactoryBean,SqlSessionFactory,DruidDataSource,Configuration,TypeHandler[]

 1 /**
2 * 通过数据库相关信息与mybatis相对应的信息创建 SqlSessionFactory
3 *
4 * @param hospitalDbInfoEntity 数据库相关信息
5 * @param hospitalMapperEntityArrayList 该数据源下存在相应的mapper信息
6 * @return 返回SqlSessionFactory
7 * @throws Exception 创建失败时会返回异常
8 */
9 public SqlSessionFactory buildSqlSessionFactory(SqlSessionFactoryBean factoryBean, HospitalDbInfoEntity hospitalDbInfoEntity, ArrayList<HosMapper> hospitalMapperEntityArrayList) throws Exception {
10 DruidDataSource dataSource =new DruidDataSource();
11 dataSource.setDefaultAutoCommit(true);
12 dataSource.setUrl(hospitalDbInfoEntity.getUrl());
13 dataSource.setPassword(hospitalDbInfoEntity.getPassword());
14 dataSource.setUsername(hospitalDbInfoEntity.getUser());
15 dataSource.setDriverClassName(hospitalDbInfoEntity.getDriver_name());
16
17 dataSource.setInitialSize(50);
18 dataSource.setMaxActive(100);
19 dataSource.setMaxIdle(50);
20 dataSource.setMinIdle(30);
21 dataSource.setRemoveAbandoned(true);
22 dataSource.setRemoveAbandonedTimeout(180);
23 dataSource.setFilters("stdout");
24 dataSource.setResetStatEnable(false);
25 dataSource.setMaxWait(600000);
26 dataSource.setTimeBetweenEvictionRunsMillis(300000);
27 dataSource.setMinEvictableIdleTimeMillis(600000);
28 dataSource.setValidationQuery("SELECT 1 from dual");
29 dataSource.setTestOnBorrow(true);
30 dataSource.setTestOnReturn(false);
31 dataSource.setTestWhileIdle(true);
32 factoryBean.setDataSource(dataSource);
33 String paths = "";
34 factoryBean.setMapperLocations(getMapperResource(hospitalMapperEntityArrayList));
35 Configuration configuration = buildConfiguration();
36 factoryBean.setConfiguration(configuration);
37 factoryBean.setTypeHandlers(buildTypeHandlers(configuration));
38 SqlSessionFactory sqlSessionFactory = factoryBean.getObject();
39 return sqlSessionFactory;
40 }

部分创建代码

上面这块设置好后就是后面拿结果了,结果还是封装到了SqlSessionTemplate中。

 1 /**
2 * 创建SqlSession信息通过医院Id值
3 *
4 * @param hospitalId 数据库中对应的唯一键值
5 * @return 返回创建好的数据库连接信息
6 */
7 public SqlSessionTemplate buildSqlSession(Integer hospitalId) {
8 SqlSession localSession = getLocalSession();
9 HosConnIdMapper hosConnIdMapper = localSession.getMapper(HosConnIdMapper.class);
10 HosMapperMapper hosMapperMapper = localSession.getMapper(HosMapperMapper.class);
11 HospitalDbInfoEntity hospitalDbInfoEntity = hosConnIdMapper.findHospitalEntity(hospitalId);
12
13 if (hospitalDbInfoEntity == null) {
14 return null;
15 }
16 ArrayList<HosMapper> hospitalMapperEntityArrayList = (ArrayList<HosMapper>) hosMapperMapper.findByHospitalId(hospitalId);
17 if (hospitalMapperEntityArrayList.size() == 0) {
18 return null;
19 }
20 SqlSessionFactory sqlSessionFactory;
21 try {
22 sqlSessionFactory = buildSqlSessionFactory(hospitalId.toString(), hospitalDbInfoEntity, hospitalMapperEntityArrayList);
23 } catch (Exception e) {
24 e.printStackTrace();
25 return null;
26 }
27 sqlSessionFactoryHashMap.put(hospitalId.toString(), sqlSessionFactory);
28 SqlSessionTemplate sqlSession = new SqlSessionTemplate(sqlSessionFactory);
29 dataPools.put(hospitalId.toString(), sqlSession);
30 return sqlSession;
31 }

创建SqlSessionTemplate

最后就是准备拿结果了:

 1 /**
2 * 获取mybatis中Mapper信息
3 *
4 * @param mapper mybatis 相关dao层类名
5 * @param hospitalId mybatis连接的
6 * @param <T> 自定义类型可供不同的mapper进行使用
7 * @return 返回Mapper信息
8 */
9 public <T> T getMapperInstance(Class<T> mapper, Integer hospitalId) {
10 SqlSessionTemplate sqlSession;
11
12 if (hospitalId == 0) {
13 sqlSession = dataPools.get("localSession");//本地连接
14 } else {
15 sqlSession = dataPools.get(hospitalId.toString());
16 }
17 if (sqlSession == null) {
18 sqlSession = buildSqlSession(hospitalId);
19 }
20 return SqlSessionUtils.getSqlSession(sqlSession.getSqlSessionFactory(),sqlSession.getExecutorType(),sqlSession.getPersistenceExceptionTranslator()).getMapper(mapper);
21 }

获取具体的mapper

到此,目的达到了。可以通过入参比如数据源ID,可以动态获取某一个数据源的ID下的具体mapper。

由于当时应该是工作的第二年,很多地方写的也不好,我就将关键的地方放上来了。有些描述不对的,请小伙伴指出来。

图1来源:https://blog.csdn.net/u013541707/article/details/113245421

自主创建mybtis管理应用,用以横向管理数据源的更多相关文章

  1. intellij 创建java web项目(maven管理的SSH)

    intellij 创建java web项目(maven管理的SSH) 环境intellij IDEA14.MAVEN.Spring.Struts2.Hibernate.Java Web.工程搭建. 1 ...

  2. oracle创建表空间自增空间管理

    表空间(tablespace).段(segment).区(extent).块(block),这些都是oracle数据库在数据文件中组织数据的基本单元 1.创建表空间create tablespace ...

  3. 订单业务楼层化 view管理器和model管理器进行了model和view的全面封装处理 三端不得不在每个业务入口上线时约定好降级开关,于是代码中充满了各种各样的降级开关字段

    京东APP订单业务楼层化技术实践解密 原创 杜丹 留成 博侃 京东零售技术 2020-09-29 https://mp.weixin.qq.com/s/2oExMjh70Kyveiwh8wOBVA 用 ...

  4. 云原生应用管理,像管理手机APP一样管理企业应用

    我们在使用智能手机的时候,手机APP从应用市场一键安装,安装好即点即用,当有新版本一键升级,如果不想用了长按图标删除,整个过程非常简单,小朋友都能熟练掌握.而对于企业应用,由于结构复杂.可用性要求高. ...

  5. Linux中断管理 (1)Linux中断管理机制

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

  6. Atitit 分布式管理 vs 集中式管理

    Atitit 分布式管理 vs 集中式管理 1. 集中式管理缺点 1 1.1. 单点故障 1 1.2. 没有灵活性 1 1.3. 打败vs 征服 参考 尼可罗·马基雅弗利编著的<君主论> ...

  7. 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)

    一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...

  8. Java SSM 客户管理 商户 管理系统 库存管理 销售报表 项目源码

    系统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3  SSM ...

  9. SVN-项目 XXX 受源代码管理。向源代码管理注册此项目时出错。建议不要对此项目进行任何修改

    错误描述:  项目 XXX 受源代码管理.向源代码管理注册此项目时出错.建议不要对此项目进行任何修改 解决办法: 使用记事本打开,项目csproj文件删除图中几行,重新打开解决方案就可以了 原因分析: ...

随机推荐

  1. go将青龙面板里面的脚本文件都下载到本地

    纯粹练手用的,大家轻喷 青龙面板的脚本文件可以下载到本地,这样的话自己可以研究一下对应的脚本文件,能学到更多的知识,原理其实很简单,F12一下就知道了,青龙面板使用Request Headers里面放 ...

  2. Java学习 (六)基础篇 类型转换

    类型转换 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换 字节大小(容量)-> 低--------------------------------------------- ...

  3. 羽夏看Linux内核——门相关入门知识

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后面,并 ...

  4. LuoguP1858 多人背包(DP)

    第\(K\)优解这类问题可在\(DP\)过程中通过添维解决.归并出当前前\(K\)大的解. #include <iostream> #include <cstdio> #inc ...

  5. [Blender] Blender 获取 Instance 的信息

    最近希望用 Blender 生成 Instance 的能力,将生成的导入游戏引擎中来渲染.Instance Rendering 是个好东西,特别是针对大场景,渲染成批的基本相同的物体的时候非常有用. ...

  6. 【java】学习路线8-cmd带命令编译包

    /*java类包(package)package XX.XX.XX;    包名命名规则:(以域名开头,都是小写)        com.remooo.xx        编译:javac -d . ...

  7. docker容器资源限制:限制容器对内存/CPU的访问

    目录 一.系统环境 二.前言 三.docker对于CPU和内存的限制 3.1 限制容器对内存的访问 3.2 限制容器对CPU的访问 一.系统环境 服务器版本 docker软件版本 CPU架构 Cent ...

  8. 利用京东云Web应用防火墙实现Web入侵防护

    摘 要 本指南描述如何利用京东云Web应用防火墙(简称WAF),对一个简单的网站(无论运行在京东云.其它公有云或者IDC)进行Web完全防护的全过程.该指南包括如下内容: 1 准备环境 1.1 在京东 ...

  9. 高阶 CSS 技巧在复杂动效中的应用

    最近我在 CodePen 上看到了这样一个有意思的动画: 整个动画效果是在一个标签内,借助了 SVG PATH 实现.其核心在于对渐变(Gradient)的究极利用. 完整的代码你可以看看这里 -- ...

  10. 2022 CLion 中的Cygwin 配置(最全,最良心版)

    目录 前景提要 一.windows 10 安装Cygwin 1.找到官网,进入官网,百度搜索或者点击下边链接. 2.找到如图位置,双击下载 3.下载完成后,找到下载的位置,双击exe文件. 4.进入欢 ...