spring boot 实现多数据源配置

@Qualifier 翻译:合格者。java

这个注解很重要。mysql

1.当咱们配置了两个service,实现同一个接口时,在Controller中,注入service对象时,能够经过该注解,声明注入的是哪一个service实现类。不然会spring启动会报错。web

2.当咱们配置多数据源时,该注解,也会起到注入指定的数据源的做用。spring

以下:sql

public interface UserService {
    public List<User> queryAll();
}

 

@Service("service1")
public class UserService1 implements UserService {
    public List<User> queryAll(){
        // 略
        return null;
    }
}

@Service("service2")
public class UserService2 implements UserService {
    public List<User> queryAll(){
        // 略
        return null;
    }
}

 

@Controller
@RequestMapping("/User")
public class UserController {
    
    @Autowired
    @Qualifier("service1")
    UserService userService1;
    
    @RequestMapping("queryAll.do")
    public List<User> test() {
       return userService1.queryAll();
    }
}

再来看看咱们关注的spring boot配置多数据源。apache

spring boot配置多数据源,大概分为三类,针对jdbc配置多数据源,针对JPA配置多数据源,还有针对mybatis配置多数据源。session

下面的例子是针对mybatis配置多数据源,并且mybatis能够基于注解或者映射关系配置来显示。mybatis

application.propertiesapp

#设置数据源
spring.datasource.test1.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
spring.datasource.test1.username=root
spring.datasource.test1.password=123456
spring.datasource.test1.driverClassName=com.mysql.jdbc.Driver

spring.datasource.test2.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
spring.datasource.test2.username=root
spring.datasource.test2.password=123456
spring.datasource.test2.driverClassName=com.mysql.jdbc.Driver

#设置服务端口号
server.port=82
#设置服务访问路径
server.servlet-path=/demo

#mybatis的配置
#mybatis.mapper-locations: classpath:mybatis/mapper/test02/*.xml
#mybatis.type-aliases-package: com.example.demo.model

增长datasource包,和datasource类ui

package com.example.demo.datasource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DataSourceTest1 {
	// 声明bean
	@Bean(name = "test1DataSource")
	// 指明读取的配置
	@ConfigurationProperties(prefix = "spring.datasource.test1")
	// 设置为主数据源
	@Primary
	/*
	 * 声明数据源配置
	 */
	public DataSource testDataSource() {
		return DataSourceBuilder.create().build();
	}

	@Bean(name = "test1SqlSessionFactory")
	@Primary
	/**
	 * 使用声明的数据源,建立sqlSession工厂
	 */
	public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		/*
		 * 当mybatis采用映射配置文件的方式时,指明该数据源须要是扫描的xml文件路径
		 */
		bean.setDataSource(dataSource);
		/*
		 * bean.setMapperLocations( new
		 * PathMatchingResourcePatternResolver().getResources(
		 * "classpath:mybatis/mapper/test1/*.xml"));
		 */
		return bean.getObject();
	}

	@Bean(name = "test1TransactionManager")
	@Primary
	/**
	 * 声明数据源有本身的事务管理
	 */
	public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

	@Bean(name = "test1SqlSessionTemplate")
	@Primary
	/**
	 * 声明SqlSessionTemplate由指定的SqlSession工厂建立
	 */
	public SqlSessionTemplate testSqlSessionTemplate(
			@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

}

注意:
1.多个数据源,必须有一个是主数据源,即主数据源须要加@Primary注解来声明。

2.若是mybatis是基于注解来实现的,那么在建立SqlSessionFactory的方法中,不须要设置

bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml")); 了

反之,若是但愿mybatis基于映射关系配置文件来实现,则须要在这里设置文件的扫描路径。

