最近在学习Spring boot 现在撸到多数据源这个部分 ,
由于我一直是面向百度编程的 所以下面的内容当然是我网上拿来 然后自己敲了下 验证 了下。
- 项目目录
- pom文件
<dependencies>
<!-- 前端模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- application.propries
#默认数据源
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#数据源1
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
#数据源2
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
- 启动主类
package com.learn.ling;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
//首先要将spring boot自带的DataSourceAutoConfiguration禁掉,
// 因为它会读取application.properties文件的spring.datasource.*属性并自动配置单数据源
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {
public static void main( String[] args ) {
SpringApplication.run(Application.class, args);
}
}
- 数据原配置-DataSourceConfig
package com.learn.ling.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* 从Spring3.0,@Configuration用于定义配置类,
* 可替换xml配置文件,
* 被注解的类内部包含有一个或多个被@Bean注解的方法,
* 这些方法将会被AnnotationConfigApplicationContext
* 或AnnotationConfigWebApplicationContext类进行扫描,
* 并用于构建bean定义,初始化Spring容器
*/
@Configuration
public class DataSourceConfig {
//@primary默认数据源
@Primary
@Bean(name = "primaryDataSource")
//指定数据读取配置的前缀
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource(){
return DataSourceBuilder.create().build() ;
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource(){
return DataSourceBuilder.create().build() ;
}
}
- 数据原配置-MybatisPrimaryConfig
package com.learn.ling.config;
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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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 javax.sql.DataSource;
/**
* 数据源1的配置
*/
@Configuration
@MapperScan(basePackages = {"com.learn.ling.mapper.primary"}, sqlSessionFactoryRef = "sqlSessionFactoryPrimary")
public class MybatisPrimaryConfig {
@Autowired
/**
* Spring的Bean注入配置注解,该注解指定注入的Bean的名称,
* Spring框架使用byName方式寻找合格的bean,
* 这样就消除了byType方式产生的歧义
*/
@Qualifier("primaryDataSource")
private DataSource primaryDataSource ;
@Bean
@Primary //默认SqlSessionFactory
public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean() ;
factoryBean.setDataSource(primaryDataSource);//设置数据源
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:primaryMybatis/*Mapper.xml"));
return factoryBean.getObject() ;
}
@Bean
public SqlSessionTemplate sqlSessionTemplatePrimary() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactoryPrimary()) ;
return template ;
}
}
- 数据原配置-MybatisSecondaryConfig
package com.learn.ling.config;
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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* 数据源1的配置
*/
@Configuration
//指定com.learn.ling.mapper.secondary下的mapper使用当前数据源
@MapperScan(basePackages = {"com.learn.ling.mapper.secondary"}, sqlSessionFactoryRef = "sqlSessionFactorySecondary")
public class MybatisSecondaryConfig {
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource ;
@Bean
public SqlSessionFactory sqlSessionFactorySecondary() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean() ;
factoryBean.setDataSource(secondaryDataSource);//设置数据源
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:secondaryMybatis/*Mapper.xml"));
return factoryBean.getObject() ;
}
@Bean
public SqlSessionTemplate sqlSessionTemplateSecondary() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactorySecondary()) ;
return template ;
}
}
上面就是数据源配置部分了,不闲我整的麻烦的 可以继续看看下面的测试部分
- 创建数据库实体
两个数据库,整一样表结构就好了方便测试嘛
第一个
package com.learn.ling.domain.primary;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserPrimary {
private Long id ;
private String name ;
private Integer age ;
}
第二个
package com.learn.ling.domain.secondary;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserSecondary {
private Long id ;
private String name ;
private Integer age ;
}
- 对应的Mapper
第一个
package com.learn.ling.mapper.primary;
import com.learn.ling.domain.primary.UserPrimary;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
//@Mapper
public interface UserPrimaryMapper {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
UserPrimary findByName( @Param("name") String name );
int update( @Param ("id") Long id , @Param("name") String name,@Param("age") Integer age) ;
}
第二个 这个整的比较多 就是试下mybatis的一些用法 请自动忽略一些没有的方法
package com.learn.ling.mapper.secondary;
import com.learn.ling.domain.secondary.UserSecondary;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
//@Mapper
public interface UserSecondaryMapper {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
UserSecondary findByName( @Param("name") String name );
/**
* @param name
* @param age
* @return
* @Param中定义的name对应了SQL中的#{name},age对应了SQL中的#{age}。
*/
@Insert("INSERT INTO USER(NAME,AGE) VALUES(#{name},#{age})")
int insert( @Param("name") String name, @Param("age") Integer age );
/**
* 如下代码,通过Map对象来作为传递参数的容器:
*
* @param map
* @return
*/
@Insert("INSERT INTO USER(NAME,AGE) VALUES(#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER})")
int insertByMap( Map<String, Object> map );
/* 使用对象
除了Map对象,我们也可直接使用普通的Java对象来作为查询条件的传参,比如我们可以直接使用User对象:
这样语句中的#{name}、#{age}就分别对应了User对象中的name和age属性。
*/
@Insert("INSERT INTO USER(NAME,AGE) VALUE(#{name},#{age})")
int insertByUser( UserSecondary user );
//修改
@Update("update user set age=#{age} where name=#{name}")
void updateByIterface( UserSecondary user );
//删除
@Delete("delete from user where id =#{id}")
void delete( Long id );
//返回结果的绑定
/**
* 在上面代码中,@Result中的property属性对应User对象中的成员名,
* column对应SELECT出的字段名。
* 在该配置中故意没有查出id属性,
* 只对User对应中的name和age对象做了映射配置,
* 这样可以通过下面的单元测试来验证查出的id为null,而其他属性不为null:
*
* @return
*/
@Results({
@Result(property = "name", column = "name"),
@Result(property = "age", column = "age")
})
@Select("select name,age from user ;")
List<UserSecondary> findAll();
/**
* 通过xml文件形式
* @param id
* @param name
* @param age
* @return
*/
int update( @Param ("id") Long id , @Param("name") String name,@Param("age") Integer age) ;
}
- 然后是service 就只写了secondary
package com.learn.ling.service.secondary;
import com.learn.ling.domain.secondary.UserSecondary;
import com.learn.ling.mapper.secondary.UserSecondaryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class UserSecondaryService {
@Autowired
private UserSecondaryMapper userSecondaryMapper ;
public UserSecondary findByName( String name ){
return userSecondaryMapper.findByName(name) ;
}
/**
* @param name
* @param age
* @return
* @Param中定义的name对应了SQL中的#{name},age对应了SQL中的#{age}。
*/
// @Insert("INSERT INTO USER(NAME,AGE) VALUES(#{name},#{age})")
public int insert(String name, Integer age ){
return userSecondaryMapper.insert(name, age) ;
}
/**
* 如下代码,通过Map对象来作为传递参数的容器:
*
* @param map
* @return
*/
// @Insert("INSERT INTO USER(NAME,AGE) VALUES(#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER})")
public int insertByMap( Map<String, Object> map ){
return userSecondaryMapper.insertByMap(map) ;
}
/* 使用对象
除了Map对象,我们也可直接使用普通的Java对象来作为查询条件的传参,比如我们可以直接使用User对象:
这样语句中的#{name}、#{age}就分别对应了User对象中的name和age属性。
*/
// @Insert("INSERT INTO USER(NAME,AGE) VALUE(#{name},#{age})")
public int insertByUser( UserSecondary user ){
return userSecondaryMapper.insertByUser(user) ;
}
//修改
// @Update("update user set age=#{age} where name=#{name}")
public void updateByIterface( UserSecondary user ){
userSecondaryMapper.updateByIterface(user);
}
//删除
// @Delete("delete from user where id =#{id}")
public void delete( Long id ){
userSecondaryMapper.delete(id);
}
//返回结果的绑定
/**
* 在上面代码中,@Result中的property属性对应User对象中的成员名,
* column对应SELECT出的字段名。
* 在该配置中故意没有查出id属性,
* 只对User对应中的name和age对象做了映射配置,
* 这样可以通过下面的单元测试来验证查出的id为null,而其他属性不为null:
*
* @return
*/
// @Results({
// @Result(property = "name", column = "name"),
// @Result(property = "age", column = "age")
// })
// @Select("select name,age from user ;")
public List<UserSecondary> findAll(){
return userSecondaryMapper.findAll() ;
}
/**
* 通过xml文件形式
* @param id
* @param name
* @param age
* @return
*/
public int update( Long id , String name,Integer age) {
return userSecondaryMapper.update(id, name, age) ;
}
}
- 再来mybatis的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.learn.ling.mapper.primary.UserPrimaryMapper">
<!-- 修改 -->
<update id="update">
UPDATE user set name=#{name} , age=#{age} WHERE id=#{id}
</update>
</mapper>
第二个
<?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.learn.ling.mapper.primary.UserPrimaryMapper">
<!-- 修改 -->
<update id="update">
UPDATE user set name=#{name} , age=#{age} WHERE id=#{id}
</update>
</mapper>
- 都整好了 那来看下测试方法吧
package com.learn.ling;
import com.learn.ling.domain.primary.UserPrimary;
import com.learn.ling.mapper.primary.UserPrimaryMapper;
import com.learn.ling.service.secondary.UserSecondaryService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
// @Test
// public void contextLoads() {
// }
@Autowired
private UserPrimaryMapper userPrimaryMapper ;
@Autowired
private UserSecondaryService userSecondaryService ;
// private UserSecondaryMapper userSecondaryMapper ;
@Test
public void testPrimary(){
userPrimaryMapper.update(1l,"aaa",188) ;
UserPrimary userPrimary = userPrimaryMapper.findByName("aaa") ;
System.out.println(userPrimary);
}
@Test
public void testSecondary(){
userSecondaryService.update(1l,"ccc",18) ;
userSecondaryService.insert("zhang",1);
userSecondaryService.insert("er",1);
userSecondaryService.insert("gou",1);
userSecondaryService.insert("wang",1);
System.out.println(userSecondaryService.findAll());
}
}
搞的有点麻烦 比较详细 因为我自己就是那个在网上看了啥东西 就恨不得整下来就能跑的通的 所以。。。