在这一篇文章中,我们要用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 INTO
User(
name) VALUES ('JNDITest1');
use yc2;INSERT INTO
User(
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层的不同访问数据库方法来完成我们的读写分离。具体实现请移步下篇文章。