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的時候完成了。

相關文章
相關標籤/搜索