zoukankan      html  css  js  c++  java
  • 七、SpringBoot整合持久化层,配置多数据源(SpringBoot系列)

    整合JDBCTemplate

    SpringBoot提供了JDBCTemplate,可以直接使用

    @Service
    public class UserService {
        @Autowired
        JdbcTemplate jdbcTemplate;
        public Integer addUser(User user) {
            return jdbcTemplate.update("insert into user (username,address) values (?,?);", user.getUsername(), user.getAddress());
        }
         public List<User> getAllUsers() {
             // 自定义 jdbcType转javaType的转换方式
            return jdbcTemplate.query("select * from user", new RowMapper<User>() {
                @Override
                public User mapRow(ResultSet resultSet, int i) throws SQLException {
                    User user = new User();
                    int id = resultSet.getInt("id");
                    String username = resultSet.getString("username");
                    String address = resultSet.getString("address");
                    user.setUsername(username);
                    user.setId(id);
                    user.setAddress(address);
                    return user;
                }
            });
        }
         public List<User> getAllUsers2() {
             // 转换成指定bean
            return jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<>(User.class));
        }
    
    }
    

    RowMapper的使用:https://www.jianshu.com/p/be60a81e2fe7

    JDBCTemplate 配置多数据源

    1. 配置
    # spring.datasource后跟上自定义name 
    # 该demo使用的DruidDataSource数据库连接池
    spring.datasource.one.url=jdbc:mysql://192.168.66.128:3306/javaboy
    spring.datasource.one.username=root
    spring.datasource.one.password=123
    spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
    
    spring.datasource.two.url=jdbc:mysql://192.168.66.128:3306/javaboy2
    spring.datasource.two.username=root
    spring.datasource.two.password=123
    spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
    
    1. 配置了多个数据源,需要手动加载

      @Configuration
      public class DataSourceConfig {
          @Bean
          @ConfigurationProperties(prefix = "spring.datasource.one")
          DataSource dsOne() {
              return DruidDataSourceBuilder.create().build();
          }
      
          @Bean
          @ConfigurationProperties(prefix = "spring.datasource.two")
          DataSource dsTwo() {
              return DruidDataSourceBuilder.create().build();
          }
      }
      
      
      1. JdbcTemplate需要手动指定一下加载的数据源,使用@Qualifiler指定要装配的组件的Id

        @Configuration
        public class JdbcTemplateConfig {
            @Bean
            JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource dsOne) {
                return new JdbcTemplate(dsOne);
            }
        
            @Bean
            JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource dsTwo) {
                return new JdbcTemplate(dsTwo);
            }
        }
        
        

        @AutoWired是byType的

        @Qualifier明确指定使用那个实现类,@Qualifier是byName的。

      2. 使用JdbcTemplate的时候需要注意注入的是针对哪个数据据源的

        @RunWith(SpringRunner.class)
        @SpringBootTest
        public class Jdbctemplate2ApplicationTests {
            // 两种指定注入的方式任选一种
            @Autowired
            @Qualifier("jdbcTemplateOne")
            JdbcTemplate jdbcTemplateOne;
            
            @Resource(name = "jdbcTemplateTwo")
            JdbcTemplate jdbcTemplateTwo;
            @Test
            public void contextLoads() {
                List<User> list1 = jdbcTemplateOne.query("select * from user", new BeanPropertyRowMapper<>(User.class));
                System.out.println(list1);
                List<User> list2 = jdbcTemplateTwo.query("select * from user", new BeanPropertyRowMapper<>(User.class));
                System.out.println(list2);
            }
        }
        

    整合Mybatis

    1. mapper注入 :

      1. 使用在Mapper上使用@Mapper注解

      2. 或者启动类使用@MapperScan(basePackage=path),整个包扫描

    2. 注意xml文件需要放到resorce才能访问,且和mapper目录一样

      • 如果不想用一样的目录,需要在application中配置mybatis.mapper-locations=classpath:path,例如:mybatis.mapper-locations=classpath:/mapper/*.xml
      • 如果不想放的话,需要在pom文件中配置
      <resoure>
           <!--将src/main/java也设置为静态目录-->
      	<directory>src/main/java</directory>
      	<includes>
              <!--表示此目录下所有以xml结尾的文件会在package时会当做资源文件打包(放在classpath下),其他文件会被忽略-->
      		<include>**/*.xml</inclued>
               <filtering>true</filtering>
      	</includes>
      </resource>
      <rosource> 
             <directory>src/main/resources</directory>
      </rosource>
      

      pom中resource的作用:https://blog.csdn.net/qq_44643051/article/details/108194448

    3. mybatis日志级别配置logging.level.org.javaboy.mybatis.mapper=debug

    Mybatis配置多数据源

    Mybatis多数据源:

    • 需要配置多个MybatisConfig:
      • 将SqlSessionFactoryBean加载不同的数据源
      • 扫描不同的Mpper
    1. 手动加载DateSource

      spring.datasource.one.username=root
      spring.datasource.one.password=123
      spring.datasource.one.url=jdbc:mysql://192.168.66.128:3306/javaboy
      spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
      
      spring.datasource.two.username=root
      spring.datasource.two.password=123
      spring.datasource.two.url=jdbc:mysql://192.168.66.128:3306/javaboy2
      spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
      
      @Configuration
      public class DataSourceConfig {
          @Bean
          @ConfigurationProperties(prefix = "spring.datasource.one")
          DataSource dsOne() {
              return DruidDataSourceBuilder.create().build();
          }
      
          @Bean
          @ConfigurationProperties(prefix = "spring.datasource.two")
          DataSource dsTwo() {
              return DruidDataSourceBuilder.create().build();
          }
      }
      
      
    2. 配置MybatisConfig,加载不同的数据源

      @Configuration
      @MapperScan(basePackages = "org.javaboy.mybatis2.mapper1",sqlSessionFactoryRef = "sqlSessionFactory1",sqlSessionTemplateRef = "sqlSessionTemplate1")
      public class MyBatisConfigOne {
          @Resource(name = "dsOne")
          DataSource dsOne;
      
          @Bean
          SqlSessionFactory sqlSessionFactory1() {
              SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
              try {
                  bean.setDataSource(dsOne);
                  return bean.getObject();
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return null;
          }
      
          @Bean
          SqlSessionTemplate sqlSessionTemplate1() {
              return new SqlSessionTemplate(sqlSessionFactory1());
          }
      }
      
      
      //同上配置一样,只是加载了不同的数据源
      @Configuration
      @MapperScan(basePackages = "org.javaboy.mybatis2.mapper2", sqlSessionFactoryRef = "sqlSessionFactory2", sqlSessionTemplateRef = "sqlSessionTemplate2")
      public class MyBatisConfigTwo {
          @Resource(name = "dsTwo")
          DataSource dsTwo;
      
          @Bean
          SqlSessionFactory sqlSessionFactory2() {
              SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
              try {
                  bean.setDataSource(dsTwo);
                  return bean.getObject();
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return null;
          }
      
          @Bean
          SqlSessionTemplate sqlSessionTemplate2() {
              return new SqlSessionTemplate(sqlSessionFactory2());
          }
      }
      
    3. code双份的mapper

      image-20210524110021619

    4. 使用的时候,调用不同的mapper就可以了

    整合Spring Data JPA

    1. 配置文件
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.username=root
    spring.datasource.password=123
    spring.datasource.url=jdbc:mysql://192.168.66.128:3306/javaboy?useUnicode=true&characterEncoding=UTF-8
    
    # 启用SQL语句的日志记录
    spring.jpa.show-sql=true
    spring.jpa.database=mysql
    spring.jpa.database-platform=mysql
    # 第一次启动根据实体类新建数据库表,之后随实体类变更修改数据库结构
    spring.jpa.hibernate.ddl-auto=update
    # 指定时mysql5.7的方言,这样新建的表的存储引擎才是innodb,不指定的话就是myisam
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
    

    spring.jpa.hibernate.ddl-auto配置:

    • create:每次启动新建表,之前的表和数据被删除
    • create-drop:和上面一样,多了一样,在应用关闭的时候,sessionFacorty关闭时,就把表删除
    • update: 第一次启动新建表,之后根据实体类变更,修改表结构
    • validate:验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值,运行程序会校验实体字段与数据库已有的表的字段类型是否相同,不同会报错
    1. 新建实体类

      // 标识是实体类, name为表名,不填默认为表类同名
      @Entity(name = "t_book") 
      public class Book {
          // jpa的实体类必须有id ,需要用@Id注解
          @Id
          // id生成
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          private Integer id;
          // 标识字段名,若类的属性和字段名不相同,可用@Column标识对应关系
           @Column(name = "name")
          private String name;
           @Column(name = "author")
          private String author;
          @Column(name = "create_time")
          private Instant createTime;
      }
      
    2. dao层: dao层继承JpaReposityory<实体类、id类型>

      public interface BookDao extends JpaRepository<Book, Integer> {
          // 方法命名规则查询
          Book findBookById(Integer id);
          List<Book> findBookByIdGreaterThan(Integer id);
          List<Book> findBookByIdLessThanOrNameContaining(Integer id, String name);
      
          //jpa的@Query()中默认识别的不是sql,是jpql(面对对象的查询语言),用nativeQuery标识,表示是可以直接执行的sql语言
          @Query(value = "select * from t_book where id=(select max(id) from t_book)", nativeQuery = true)
          Book getMaxIdBook();
      
          //	Jpa@Query()修改,参数占位符有两种写法:
      	//	1. ?1 ?2
      	//	2. 使用@Pararm注解 ,:参数1名称 :参数二名称
          
          //jpa自定义sql修改语句,需要加上`@Modifying`和`@Transcational`
          // 第一种占位符写法:1. ?1 ?2
          @Query(value = "insert into t_book(name,author) values(?1,?2)", nativeQuery = true)
          @Modifying
          @Transactional
          Integer addBook(String name, String author);
          
          // 第二种占位符写法:2. 使用@Pararm注解 ,:参数1名称 :参数二名称
          @Query(value = "insert into t_book(name,author) values(:name,:author)", nativeQuery = true)
          @Modifying
          @Transactional
          Integer addBook2(@Param("name") String name, @Param("author") String author);
      }
      
      

    Spring Data JPA配置多数据源

    1. 手动加载多数据库源,(和JDBCTemplate和mybatis配置多数据源不同的是,需要添加一个@Primary注解)

      @Configuration
      public class DataSourceConfig {
          @Bean
          @Primary // 存在多个实例时,优先使用
          @ConfigurationProperties(prefix = "spring.datasource.one")
          DataSource dsOne() {
              return DruidDataSourceBuilder.create().build();
          }
      
          @Bean
          @ConfigurationProperties(prefix = "spring.datasource.two")
          DataSource dsTwo() {
              return DruidDataSourceBuilder.create().build();
          }
      }
      
      
    2. 需要配置多个JpaCondig

      • LocalContainerEntityManagerFactoryBean指定不同数据源
      • 扫描不同dao包
    @Configuration
    @EnableJpaRepositories(basePackages = "org.javaboy.jpa2.dao1",entityManagerFactoryRef = "localContainerEntityManagerFactoryBean1",transactionManagerRef = "platformTransactionManager1")
    public class JpaConfig1 {
        @Autowired
        @Qualifier("dsOne")
        DataSource dsOne;
    
        @Autowired
        JpaProperties jpaProperties;
    
        @Bean
        @Primary // 存在多个实例时,优先使用
        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean1(EntityManagerFactoryBuilder builder) {
            return builder.dataSource(dsOne)
                    .properties(jpaProperties.getProperties())
                	// 配置单元(起个名字) 
                    .persistenceUnit("pu1")
                	// 扫描的实体类包
                    .packages("org.javaboy.jpa2.bean")
                    .build();
        }
    
        // 事务管理
        @Bean
        PlatformTransactionManager platformTransactionManager1(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(localContainerEntityManagerFactoryBean1(builder).getObject());
        }
    }
    
    
    @Configuration
    @EnableJpaRepositories(basePackages = "org.javaboy.jpa2.dao2",entityManagerFactoryRef = "localContainerEntityManagerFactoryBean2",transactionManagerRef = "platformTransactionManager2")
    public class JpaConfig2 {
        @Autowired
        @Qualifier("dsTwo")
        DataSource dsTwo;
    
        @Autowired
        JpaProperties jpaProperties;
    
        @Bean
        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean2(EntityManagerFactoryBuilder builder) {
            return builder.dataSource(dsTwo)
                    .properties(jpaProperties.getProperties())
                    .persistenceUnit("pu2")
                    .packages("org.javaboy.jpa2.bean")
                    .build();
        }
    
        @Bean
        PlatformTransactionManager platformTransactionManager2(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(localContainerEntityManagerFactoryBean2(builder).getObject());
        }
    }
    
    
  • 相关阅读:
    CentOS8 安装 Java JDK
    小程序问题汇总
    CSS实现侧边栏固定宽度,内容栏自适应
    垂直居中总结
    移动端Web App自适应布局探索
    学习指南
    插件集
    移动端滑动事件
    网站收藏
    js void运用
  • 原文地址:https://www.cnblogs.com/zhaoyuan72/p/14804192.html
Copyright © 2011-2022 走看看