springboot -- 使用jpa和hibernate的方式配置多数据源 ( postgresql -- druid连接池)(二) --- 实践版本

x33g5p2x  于2021-12-24 转载在 其他  
字(14.0k)|赞(0)|评价(0)|浏览(571)

参考文章:https://www.liangzl.com/get-article-detail-29242.html

pom文件配置

  1. <!--阿里druid-->
  2. <dependency>
  3. <groupId>com.alibaba</groupId>
  4. <artifactId>druid-spring-boot-starter</artifactId>
  5. <version>1.1.9</version>
  6. </dependency>
  7. <!--事务管理:原子性,一致性,隔离性,持久性-->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-jdbc</artifactId>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-data-jpa</artifactId>
  15. </dependency>
  16. <!--引入postgresql依赖-->
  17. <dependency>
  18. <groupId>org.postgresql</groupId>
  19. <artifactId>postgresql</artifactId>
  20. </dependency>

application.yml配置

  1. # postgresql 环境配置
  2. server:
  3. port: 18005
  4. max-http-header-size: 8192
  5. logging:
  6. level:
  7. root: info
  8. spring:
  9. datasource:
  10. url: jdbc:postgresql://10.101.15.59:5432/postgres
  11. username: root
  12. password: 123abc
  13. driverClassName: org.postgresql.Driver
  14. platform: postgres
  15. type: com.alibaba.druid.pool.DruidDataSource
  16. # type: org.apache.commons.dbcp2.BasicDataSource
  17. initialization-mode: always
  18. # ============================== druid ============================== #
  19. druid:
  20. #最大活跃数
  21. maxActive: 20
  22. #初始化数量
  23. initialSize: 1
  24. #最大连接等待超时时间
  25. maxWait: 60000
  26. #打开PSCache,并且指定每个连接PSCache的大小
  27. poolPreparedStatements: true
  28. maxPoolPreparedStatementPerConnectionSize: 20
  29. #通过connectionProperties属性来打开mergeSql功能;慢SQL记录
  30. #connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
  31. minIdle: 1
  32. timeBetweenEvictionRunsMillis: 60000
  33. minEvictableIdleTimeMillis: 300000
  34. validationQuery: select 1 from dual
  35. testWhileIdle: true
  36. testOnBorrow: false
  37. testOnReturn: false
  38. #配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
  39. filters: stat, wall, log4j
  40. # ============================= spring jpa 配置 ============================= #
  41. jpa:
  42. show_sql: true
  43. database-platform: org.hibernate.dialect.PostgreSQL9Dialect
  44. # database-platform: cn.luutqf.springboot.dialect.JsonbPostgresDialect
  45. hibernate:
  46. ddl-auto: update # none: 关闭hibernate的自动创建表结构的机制
  47. properties:
  48. hibernate:
  49. dialect: org.hibernate.dialect.PostgreSQLDialect
  50. hbm2ddl.auto: update
  51. jdbc.lob.non_contextual_creation: true
  52. format_sql: true
  53. temp:
  54. # 兼容SpringBoot2.X, 关闭 Hibernate尝试验证PostgreSQL的CLOB特性
  55. use_jdbc_metadata_defaults: false

工程目录结构

