spring学习笔记(18)使用JNDI模拟访问应用服务器多数据源实例

在这一篇文章中,我们要用JNDI访问我们的应用服务器配置好的多数据源。在本实例中,我们使用本地的tomcat服务器来模拟远程服务器,由于本地只有mysql数据库,故通过访问不同的mysql数据库不同database来模拟同时访问不同数据库如mysql和oracle等。
下面是我们的配置步骤。

1. 在服务器配置全局数据源

首先在我们的tomcat服务器下找到conf文件夹里的server.xml文件,打开并找到 <GlobalNamingResources>。在该节点下会有一个形如下面所示的全局资源

    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
我们需要在这后面添加我们的数据源配置。如:
    <Resource
       name="jdbc/mysql1"
       auth="Container"
       type="javax.sql.DataSource"
       maxActive="100"
       maxIdle="30"
       maxWait="10000"
       username="root"
       password="root"
       driverClassName="com.mysql.jdbc.Driver"
       url="jdbc:mysql://127.0.0.1:3306/yc1"/>
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
<Resource
       name="jdbc/mysql2"
       auth="Container"
       type="javax.sql.DataSource"
       maxActive="100"
       maxIdle="30"
       maxWait="10000"
       username="root"
       password="root"
       driverClassName="com.mysql.jdbc.Driver"
       url="jdbc:mysql://127.0.0.1:3306/yc2"/>

然后需要在存放server.xml的同一个conf目录下找到context.xml,在节点下加入如下示例配置信息

<ResourceLink global="jdbc/mysql1" name="jdbc/mysql1" type="javax.sql.DataSource" />
<ResourceLink global="jdbc/mysql2" name="jdbc/mysql2" type="javax.sql.DataSource" />
注意这里的global要和我们在server.xml中配置的数据源名字一样

2. 在Spring容器中配置JNDI连接池信息

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName">
        <value>java:comp/env/jdbc/mysql1</value>
        <!--java:comp/env是默认部分,
        我们修改jdbc/mysql1对应我们在context.xml中配置<ResourceLink>中的name-->
    </property>
</bean>
<bean id="dataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName">
        <value>java:comp/env/jdbc/mysql2</value>
    </property>
</bean>

在这里我配置两个数据源来模拟连接两个不同的数据库。

3. 测试连接

在本实例中通过Hibernate整合SpringMVC来进行测试。

1. 在IOC容器中配置

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource" />
    </property>
    <property name="hibernateProperties">
        <props>
            <!-- MySQL的方言 -->
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="javax.persistence.validation.mode">none</prop>
            <!-- 必要时在数据库新建所有表格 -->
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="current_session_context_class">thread</prop>
            <!-- <prop key="hibernate.format_sql">true</prop> -->
        </props>
    </property>
    <property name="packagesToScan" value="com.yc.model1" />
</bean>
<bean id="sessionFactory2"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource2" />
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="javax.persistence.validation.mode">none</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="current_session_context_class">thread</prop>
            <prop key="hibernate.format_sql">true</prop>
        </props>
    </property>
    <property name="packagesToScan" value="com.yc.model2" />
</bean>

2. 定义我们的实体类

在这里我们定义两个实体类,对应到两个不同的库表中。

   /*****************实体类1*****************/
   package com.yc.model1;
   @Entity
   public class User {
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       private Integer id;
       private String name;
    //忽略getter和setter
   }
   /*****************实体类2*****************/
   package com.yc.model2;
   @Entity
   public class User {
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       private Integer id;
       private String name;
    //忽略getter和setter
   }

3. 在mysql中创建数据库yc1和yc2:

create database yc1;
create database yc2;

至此,我们的初步测试配置已完成,这时候,运行tomcat服务器,进入mysql数据库,依次执行命令
`use yc1;show tables;use yc2;show tables;`
会看到如下图所示的结果


即hibernate帮我们自动对应实体创建表格了。到这里位置,我们的JNDI多数据源配置测试基本完成,但为了使我们的测试更加充分,不妨通过web配置具体测试一遍。

4. 在数据表中插入测试数据

依次执行如下命令:
use yc1;INSERT INTOUser(name) VALUES ('JNDITest1');
use yc2;INSERT INTOUser(name) VALUES ('JNDITest2');

5. 配置Controller

示例如下:

package com.yc.controller;

@Controller
public class JNDITestController {

    @Autowired
    @Qualifier("sessionFactory")
    private SessionFactory sessionFactory;

    @Autowired
    @Qualifier("sessionFactory2")
    private SessionFactory sessionFactory2;
    @RequestMapping("testJNDI")
    @ResponseBody
    public String testJNDI(){
        String name1 = (String) sessionFactory.openSession().createQuery("select name from User where id = 1").uniqueResult();
        String name2 = (String) sessionFactory2.openSession().createQuery("select name from User where id = 1").uniqueResult();
        return "name1 = " + name1 + "————name2 = "+ name2 ;

    }
}

6. 重启tomcat服务器

在游览器中输入如下url:http://localhost:8090/yc/testJNDI,会得到游览器响应:name1 = JNDITest1————name2 = JNDItest2。示例图片如下所示:

