同一个项目有时会涉及到多个数据库,这时我们就要配置多个数据源。配置多数据源的常见情况有以下两种:
1)同一个项目中涉及两个或多个业务数据库,它们之间相互独立,这种情况也可以作为两个或多个项目来开发
2)两个或多个数据库之间是主从关系,主库负责写,从库负责读
多数据源的配置下面我们通过一个示例来说明多数据源的配置
1、配置文件配置
在配置文件application-dev.yml中配置我们需要链接的数据库:blog和user
spring: datasource: blog: jdbc-url: jdbc:mysql://localhost:3306/blog username: root password: test driver-class-name: com.mysql.cj.jdbc.Driver user: jdbc-url: jdbc:mysql://localhost:3306/user username: root password: test driver-class-name: com.mysql.cj.jdbc.Driver
注意:
1)我们在spring.datasource之后多设置了一个数据源名称blog和user来区分不同的数据源配置
2)如果报下面错误,则把url改为jdbc-url即可
nested exception is java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
3)com.mysql.jdbc.Driver 与 com.mysql.cj.jdbc.Driver 的区别
com.mysql.jdbc.Driver 是 mysql-connector-java 5中的
com.mysql.cj.jdbc.Driver 是 mysql-connector-java 6中的
2、数据源配置
配置文件配置好之后,我们创建两个配置类来加载配置信息,初始化数据源
blog的配置类:
@Configuration @MapperScan(basePackages = "com.tn666.demo.dao.blog", sqlSessionTemplateRef = "blogSqlSessionTemplate") public class DataSourceBlogConfig { @Primary @Bean(name = "blogDataSource") @ConfigurationProperties(prefix = "spring.datasource.blog") public DataSource blogDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "blogSqlSessionFactory") public SqlSessionFactory blogSqlSessionFactory(@Qualifier("blogDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "blogSqlSessionTemplate") public SqlSessionTemplate blogSqlSessionTemplate(@Qualifier("blogSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
User的配置类:
@Configuration @MapperScan(basePackages = "com.tn666.demo.dao.user", sqlSessionTemplateRef = "userSqlSessionTemplate") public class DataSourceUserConfig { @Bean(name = "userDataSource") @ConfigurationProperties(prefix = "spring.datasource.user") public DataSource userDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "userSqlSessionFactory") public SqlSessionFactory userSqlSessionFactory(@Qualifier("userDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "userSqlSessionTemplate") public SqlSessionTemplate userSqlSessionTemplate(@Qualifier("userSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
注意:
1)类注解@MapperScan的属性basePackages配置的为对应DA层dao的位置
2)@Primary注解指定了主数据源
3、实体类和dao层配置
在blog数据库中,创建一个article表,在user数据库中创建一个user_info表,然后创建它们的实体类和dao层
创建article和user_info的实体类:
public class ArticlePo { private Integer id; private String articleId; private String title; // get、set... } public class UserInfoPo { private Integer id; private String userId; private String name; // get、set... }
创建article和user_info的dao层:
@Repository public interface ArticleDao { @Select("select * from article where article_id = #{articleId}") @Results({@Result(column = "article_id", property = "articleId")}) ArticlePo get(@Param("articleId") String articleId); // 给article赋值自增主键id @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") @Insert("insert into article(article_id, title) values(#{article.articleId}, #{article.title})") int insert(@Param("article") ArticlePo articlePo); } @Repository public interface UserInfoDao { @Select("select * from user_info where user_id=#{userId}") @Results({@Result(column = "user_id", property = "userId")}) UserInfoPo get(@Param("userId") String userId); @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id") @Insert("insert into user_info(user_id, name) values(#{userInfo.userId}, #{userInfo.name})") int insert(@Param("userInfo") UserInfoPo userInfoPo); }
4、测试验证
编写ArticleController和UserInfoController:
@RestController @RequestMapping("/article") public class ArticleController { @Resource private ArticleDao articleDao; @GetMapping(value = "/get") public ArticlePo get(@RequestParam("articleId") String articleId) { ArticlePo articlePo = articleDao.get(articleId); return articlePo; } @PostMapping(value = "/insert") public Boolean insert(@RequestBody ArticlePo articlePo) { articleDao.insert(articlePo); Boolean res = false; if (articlePo.getId() > 0) { res = true; } return res; } } @RestController @RequestMapping("/user") public class UserInfoController { @Resource private UserInfoDao userInfoDao; @GetMapping(value = "/get") public UserInfoPo get(@RequestParam("userId") String userId) { UserInfoPo res = userInfoDao.get(userId); return res; } @PostMapping(value = "/insert") public Boolean insert(@RequestBody UserInfoPo userInfoPo) { userInfoDao.insert(userInfoPo); Boolean res = false; if (userInfoPo.getId() > 0) { res = true; } return res; } }
业务逻辑复杂时,Controller和Mapper中间会有Service层来处理业务逻辑,现在我们就简单的测试一下多数据源,所以直接使用Controller调用Mapper了
更多内容,请关注公众号图南随笔:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)