a plurality of source data items ssm

In the project, a number of issues, some of the modules need to link to another database query, then, you can be configured to operate two data sources.

1. Create jdbc.properties

= jdbc jdbc.url: MySQL: // localhost:? 3306 / test1 to true & characterEncoding useUnicode = = utf8
jdbc.driver = com.mysql.jdbc.Driver
jdbc.username = root
jdbc.password = 123


## second data link
jdbc = jdbc .url2: MySQL: //192.168.1.57:? 3306 / = to true useUnicode the Test & characterEncoding = utf8
jdbc.driver2 = com.mysql.jdbc.Driver
jdbc.username2 = root
jdbc.password2 = 123
2. obtain data currently used source

org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource Import;
/ **
* <P> desc: a plurality of data sources </ P>
* <P> Class Name: DynamicDataSource </ P>
* <P> Created: 2018-7-10 9:38:42 aM </ P>
* <P> @author: MMY </ P>
* /
public class DynamicDataSource the extends AbstractRoutingDataSource {

protected determineCurrentLookupKey Object () {
return DBContextHolder.getDbType ();
}

}
3. switch the data source tools:

/ **
* <the p-> desc: switch data sources </ p>
* <the p-> class name: DBContextHolder </ p>
* <the p-> Created: 2018-7-10 9:39:24 AM </ p >
* <P> @author: MMY </ P>
* /
public class DBContextHolder {

Private static Final the ThreadLocal <String> = new new ContextHolder the ThreadLocal <String> ();
public static void setDbType (String dbType) {
contextHolder.set (dbType );
}

public static String getDbType () {
return ((String) contextHolder.get ());
}

public static void clearDbType () {
contextHolder.remove ();
}

}
4. configuration profile in the spring

<!-- 第一步:配置数据源 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>

<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.url2}"></property>
<property name="driverClass" value="${jdbc.driver2}"></property>
<property name="user" value="${jdbc.username2}"></property>
<property name="password" value="${jdbc.password2}"></property>
</bean>

<!-- 配置多数据源 -->
<bean class="com.ocean.utils.DynamicDataSource" id="dynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource1" key="dataSource1"></entry>
<entry value-ref="dataSource2" key="dataSource2"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1"></property>
</bean>


<!-- 创建sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource"></property>
<Property name = "configLocation" value = "the CLASSPATH: SqlMapConfig.xml"> </ Property>
</ bean>
! <- Interface configuration mybatis agent development
* interface class name and mapping files must be the same name
* interface classes and mapping files must be in the the same directory
* namespace mapping file name must be the full path name of the class interface
* interface method name and id mapping Statement must be consistent
->
<-! <bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer ">
<Property name =" basePackage "value =" com.ocean.mapper "> </ Property>
<Property name =" sqlSessionFactoryBeanName "value =" SqlSessionFactory "> </ Property>
</ the bean> ->

<! - - integration need to do configuration changes General Mapper: ->
<- original full class name:! org.mybatis.spring.mapper.MapperScannerConfigurer ->
<!- General Mapper Use: tk.mybatis.spring.mapper.MapperScannerConfigurer ->
<the bean class = "tk.mybatis.spring.mapper.MapperScannerConfigurer">
<Property name = "basePackage" value = "com.ocean.mapper" />
<Property name = "Properties">
<value>
enumAsSimpleType to true =
</ value>
</ Property>
</ bean>


<-! Affairs ->
<bean the above mentioned id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<Property name = "dataSource" ref = "dynamicDataSource "> </ Property>
</ bean>

<- turned Affairs notes ->!
<tx: transaction-Driven-annotation Manager =" transactionManager "/>
here, using a generic mapper, you need to import additional two jar and package.

Generic mapper, can help us perform basic CRUD operations For other operations, you can then be configured to the .xml

Examples are as follows:

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ocean.mapper.UserMapper" >
<resultMap id="BaseResultMap" type="com.ocean.po.User" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="nickname" property="nickname" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
<result column="qy_flag" property="qyFlag" jdbcType="VARCHAR" />
</resultMap>

<select id="findOne" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT * from user where id = #{id}
</select>

</mapper>
4.测试使用

Note: The default data source is dataSource1, does not require the use configuration. If you need to use dataSource2, you will need to declare and needs to close after use is completed.

the findById the User public (Integer ID) {
the User User = userMapper.selectByPrimaryKey (ID);
return User;
}
/ **
* Test second data source usage
* /
public findId2 the User (Integer ID) {
// = the User User UserMapper. selectByPrimaryKey (ID);
// call to the database 2
DBContextHolder.setDbType ( "DataSource2");
the User User = userMapper.findOne (ID);
DBContextHolder.clearDbType (); // Close
return User;
}
 

The results are as follows

 

 

 

By the way, a method of printing sql below, was added to a word in the configuration file sqlMapConfig.xml mybatis

<Settings>
<- - print query!>
<Setting name = "logImpl" value = "STDOUT_LOGGING" />
</ Settings>
Key: Follow discovered a problem, see: Transaction has not been configured, the question is: scan configuration in application.xml and Springmvc.xml notes in question.

Under summary: Spring loaded when using ContextLoadListener applicationContext.xml or xml file with a different name, to check the data source and related matters annotations, start a transaction characteristics. If the file is loaded Springmvc.xml only as an ordinary bean definition is loaded. So that is a good habit, hierarchical configuration related bean. applicationContext.xml configuration database associated bean (dao, service, etc.), mvc configuration related bean (controller, etc.) in the spingmvc.

After adding Affairs, we found that the data source can not be switched, it is a headache. A variety of Baidu, finally found the problem.

Question: open transaction is generally open in service during and after the transaction will lead to open the data source switch fails, the data source switching needs to be performed before the transaction open.

Solution: Before the controller layer-Service calls, switching the data source, after the call is completed, the data source, and turn off the controller.
---------------------

Guess you like

Origin www.cnblogs.com/ly570/p/11183008.html