`
lvwenwen
  • 浏览: 958465 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

Spring多数据源解决方案

阅读更多


                                        Figure 2 多数据源的选择逻辑渗透至客户端

  解决方案

图片                                    Figure 3 采用Proxy模式来封转数据源选择逻辑  

         通过采用Proxy模式我们在方案实现中实现一个虚拟的数据源.并且通过它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来.Client提供选择所需的上下文(因为这是Client所知道的),有虚拟的DataSource根据Client提供的上下文来实现数据源的选择.Spring2.x的版本中提供了实现这种方式的基本框架.虚拟的DataSource仅需要继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源选择逻辑.

       实例:

      public class DynamicDataSource extends AbstractRoutingDataSource{

               static Logger log=Logger.getLogger("DynamicDataSource");

               @Override

               protected Object determineCurrentLookupKey(){

                      String userId=(String)DbContextHolder.getContext();

                      Integer dataSourceId=getDataSourceIdByUserId(userId);

                      return dataSourceId; 

              } 

     }

 

实例中通过UserId来决定数据存放在哪个数据库中。
    配置文件示例:

<bean id="dataSource" class="com.bitfone.smartdm.datasource.DynamicDataSource">
              <property name="targetDataSources">
                 <map key-type="java.lang.Integer">
                    <entry key="0" value-ref="dataSource0"/>
                    <entry key="1" value-ref="dataSource1"/>
                    <entry key="2" value-ref="dataSource2"/>
                 </map>
              </property>
              <property name="defaultTargetDataSource" ref="dataSource0"/>
            </bean>
            <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
                <property name="configLocation" value="classpath:com/bitfone/smartdm/dao/sqlmap/sql-map-config.xml"/>
                <property name="dataSource" ref="dataSource"/>
           </bean>
            <bean id="UserInfoDAO" class="com.bitfone.smartdm.dao.impl.UserInfoDAO">

                  <property name="sqlMapClient" ref="sqlMapClient"/>
            </bean>

 

下面是个人在项目中用过的配置方法(以后公布):

程序中的控制代码

public class DbContextHolder{

    private static final ThreadLocal contextHolder = new ThreadLocal();    
    
    public static void setDbType(String dbType) 
    {    
        contextHolder.set(dbType);   
    }    
    
    
    
    public static String getDbType() 
    {    
        String str=(String) contextHolder.get();
        if(null==str || "".equals(str))
            str="1";
        return str;   
    }    
    
    public static void clearDbType() 
    {    
        contextHolder.remove();   
    } 

}

在程序中通过设置DbContextHolder.setDbType(String dbType);来控制数据库的选取,其中key配置目标数据源的键值.

MySQL中group_concat函数
                                                                                                                                                @author Bob  2012/08/07
 

本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) 。
MySQL中group_concat函数
完整的语法如下:
group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])

基本查询 
mysql> select * from aa;
+------+------+
| id| name |
+------+------+
|1 | 10|
|1 | 20|
|1 | 20|
|2 | 20|
|3 | 200  |
|3 | 500  |
+------+------+
6 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔(默认) 
mysql> select id,group_concat(name) from aa group by id;
+------+--------------------+
| id| group_concat(name) |
+------+--------------------+
|1 | 10,20,20|
|2 | 20 |
|3 | 200,500|
+------+--------------------+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,分号分隔 
mysql> select id,group_concat(name separator ';') from aa group by id;
+------+----------------------------------+
| id| group_concat(name separator ';') |
+------+----------------------------------+
|1 | 10;20;20 |
|2 | 20|
|3 | 200;500  |
+------+----------------------------------+
3 rows in set (0.00 sec)

以id分组,把去冗余的name字段的值打印在一行, 
逗号分隔

mysql> select id,group_concat(distinct name) from aa group by id;
+------+-----------------------------+
| id| group_concat(distinct name) |
+------+-----------------------------+
|1 | 10,20|
|2 | 20  |
|3 | 200,500 |
+------+-----------------------------+
3 rows in set (0.00 sec)

以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序 
mysql> select id,group_concat(name order by name desc) from aa group by id;
+------+---------------------------------------+
| id| group_concat(name order by name desc) |
+------+---------------------------------------+
|1 | 20,20,10  |
|2 | 20|
|3 | 500,200|
+------+---------------------------------------+
3 rows in set (0.00 sec)

本人在做用户有哪些角色动态显示是用到.可以提高代码简洁性与程序的效率,不用对比用户角色关联表与用户角色与用户表.

JavaScript 动态实现树形菜单(使用dtree控件)
                                                                                                                @author Bob 2012/08/09

动态生成树型菜单

数据库脚本:

use master
go
if exists (select * from sysdatabases where name = 'tree')
 drop database tree
go
create database tree
on
(
  Name = 'tree_data',                  --主数据文件的逻辑名称 
    FileName = 'D:/tree_data.mdf'--数据文件的物理名称 
    Size = 5Mb,                         -- 主数据文件的初始大小 
    FileGrowth = 20%                    --主数据文件增长率 
)
log on
(
 Name = 'tree_log'
    FileName = 'd:/tree_log.ldf'
    Size = 3Mb, 
    FileGrowth = 10%
)
go
if exists (select * from sysobjects where name = 'dtree')
 drop table dtree
go
use tree
go
/*--- 创建节点表 ---*/
create table dtree
(
 id varchar(20) ,     --节点编号
 pid varchar(20) ,     --父节点
 [name] varchar(20),     --节点名称
 url varchar(20),     --连接地址
 title varchar(20),     --节点描述
 target varchar(20),     --Target
 icon varchar(20),     --图标
 iconOpen varchar(20),    --展开状态下的图标路径 
 [open] varchar(20)     --是否展开
)
/*--- 初始化测试数据 ---*/
insert into  dtree values('0','-1','T16班','index.jsp','blank','','','','')
insert into  dtree values('1','0','教师','index.jsp','blank','','','','')
insert into  dtree values('2','0','班干部','index.jsp','blank','','','','')
insert into  dtree values('3','0','组长','index.jsp','blank','','','','')
insert into  dtree values('4','0','学员','index.jsp','blank','','','','')
insert into  dtree values('5','1','班主任','index.jsp','blank','','','','')
insert into  dtree values('6','1','教员','index.jsp','blank','','','','')
insert into  dtree values('7','2','班长','index.jsp','blank','','','','')
insert into  dtree values('8','2','学委','index.jsp','blank','','','','')
insert into  dtree values('9','4','学员1','index.jsp','blank','','','','')
insert into  dtree values('10','4','学员2','index.jsp','blank','','','','')
insert into  dtree values('11','4','学员3','index.jsp','blank','','','','')
insert into  dtree values('12','4','学员4','index.jsp','blank','','','','')
insert into  dtree values('13','4','学员5','index.jsp','blank','','','','')
insert into  dtree values('14','4','学员6','index.jsp','blank','','','','')
insert into  dtree values('15','4','学员7','index.jsp','blank','','','','')
insert into  dtree values('16','4','学员8','index.jsp','blank','','','','')
insert into  dtree values('17','4','学员9','index.jsp','blank','','','','')
insert into  dtree values('18','4','学员10','index.jsp','blank','','','','')
insert into  dtree values('19','4','学员11','index.jsp','blank','','','','')
insert into  dtree values('20','4','学员12','index.jsp','blank','','','','')
insert into  dtree values('21','4','学员13','index.jsp','blank','','','','')
insert into  dtree values('22','4','学员14','index.jsp','blank','','','','')
insert into  dtree values('23','4','学员15','index.jsp','blank','','','','')
select id,pid,[name],url,title,target,icon,iconOpen,[openfrom dtree

客户端代码 index.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@page import="com.zsw.biz.TreeNodeBiz;"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>    
    <title>树形菜单</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page"
 <link rel="StyleSheet" href="dtree.css" type="text/css" />
 <script type="text/javascript" src="dtree.js"></script>
  </head>  
  <body>
    <div>
     <%
      TreeNodeBiz tnb = new TreeNodeBiz();  
     %
>
     <script type="text/javascript">
      d = <%= tnb.getList("dtree") %>
      document.write(d);
     </script>
    </div>    
  </body>
</html>

转换成节点数据转换成js文件 关键代码:

  if(list==null || list.size() == 0){
   System.out.println("没有节点");
   return "";
  }
  
  StringBuffer contents = new StringBuffer();
  contents.append("dtree = new dTree('"+dtree+"');");
  
  for(TreeNode tn : list){   
   contents.append("/n");
   contents.append(dtree+".add('");
   contents.append(tn.getId());
   contents.append("','");
   contents.append(tn.getPid());
   contents.append("','");
   contents.append(tn.getName());
   contents.append("','");
   contents.append(tn.getUrl());
   contents.append("','");
   contents.append(tn.getTitle());
   contents.append("','");
   contents.append(tn.getTarget());
   contents.append("','");
   contents.append(tn.getIcon());
   contents.append("','");
   contents.append(tn.getIconOpen());
   contents.append("','");
   contents.append(tn.getOpen());
   contents.append("');"); 
   contents.append("/n");   
  }

客户端的代码:

需要导入:dtree.js 和dtree.css

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@page import="com.zsw.biz.TreeNodeBiz;"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>    
    <title>树形菜单</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">    
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page"
 <link rel="StyleSheet" href="dtree.css" type="text/css" />
 <script type="text/javascript" src="dtree.js"></script>
  </head>  
  <body>
  <p><a href="javascript: d.openAll();">全部展开</a> |
   <a href="javascript: d.closeAll();">全部关闭</a>
  </p>   
    <div>
     <%
      TreeNodeBiz tnb = new TreeNodeBiz();  
     %>
     <script type="text/javascript">
      d = <%= tnb.getList("dtree") %>
      document.write(d);
     </script>
    </div>    
  </body>
</html>

系统功能与操作权限分配原理(ERP)
 
 
                                                                                                       @author Bob 2012/08/09
        我们以前一般做的系统功能操作权限,采用的是在系统功能中定义一个权限字段,并把操作权限的id以;分割符号保存在该字段中
;一下介绍一种简便的权限分配原理; 由于本人文字功底有限.直接以图说明原理.
1.系统功能表中有一个prev字段保存操作权限 ,类型为int
2,操作权限表中的数据为
           0        查看
           1        增加
           2        修改
           3        删除
  权限分配原理:prev=2^1+2^2+2^n.....;
 至于如何在功能表中检测有哪些权限(以后在公布)
  如果 prev=5    哪么   prev=2^0+2^2    既本功能有查看,修改功能

 

 

分享到:
评论

相关推荐

    基于Spring多数据源实例

    在IT行业中,数据库是系统的核心组成部分,特别是...通过理解上述步骤和原理,开发者可以更好地设计和实施适用于各种业务场景的多数据源解决方案。在实际操作中,应根据项目需求灵活调整,以达到最佳的性能和可维护性。

    spring多数据源动态切换方案

    "Spring多数据源动态切换方案"是解决这一问题的关键技术,它允许应用程序根据业务需求动态选择数据源,提高了系统的灵活性和可扩展性。下面我们将详细探讨如何在Spring中实现多数据源的配置及动态切换。 首先,我们...

    mybatis spring 多数据源

    标签中的"源码"可能指的是理解MyBatis和Spring框架内部如何处理多数据源的关键代码,这有助于我们更深入地定制和优化解决方案。"工具"可能是指像Druid、HikariCP这样的数据库连接池,它们在多数据源配置中起着至关...

    springboot多数据源即分布式事务解决方案

    如果不想使用JTA,Spring还提供了一种基于编程式事务管理的解决方案,称为PROPAGATION_REQUIRED。在这种模式下,开发者需要手动调用`TransactionTemplate`或在Service方法上使用`@Transactional`注解来开启和管理...

    spring boot mybatis多数据源最简解决方案

    总的来说,Spring Boot和MyBatis的多数据源解决方案为开发者提供了一种灵活、可扩展的方式来管理和操作多个数据库,满足了复杂业务场景下的需求。通过合理的配置和设计,可以有效提升系统的稳定性和性能。

    spring动态数据源+mybatis分库分表

    "spring动态数据源+mybatis分库分表"是一个针对大型数据库场景的解决方案,它利用Spring框架的动态数据源功能和MyBatis的SQL映射能力,实现数据库的透明化分片。以下是这个主题的详细知识点: 1. **Spring动态数据...

    springboot多数据源即分布式事务解决方案,添加对多线程的支持

    综上所述,Spring Boot通过其强大的框架能力,为开发者提供了实现多数据源操作、分布式事务管理和多线程支持的解决方案。开发者只需进行适当的配置和编码,就能在复杂的业务场景中确保数据的完整性和一致性。在实际...

    spring多数据源的处理_mybatis实现跨库查询

    "Spring 多数据源处理_Mybatis 实现跨库查询" 本文主要讨论了 Spring 框架中多数据源的处理方法,特别是使用 Mybatis 实现跨库查询。在大型应用中,为了提高系统的水平伸缩性,需要对数据进行切分,并且采用多个...

    spring框架多数据源切换问题的解决

    首先,这个方案完全是在spring的框架下解决的,数据源依然配置在spring的配置文件中,sessionFactory依然去配置它的dataSource属性,它甚至都不知道dataSource的改变。 其次,实现简单,易于维护。这个方案虽然我说...

    如何在spring框架中解决多数据源的问题

    ### 如何在Spring框架中解决多数据源的问题 #### 问题背景及挑战 在实际的软件开发过程中,尤其是在企业级应用开发中,经常会遇到需要同时处理多个数据源的情况。例如,一个应用程序可能需要同时访问Oracle数据库...

    springboot实现多数据源而且加上事务不会使aop切换数据源失效

    本示例主要讲解如何使用Spring Boot结合MyBatis实现多数据源切换,并确保AOP事务管理仍然有效。 首先,我们需要配置多数据源。在Spring Boot中,可以使用`DataSource`接口的实现类,如`HikariCP`或`Druid`,创建两...

    Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源

    本项目“Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源”正是针对这一需求提供的一种解决方案。下面将详细介绍这个项目中的关键技术点和实现原理。 首先,Spring框架是Java企业级应用开发的核心...

    springboot连接池、动态配置多数据源连接池,特别适合大数据部门、数据中台服务的多数据源连接池.zip

    综上所述,"spring-boot-easy-connection-pool-master"项目提供了一种实用的解决方案,它结合了Spring Boot的便利性和多数据源的灵活性,为大数据环境下的数据访问和管理带来了极大的便利。通过深入学习和实践该项目...

    SpringBoot多数据源配置(方式一:配置多个mapper扫描不同的包路径实现多数据源配置).docx

    Spring Boot作为一款流行的Java框架,为开发者提供了灵活的多数据源配置方案。本文将详细介绍如何通过配置多个Mapper扫描不同的包路径来实现多数据源的配置。 #### 二、多数据源配置背景与应用场景 在Spring Boot...

    spring boot mybatis多数据源解决方案过程解析

    Spring Boot MyBatis 多数据源解决方案过程解析 在实际项目中,我们经常会遇到需要在一个项目中使用多个数据源的问题。例如,在迁移用户的聊天记录时,我们需要使用三个数据源。这时,我们可以使用 Spring Boot 和 ...

    Spring实现动态切换多数据源的解决方案

    Spring 实现动态切换多数据源的解决方案是针对大型应用程序中数据切分的需求,通过使用多个数据库实例提升系统的可扩展性。在这样的架构中,程序需要根据请求和系统状态动态选择数据存储和读取的数据库。Spring 从 2...

    基于注解多数据源解决方案.docx

    Spring框架提供了一种灵活的多数据源解决方案,基于注解的方式使得数据源的切换变得简单。本文将详细介绍如何实现基于注解的多数据源配置。 首先,Spring的`AbstractRoutingDataSource`是一个关键组件,它负责根据...

    Spring Boot中使用多个数据源 数据库.zip_常用数据库数据源

    请参考提供的资源文件,如`Spring Boot中使用多数据库 - JDBC.url`、`spring-boot jpa 配置两个数据源 - CSDN博客.url`以及`spring boot(七):springboot+mybatis多数据源最简解决方案 - 纯洁的微笑 - 博客园.url`,...

    多数据源事务解决方案,单应用多数据库保证事务

    本文将深入探讨“多数据源事务解决方案”,以及如何在单个应用程序中使用注解来实现对多个数据库的事务管理。 首先,让我们理解什么是多数据源事务。在传统的单一数据库环境中,事务管理通常由数据库系统自身提供,...

Global site tag (gtag.js) - Google Analytics