最近用到了MyBatis配置多数据源,原以为简单配置下就行了,实际操作后发现还是要费些事的,这里记录下,以作备忘。不多废话,直接上代码,后面会有简单的实现介绍。一.log4j2.xml
二.database.properties
jdbc.mysql.driver=com.mysql.jdbc.Driver
jdbc.mysql.url=jdbc:mysql://192.168.235.1:3306/hbatis?characterEncoding=utf8
jdbc.mysql.username=hbatis
jdbc.mysql.password=hbatis12345
jdbc.mysql.driver2=com.mysql.jdbc.Driver
jdbc.mysql.url2=jdbc:mysql://192.168.235.2:3306/hbatis?characterEncoding=utf8
jdbc.mysql.username2=hbatis
jdbc.mysql.password2=hbatis12345
jdbc.initialSize=5
jdbc.minIdle=5
#druid not need jdbc.maxIdle
#jdbc.maxIdle=20
jdbc.maxActive=100
jdbc.maxWait=100000
jdbc.defaultAutoCommit=false
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=600
jdbc.testWhileIdle=true
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.numTestsPerEvictionRun=20
jdbc.minEvictableIdleTimeMillis=300000
三.单数据源时的Spring配置文件
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
四.多数据源时Spring配置文件
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
五.MultipleDataSource实现
package com.bijian.study.dao;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class MultipleDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal dataSourceKey = new InheritableThreadLocal();
public static void setDataSourceKey(String dataSource) {
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
六.MyBatis接口
package com.bijian.study.dao;
import java.util.List;
import com.bijian.study.model.Article;
import com.bijian.study.model.User;
public interface IUserMapper {
User getUserById(int id);
List getUsers(String name);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
List getArticlesByUserId(int id);
}
package com.bijian.study.dao;
import java.util.List;
import com.bijian.study.model.Article;
import com.bijian.study.model.User;
public interface IUserMapper2 {
User getUserById(int id);
List getUsers(String name);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
List getArticlesByUserId(int id);
}
七.Entity实体及Mapping配置
Article.java
package com.bijian.study.model;
public class Article {
private int id;
private User user;
private String title;
private String content;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
User.java
package com.bijian.study.model;
public class User {
private int id;
private String name;
private int age;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
// 如果有带参数的构造器,编译器不会自动生成无参构造器。当查询需要返回对象时,ORM框架用反射来调用对象的无参构造函数,导致异常:java.lang.NoSuchMethodException: com.bijian.study.model.User.()
// 这时需要明确写出:
public User() {
}
public User(int id, String address) {
this.id = id;
this.address = address;
}
public User(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
}
User.xml
select *
from `user` where id = #{id}
select * from `user` where name like #{name}
insert into user(name,age,address) values(#{name},#{age},#{address})
update `user` set name=#{name}, age=#{age}, address=#{address}
where id=#{id}
delete from `user` where id=#{id}
select u.id, u.name, u.age, u.address, a.id a_id, a.title, a.content
from article a
inner join user u
on a.user_id=u.id and u.id=#{id}
User2.xml
select *
from `user` where id = #{id}
select * from `user` where name like #{name}
insert into user(name,age,address) values(#{name},#{age},#{address})
update `user` set name=#{name}, age=#{age}, address=#{address}
where id=#{id}
delete from `user` where id=#{id}
select u.id, u.name, u.age, u.address, a.id a_id, a.title, a.content
from article a
inner join user u
on a.user_id=u.id and u.id=#{id}
八.手动数据源切换调用
package com.bijian.test;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.bijian.study.dao.IUserMapper;
import com.bijian.study.dao.IUserMapper2;
import com.bijian.study.dao.MultipleDataSource;
import com.bijian.study.model.Article;
public class Main {
public static void main(String[] args) {
//初始化ApplicationContext
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("file:E:/develop/eclipse/workspace/SpringMVC/WebContent/WEB-INF/applicationContext.xml");
DataSource mySqlDataSource = (DataSource)applicationContext.getBean("mySqlDataSource");
System.out.println("mySqlDataSource:" + mySqlDataSource);
IUserMapper mySqlMapper = applicationContext.getBean(IUserMapper.class);
IUserMapper2 mySqlMapper2 = applicationContext.getBean(IUserMapper2.class);
//设置数据源为MySql,使用了AOP测试时请将下面这行注释
MultipleDataSource.setDataSourceKey("mySqlDataSource");
List articles = mySqlMapper.getArticlesByUserId(1);
for(Article acticle : articles) {
System.out.println(acticle.getTitle());
}
//设置数据源为SqlServer,使用AOP测试时请将下面这行注释
MultipleDataSource.setDataSourceKey("mySql2DataSource");
List articles2 = mySqlMapper2.getArticlesByUserId(2);
for(Article acticle : articles2) {
System.out.println(acticle.getTitle());
}
}
}
运行结果如下:
title1
title2
title3
title4
test1
test2
test3
test4
结合如下对应数据库中的数据不难发现运行结果正确。
jdbc.mysql.url对应的数据库表数据如下所示:
jdbc.mysql.url2对应的数据库表数据如下所示:
PS:上面是dbcp数据连接池,我们可以改成druid连接池如下,这里引用的是druid-1.1.3.jar
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
运行Main.java结果如下:
14:20:24.422 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited
14:20:24.632 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-2} inited
mySqlDataSource:{
CreateTime:"2018-12-23 14:20:23",
ActiveCount:0,
PoolingCount:5,
CreateCount:5,
DestroyCount:0,
CloseCount:0,
ConnectCount:0,
Connections:[
{ID:1207231495, ConnectTime:"2018-12-23 14:20:24", UseCount:0, LastActiveTime:"2018-12-23 14:20:24"},
{ID:756936249, ConnectTime:"2018-12-23 14:20:24", UseCount:0, LastActiveTime:"2018-12-23 14:20:24"},
{ID:1221981006, ConnectTime:"2018-12-23 14:20:24", UseCount:0, LastActiveTime:"2018-12-23 14:20:24"},
{ID:264394929, ConnectTime:"2018-12-23 14:20:24", UseCount:0, LastActiveTime:"2018-12-23 14:20:24"},
{ID:1878413714, ConnectTime:"2018-12-23 14:20:24", UseCount:0, LastActiveTime:"2018-12-23 14:20:24"}
]
}
title1
title2
title3
title4
test1
test2
test3
test4