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