DataSourceConfig配置

  1. package org.fiend.config;
  2. import com.alibaba.druid.support.http.StatViewServlet;
  3. import com.alibaba.druid.support.http.WebStatFilter;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.boot.context.properties.ConfigurationProperties;
  6. import org.springframework.boot.jdbc.DataSourceBuilder;
  7. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  8. import org.springframework.boot.web.servlet.ServletRegistrationBean;
  9. import org.springframework.context.annotation.Bean;
  10. import org.springframework.context.annotation.Configuration;
  11. import org.springframework.context.annotation.Primary;
  12. import javax.sql.DataSource;
  13. /**
  14. * postgresql data source config
  15. * @author fiend 2018/12/5
  16. */
  17. @Configuration
  18. public class DataSourceConfig {
  19. @Primary
  20. @Bean(name="dataSource1")
  21. @ConfigurationProperties(prefix="spring.datasource")
  22. public DataSource dataSource() {
  23. return DataSourceBuilder.create().type(dataSourceType).build();
  24. }
  25. /**
  26. * 多数据源配置, 数据源二
  27. */
  28. @Bean(name="dataSource2")
  29. @ConfigurationProperties(prefix="spring.datasource")
  30. public DataSource dataSource2() {
  31. return DataSourceBuilder.create().type(dataSourceType).build();
  32. }
  33. @Value("${spring.datasource.type}")
  34. private Class<? extends DataSource> dataSourceType;
  35. /**
  36. * 配置监控服务器
  37. * @return 返回监控注册的servlet对象
  38. */
  39. @Bean
  40. @SuppressWarnings("unchecked")
  41. public ServletRegistrationBean statViewServlet() {
  42. ServletRegistrationBean servletRegistrationBean =
  43. new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
  44. // 添加IP白名单
  45. servletRegistrationBean.addInitParameter("allow", "192.168.25.125,127.0.0.1");
  46. // 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
  47. servletRegistrationBean.addInitParameter("deny", "192.168.25.123");
  48. // 添加控制台管理用户
  49. servletRegistrationBean.addInitParameter("loginUsername", "druid");
  50. servletRegistrationBean.addInitParameter("loginPassword", "123456");
  51. // 是否能够重置数据
  52. servletRegistrationBean.addInitParameter("resetEnable", "false");
  53. return servletRegistrationBean;
  54. }
  55. /**
  56. * 配置服务过滤器
  57. * @return 返回过滤器配置对象
  58. */
  59. @Bean
  60. @SuppressWarnings("unchecked")
  61. public FilterRegistrationBean statFilter() {
  62. FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean(new WebStatFilter());
  63. // 添加过滤规则
  64. filterRegistrationBean.addUrlPatterns("/*");
  65. // 忽略过滤格式
  66. filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*,");
  67. return filterRegistrationBean;
  68. }
  69. }

PrimaryConfig配置

PrimaryConfig使用dataSource1数据源

  1. package org.fiend.config;
  2. import org.springframework.beans.factory.annotation.Qualifier;
  3. import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
  4. import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
  5. import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.annotation.Primary;
  9. import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  10. import org.springframework.orm.jpa.JpaTransactionManager;
  11. import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
  12. import org.springframework.transaction.PlatformTransactionManager;
  13. import org.springframework.transaction.annotation.EnableTransactionManagement;
  14. import javax.annotation.Resource;
  15. import javax.persistence.EntityManager;
  16. import javax.sql.DataSource;
  17. import java.util.Map;
  18. import java.util.Objects;
  19. /**
  20. * @author fiend 2018/12/12
  21. */
  22. @Configuration
  23. @EnableTransactionManagement
  24. @EnableJpaRepositories(
  25. entityManagerFactoryRef = "entityManagerFactoryPrimary",
  26. transactionManagerRef = "transactionManagerPrimary",
  27. basePackages = {"org.fiend.repository.primary"} //设置Repository所在位置
  28. )
  29. public class PrimaryConfig {
  30. @Resource
  31. @Qualifier("dataSource1")
  32. private DataSource dataSource1;
  33. @Resource
  34. private JpaProperties jpaProperties;
  35. /**
  36. * 配置EntityManager实体
  37. * @return 实体管理器
  38. */
  39. @Primary
  40. @Bean(name="entityManagerPrimary")
  41. public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
  42. return Objects.requireNonNull(entityManagerFactoryPrimary(builder).getObject()).createEntityManager();
  43. }
  44. @Primary
  45. @Bean(name="transactionManagerPrimary")
  46. public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
  47. return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
  48. }
  49. /**
  50. * 设置实体类所在位置
  51. */
  52. @Primary
  53. @Bean(name="entityManagerFactoryPrimary")
  54. public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(
  55. EntityManagerFactoryBuilder builder) {
  56. return builder
  57. .dataSource(dataSource1)
  58. .packages("org.fiend.entity.primary") // 实体类所在位置
  59. .persistenceUnit("ds1PersistenceUnit") // datasource1 persistenceUnit
  60. .properties(getVendorProperties())
  61. .build();
  62. }
  63. /**
  64. * 这里其实不需要配置数据库的方言.
  65. * 像hibernate.hbm2ddl.auto 可以在这里配置. 我们已在application.yml中配置.
  66. */
  67. private Map<String, Object> getVendorProperties() {
  68. return jpaProperties.getHibernateProperties(new HibernateSettings());
  69. }
  70. }