4. 测试小结

至此我们的配置和测试都已经完成了。这里囿于我的本地资源限制,没有进行远程服务器测试。也没有进行真正的多数据库测试,但原理都是类似的。

上面示例只是为了展示JDNI连接应用服务器配置多数据源的实际操作流程测试。但在实际应用中,面对多数据源,我们还需要针对我们的具体需求作更深入的DAO层设计配置。比如,我们可以结合AOP来针对我们的DAO层的不同访问数据库方法来完成我们的读写分离。具体实现请移步下篇文章。

时间: 2024-10-18 15:11:55

spring学习笔记(18)使用JNDI模拟访问应用服务器多数据源实例的相关文章

spring学习笔记(19)mysql读写分离后端AOP控制实例

在这里,我们接上一篇文章,利用JNDI访问应用服务器配置的两个数据源来模拟同时操作不同的数据库如同时操作mysql和oracle等.实际上,上个例子可能用来模拟mysql数据库主从配置读写分离更贴切些.既然如此,在本例中,我们就完成读写分离的模拟在web端的配置实例. 续上次的例子,关于JNDI数据源的配置和spring datasource的配置这里不再重复.下面着重加入AOP实现DAO层动态分库调用.可先看上篇文章<spring学习笔记(18)使用JNDI模拟访问应用服务器多数据源实例 >

spring学习笔记(21)编程式事务配置,service层概念引入

访问数据库事务导入 在我之前的文章<spring学习笔记(19)mysql读写分离后端AOP控制实例>中模拟数据库读写分离的例子,在访问数据库时使用的方法是: public <E> E add(Object object) { return (E) getSessionFactory().openSession().save(object); } 通过直接开启session而后保存对象.查询数据等操作,是没有事务的.而如果我们的项目规模变大,业务逻辑日益复杂,我们在一个方法中进行大

spring学习笔记(16)趣谈spring 事件机制[2]:多监听器流水线式顺序处理

上一篇我们使用到的ApplicationListener是无序的,结合异步调度它能满足了我们的大部分应用场景,但现在我们来个另类的需求,我们来模拟一条作业调度流水线,它不能异步,必须按照先后次序执行不同的任务才能得到我们的最终结果. 需求示例:现在假如华中科技大学的小白想要为它的智能机器人作品申报国家创新奖,需要经过学校.省级创新科研机构.国家创新科研机构逐层审核.我们尝试通过事件来实现,核心就在监听器实现SmartApplicationListener接口.示例如下: 1. 配置事件发布者小白

spring学习笔记(13)基于Schema配置AOP详解

基于Schema配置入门实例 除了基于@AspectJ注解的形式来实现AOP外,我们还可以在IOC容器中配置.先来看看一个常见的应用场景,在我们的web项目中,我们需要为service层配置事务,传统的做法是在每个业务逻辑方法重复下面配置中: Created with Raphaël 2.1.0程序开始1. 获取DAO层封装好的数据库查询API,如HIbernate中的SessionFactory/Session和mybatis中的xxxMapper2. 开启事务3. 根据入参查询数据库完成相应

Spring学习笔记3之消息队列(rabbitmq)发送邮件功能_java

rabbitmq简介: MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术.排队指的是应用程序通过 队列来通信.队列的使用除去了接收和发送应用程序同时执行的要求.其中较为成熟的MQ产品有IBM WEBSPHERE MQ. 本节的内容是用户注册时,将邮

spring学习笔记(10)@AspectJ研磨分析[1]入门、注解基本介绍

@AspectJ准备 AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件. 在使用AspectJ之前,我们需要导入aspectJ相应的jar包,可到我的资源页http://download.csdn.net/detail/qwe6112071/9468329 中下载,而如果使用maven则可直接在pom.xml中加入如下代码: <dependency> <groupId>o

Spring学习笔记之依赖的注解(2)

Spring学习笔记之依赖的注解(2) 1.0 注解,不能单独存在,是Java中的一种类型 1.1 写注解 1.2 注解反射 2.0 spring的注解 spring的 @Controller@Component@Service//更多典型化注解,但是@Controller@Service建议使用 @service("personService")可以代替set get 方法,@Resource(name=personDao) @Autowired//按照类型匹配 @Qualifier

Spring学习笔记之aop动态代理(3)

Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. PersonDao.java public interface PersonDao { public void savePerson(); } PersonDaoImpl.java public class PersonDaoImpl implements PersonDao{ public void save

Spring学习笔记2之表单数据验证、文件上传实例代码_java

在上篇文章给大家介绍了Spring学习笔记1之IOC详解尽量使用注解以及java代码,接下来本文重点给大家介绍Spring学习笔记2之表单数据验证.文件上传实例代码,具体内容,请参考本文吧! 一.表单数据验证 用户注册时,需要填写账号.密码.邮箱以及手机号,均为必填项,并且需要符合一定的格式.比如账号需要32位以内,邮箱必须符合邮箱格式,手机号必须为11位号码等.可以采用在注册时验证信息,或者专门写一个工具类用来验证:来看下在SpringMVC中如何通过简单的注释实现表单数据验证. 在javax