package com.example.demo.datasource;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DataSourceTest2 {
	// 声明bean
	@Bean(name = "test2DataSource")
	// 指明读取的配置
	@ConfigurationProperties(prefix = "spring.datasource.test2")
	/*
	 * 声明数据源配置
	 */
	public DataSource testDataSource() {
		return DataSourceBuilder.create().build();
	}

	@Bean(name = "test2SqlSessionFactory")
	/**
	 * 使用声明的数据源,建立sqlSession工厂
	 */
	public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		/*
		 * 当mybatis采用映射配置文件的方式时,指明该数据源须要是扫描的xml文件路径
		 */
		bean.setDataSource(dataSource);
		bean.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
		return bean.getObject();
	}

	@Bean(name = "test2TransactionManager")
	/**
	 * 声明数据源有本身的事务管理
	 */
	public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

	@Bean(name = "test2SqlSessionTemplate")
	/**
	 * 声明SqlSessionTemplate由指定的SqlSession工厂建立
	 */
	public SqlSessionTemplate testSqlSessionTemplate(
			@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

建立mapper

package com.example.demo.mapper.test1;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import com.example.demo.model.User;

public interface User1Mapper {
	@Select("select * from user")
	List<User> queryAll();

}

 

package com.example.demo.mapper.test2;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.example.demo.model.User;

public interface User2Mapper {
	List<User> queryAll();

	User queryByName(String name);

	void insertUser(User user);
}

注意:1.基于映射关系配置来实现的mapper,首先接口中定义的方法名称,必定要与mapper.xml里面的方法id一致,方法很少很多。并且mapper.xml中的namaspace必定要把路径写对,指向这个mapper接口。

2.mapper.xml文件一般放在resource文件夹下,且路径与datasource里面,建立SqlSessionFactory时,setMapperLocations()时的路径一致,否则扫描不到。

建立mapper.xml

<?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.example.demo.mapper.test2.User2Mapper">
	<resultMap id="User" type="com.example.demo.model.User">
		<id property="id" column="id" jdbcType="INTEGER" />
		<result property="name" column="name" jdbcType="NVARCHAR" />
		<result property="age" column="age" jdbcType="INTEGER" />
	</resultMap>
	<select id="queryAll" resultMap="User">
		SELECT
		ID,
		NAME,
		AGE
		FROM
		USER
	</select>
	<select id="queryByName" parameterType="java.lang.String"
		resultType="com.example.demo.model.User">
		SELECT
		ID,
		NAME,
		AGE
		FROM
		USER
		WHERE
		NAME = #{name}
	</select>
	<insert id="insertUser"
		parameterType="com.example.demo.model.User">
		INSERT INTO USER
		(id,name,age)
		values(#{id},#{name},#{age})
	</insert>
</mapper>

建立service

package com.example.demo.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.mapper.test1.User1Mapper;
import com.example.demo.mapper.test2.User2Mapper;
import com.example.demo.model.User;

@Service
public class UserService {
	@Autowired
	private User1Mapper user1Mapper;
	@Autowired
	private User2Mapper user2Mapper;

	public List<User> getAll() {
		return user1Mapper.queryAll();
	}

	public void add(User user) {
		user2Mapper.insertUser(user);
	}
}

这里的service注入了两个mapper对象,执行不一样的SQL方法。也能够建立两个service,每一个service只注入一个mapper对象,执行各自的方法。

建立User实体类

package com.example.demo.model;

public class User {
	private int id;
	private String name;
	private int age;

	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;
	}

}

建立Controller

package com.example.demo.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.model.User;
import com.example.demo.service.UserService;

@Controller
@RequestMapping("test")
// 还有RestController RestController = Controller + ResponseBody
public class TestController {

	@Autowired
	UserService userService;

	@GetMapping("/add")
	@ResponseBody
	public void add() {
		User user = new User();
		user.setId(6);
		user.setName("赵六");
		user.setAge(24);
		userService.add(user);
	}

	@RequestMapping(value = "/getAll", method = RequestMethod.GET)
	@ResponseBody
	public List<User> getAll() {
		return userService.getAll();
	}
}

建立启动类

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
//ComponentScan是spring的,用于扫描controller, service等spring注解。
@ComponentScan(basePackages = { "com.example.demo.controller", "com.example.demo.service",
		"com.example.demo.datasource" })
//MapperScan是spring整合mybatis的,专门用于扫描mybatis的mapper的
//@MapperScan(basePackages = { "com.example.demo.mapper.test01"})

//EnableJpaRepositories开启JPA注解
// @EnableJpaRepositories(basePackages = { "com.example.demo.repository" })
// @EntityScan(basePackages = { "com.example.demo.model" })

@EnableAutoConfiguration
public class Demo1Application {

	public static void main(String[] args) {
		SpringApplication.run(Demo1Application.class, args);
	}

}

启动类只须要扫描controller和service层的注解就好。

mybatis须要使用的注解@MapperScan已经在建立datasource的时候完成了。

相关文章
相关标签/搜索