SecondaryConfig配置

SecondaryConfig使用dataSource2数据源

  1. package org.fiend.config;
  2. import org.springframework.beans.factory.annotation.Qualifier;
  3. import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
  4. import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
  5. import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  9. import org.springframework.orm.jpa.JpaTransactionManager;
  10. import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
  11. import org.springframework.transaction.PlatformTransactionManager;
  12. import org.springframework.transaction.annotation.EnableTransactionManagement;
  13. import javax.annotation.Resource;
  14. import javax.persistence.EntityManager;
  15. import javax.sql.DataSource;
  16. import java.util.Map;
  17. import java.util.Objects;
  18. /**
  19. * @author fiend 2018/12/12
  20. */
  21. @Configuration
  22. @EnableTransactionManagement
  23. @EnableJpaRepositories(
  24. entityManagerFactoryRef = "entityManagerFactorySecondary",
  25. transactionManagerRef = "transactionManagerSecondary",
  26. basePackages = {"org.fiend.repository.secondary"} //设置Repository所在位置
  27. )
  28. public class SecondaryConfig {
  29. @Resource
  30. @Qualifier("dataSource2")
  31. private DataSource dataSource2;
  32. @Resource
  33. private JpaProperties jpaProperties;
  34. /**
  35. * 配置EntityManager实体
  36. * @return 实体管理器
  37. */
  38. @Bean(name="entityManagerSecondary")
  39. public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
  40. return Objects.requireNonNull(entityManagerFactorySecondary(builder).getObject()).createEntityManager();
  41. }
  42. @Bean(name="transactionManagerSecondary")
  43. public PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
  44. return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
  45. }
  46. /**
  47. * 设置实体类所在位置
  48. */
  49. @Bean(name="entityManagerFactorySecondary")
  50. public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(
  51. EntityManagerFactoryBuilder builder) {
  52. return builder
  53. .dataSource(dataSource2)
  54. .packages("org.fiend.entity.secondary") // 实体类所在位置
  55. .persistenceUnit("ds2PersistenceUnit") // datasource2 persistenceUnit
  56. .properties(getVendorProperties())
  57. .build();
  58. }
  59. /**
  60. * 这里其实不需要配置数据库的方言.
  61. * 像hibernate.hbm2ddl.auto 可以在这里配置. 我们已在application.yml中配置.
  62. */
  63. private Map<String, Object> getVendorProperties() {
  64. return jpaProperties.getHibernateProperties(new HibernateSettings());
  65. }
  66. }

Entity文件

这里只展示primary的entity文件

  1. package org.fiend.entity.primary;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.Id;
  5. import javax.persistence.Table;
  6. import java.io.Serializable;
  7. /**
  8. * @author fiend 2018/12/5
  9. */
  10. @Entity
  11. // catalog: 数据库名称, name: 表名
  12. @Table(catalog="primary1", name="user")
  13. public class UserPri implements Serializable { //序列化在Jpa需要
  14. // @Id是用来标识主键的,而@GeneratedValue则是用来指定主键策略的
  15. @Id
  16. @GeneratedValue
  17. private String name;
  18. // @Column(name = "count", nullable = false)
  19. private Integer count;
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. public Integer getCount() {
  27. return count;
  28. }
  29. public void setCount(Integer count) {
  30. this.count = count;
  31. }
  32. }

Repository文件

