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