这里只展示primary的repository文件

  1. package org.fiend.repository.primary;
  2. import org.fiend.entity.primary.UserPri;
  3. import org.springframework.data.jpa.repository.JpaRepository;
  4. import org.springframework.data.jpa.repository.Modifying;
  5. import org.springframework.data.jpa.repository.Query;
  6. import org.springframework.data.repository.query.Param;
  7. import org.springframework.stereotype.Repository;
  8. import javax.transaction.Transactional;
  9. import java.util.List;
  10. /**
  11. * @author fiend 2018/12/10
  12. */
  13. @Repository
  14. public interface UserRepositoryPri extends JpaRepository<UserPri, String> {
  15. /**
  16. * 进行数据库操作, 可以通过自定义HQL来完成符合个性的其他操作
  17. * 通过@Query注解, 完成了HQL的书写, 其中“:name”与下方的@Param注解中参数保持一致。
  18. * HQL可使用Hibernate的SQL生成和缓存策略
  19. * HQL中一些关键字如 SELECT, FROM 和 WHERE等, 是不区分大小写的, 但是一些属性如表名和列名区分大小写
  20. */
  21. @Query(value = "SELECT u FROM UserPri u WHERE name=:name")
  22. UserPri findName(@Param("name") String name);
  23. /**
  24. * 使用SQL语句, nativeQuery为true代表使用SQL语言
  25. * 建议尽可能的使用HQL语句, 以避免数据库关于可移植性的麻烦, 且HQL可使用Hibernate的SQL生成和缓存策略。
  26. */
  27. @Query(value = "insert into User value(?,?,?)", nativeQuery = true)
  28. @Transactional
  29. @Modifying
  30. int countUserBy(@Param("id") Integer id, @Param("name") String name,
  31. @Param("password") String password);
  32. /**
  33. * 根据用户名查询
  34. */
  35. @Query("select t from UserPri t where t.name = :name")
  36. UserPri findByUserName(@Param("name") String name);
  37. /**
  38. * 查询全部
  39. */
  40. @Query("select t from UserPri t")
  41. List<UserPri> find();
  42. /**
  43. * 删除, 必须加入@Modifying和@Transactional
  44. */
  45. @Modifying
  46. @Transactional
  47. @Query("delete from UserPri u where u.id=:id")
  48. int deleteUserById(@Param("id") Integer id);
  49. @Modifying
  50. @Transactional
  51. @Query("update UserPri u set u.name = :name where u.id=:id")
  52. int queryUserById(@Param("id") Integer id, @Param("name") String name);
  53. }

Service文件

  1. package org.fiend.service;
  2. import com.alibaba.fastjson.JSONObject;
  3. import org.fiend.base.AbstractService;
  4. import org.fiend.entity.primary.UserPri;
  5. import org.fiend.entity.secondary.UserSec;
  6. import org.fiend.repository.primary.UserRepositoryPri;
  7. import org.fiend.repository.secondary.UserRepositorySec;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Service;
  12. import java.util.List;
  13. /**
  14. * @author Administrator
  15. */
  16. @Service
  17. public class HomeService extends AbstractService {
  18. Logger log = LoggerFactory.getLogger(getClass());
  19. @Autowired
  20. private UserRepositoryPri userRepositoryPri;
  21. @Autowired
  22. private UserRepositorySec userRepositorySec;
  23. public JSONObject getUserListPri() {
  24. JSONObject json = new JSONObject();
  25. List<UserPri> userList = userRepositoryPri.find();
  26. json.put("userList", userList);
  27. return json;
  28. }
  29. public JSONObject getUserListSec() {
  30. JSONObject json = new JSONObject();
  31. List<UserSec> userList = userRepositorySec.find();
  32. json.put("userList", userList);
  33. return json;
  34. }
  35. }

Controller文件

  1. package org.fiend.controller;
  2. import com.alibaba.fastjson.JSONObject;
  3. import org.fiend.base.AbstractController;
  4. import org.fiend.service.HomeService;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.ResponseBody;
  10. import javax.inject.Inject;
  11. import javax.inject.Named;
  12. /**
  13. * @author Administrator
  14. */
  15. @Controller
  16. @RequestMapping(value="home")
  17. public class HomeController extends AbstractController<HomeService> {
  18. Logger log=LoggerFactory.getLogger(this.getClass());
  19. @Override
  20. @Inject
  21. @Named("homeService")
  22. protected void setService(HomeService service) {
  23. this.service=service;
  24. }
  25. @RequestMapping(value="getUserListPri")
  26. @ResponseBody
  27. public JSONObject getUserListPri() {
  28. return service.getUserListPri();
  29. }
  30. @RequestMapping(value="getUserListSec")
  31. @ResponseBody
  32. public JSONObject getUserListSec() {
  33. return service.getUserListSec();
  34. }
  35. }

输出结果:

相关文章