美文网首页
Springboot与springdata JPA

Springboot与springdata JPA

作者: 靈08_1024 | 来源:发表于2017-11-01 10:31 被阅读133次

    springboot的版本为1.4.3.RELEASE

    基本的配置

    yaml配置文件:

    spring:
      datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false
          username: root
          password: root
    

    仓库的代码:

    public interface HospitalResponsity extends JpaRepository<Hospital, Integer> {
    }
    

    其中,Hospital是类名,Integer是主键类型。
    然后注入到service中就可以使用了。

    基本的语法

    对于其方法名的定义,遵循驼峰命令,有一些基本的语法。
    如find是查询、save是保存、delete是删除、insert是添加。
    And是和、Or是或者、Containing是包含,相当于前后%的like。

    双数据源

    因项目需要读写分离,所以采用双数据源进行处理。
    yaml文件配置:

    spring:
    #数据源的配置#
      datasource:
      #主读副写
          primary:
            driver-class-name: com.mysql.jdbc.Driver
            url: jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false
            username: root
            password: root
          secondary:
            driver-class-name: com.mysql.jdbc.Driver
            url: jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false
            username: root
            password: root
    # 如果需要h2数据库的
    #        url:  jdbc:h2:D:/tools/H2/test
    #        username: sa
    #        password: sa
    

    Java的config文件配置(boot版本1.4.3):
    总配置源DataSourceConfig.java文件:

    
    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 javax.sql.DataSource;
    
    /**
     * Created by lingbao on 2017/10/30.
     *
     * @author lingbao
     * @Description
     * @Modify
     */
    @Configuration
    public class DataSourceConfig {
    
        @Bean(name = "primaryDataSource")
        @Qualifier("primaryDataSource")
        @ConfigurationProperties(prefix="spring.datasource.primary")
        public DataSource primaryDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "secondaryDataSource")
        @Qualifier("secondaryDataSource")
        @Primary
        @ConfigurationProperties(prefix="spring.datasource.secondary")
        public DataSource secondaryDataSource() {
            return DataSourceBuilder.create().build();
        }
    
    }
    
    

    主数据源PrimaryConfig.java

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
    import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import javax.persistence.EntityManager;
    import javax.sql.DataSource;
    import java.util.Map;
    
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef="entityManagerFactoryPrimary",
            transactionManagerRef="transactionManagerPrimary",
            basePackages= {"com.kindo.vine.*.repository.read"}) //设置该数据源要监控的Repository所在位置
    public class PrimaryConfig {
    
        @Autowired @Qualifier("primaryDataSource")
        private DataSource primaryDataSource;
    
        @Primary
        @Bean(name = "entityManagerPrimary")
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
        }
    
        @Primary
        @Bean(name = "entityManagerFactoryPrimary")
        public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
            return builder
                    .dataSource(primaryDataSource)
                    .properties(getVendorProperties(primaryDataSource))
                    .packages("com.kindo.vine.*.entity") //设置实体类所在位置
                    .persistenceUnit("primaryPersistenceUnit")
                    .build();
        }
    
        @Autowired
        private JpaProperties jpaProperties;
    
        private Map<String, String> getVendorProperties(DataSource dataSource) {
            return jpaProperties.getHibernateProperties(dataSource);
        }
    
        @Primary
        @Bean(name = "transactionManagerPrimary")
        public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
        }
    
    }
    

    Java的config文件配置(boot版本2.0.0.BUILD-SNAPSHOT):

    
    import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
    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 javax.sql.DataSource;
    
    /**
     * Created by lingbao on 2017/11/28.
     *
     * @author lingbao
     * @Description
     * @Modify
     */
    @Configuration
    public class DataSourceConfig {
        @Bean
        @Primary
        @ConfigurationProperties("spring.datasource.primary")
        public DataSourceProperties primaryDataSourceProperties() {
            return new DataSourceProperties();
        }
    
        @Bean
        @Primary
        @ConfigurationProperties("spring.datasource.primary")
        public DataSource primaryDataSource() {
            return primaryDataSourceProperties().initializeDataSourceBuilder().build();
        }
    
        @Bean
        @ConfigurationProperties("spring.datasource.secondary")
        public DataSourceProperties secondaryDataSourceProperties() {
            return new DataSourceProperties();
        }
    
        @Bean
        @ConfigurationProperties("spring.datasource.secondary")
        public DataSource secondaryDataSource() {
            return secondaryDataSourceProperties().initializeDataSourceBuilder().build();
        }
    }
    
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import javax.persistence.EntityManager;
    import javax.sql.DataSource;
    
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef="entityManagerFactoryPrimary",
            transactionManagerRef="transactionManagerPrimary",
            basePackages= {"com.kindo.lily.business.*.repository.write"}) //设置Repository所在位置
    public class PrimaryConfig {
    
        @Autowired
        @Qualifier("primaryDataSource")
        private DataSource primaryDataSource;
    
        @Primary
        @Bean(name = "entityManagerPrimary")
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
        }
    
        @Primary
        @Bean(name = "entityManagerFactoryPrimary")
        public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
            return builder
                    .dataSource(primaryDataSource)
                    .packages("com.kindo.lily.business.*.entity") //设置实体类所在位置
                    .persistenceUnit("primaryPersistenceUnit")
                    .build();
        }
    
        @Primary
        @Bean(name = "transactionManagerPrimary")
        public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
        }
    
    }
    

    从数据源同理,primary变成secondary就OK,去掉@Primary即可。此处略过。

    在Service层需要注入两个数据源,然后根据需要使用指定的数据源。


    DSL的使用:
    使用QueryDslPredicateExecutor接口来实现:

    public interface UserRespository extends JpaRepository<User,Long>, JpaSpecificationExecutor {
    //根据JPA的语法写出的查询
        List<Dict> findAllByName(String name);
    
    //以下两种方法等效
    @Query(nativeQuery = true,value = "SELECT * FROM test_dict t1 WHERE " +
                "t1.id IN ( SELECT pid FROM test_dict t WHERE t.name LIKE concat('%',?1,'%'))" +
                "OR t1.id IN (SELECT id FROM test_dict t WHERE t.name LIKE concat('%',?1,'%'))")
        List<Dict> findAllByName1(String name);
    
        @Query("SELECT t1 FROM Dict t1 WHERE " +
                "t1.id IN ( SELECT pid FROM Dict t WHERE t.name like CONCAT('%',:name,'%'))" +
                "OR t1.id IN (SELECT id FROM Dict t WHERE t.name LIKE CONCAT('%',:name,'%'))")
        List<Dict> findAllByName2(@Param("name") String name);
    }
    

    Tips:JPA上写SQL的like的值,要用concat来拼接的,不能直接用单引号或者双引号等。

    单实体模糊查询:

    //下面的实现功能为模糊查询userName,确定查询age,定值条件state,最后id倒序查询分页。
    
    public Page<User> queryAll(String userName, String age, Pageable pageable) throws CommonException {
    
            Specification querySpecifi = (root, query, cb) -> {
                Predicate predicate = cb.equal(root.get("state"), "0");
                if (null != name) {
                    //root.get("userName")表达式,userName为实体中的字段名称。
                    //如果用户名传空字串的话,%+""+%表示查询全部。
                    //如果用户名传带空格的空字串的话,%+" "+%表示用户的意愿是查询带"空格"的全部。
                    predicate = cb.and(cb.like(root.get("userName"), "%" + name + "%"));
                }
    
                if (StringUtils.isNotBlank(age)) {
                    predicate = cb.and(cb.equal(root.get("age"), age));
                }
                query.orderBy(cb.desc(root.get("id").as(Integer.class)));
                return predicate;
            };
            //返回SpringJPA里的page类型
            Page page = medicineReadRepository.findAll(querySpecifi, pageable);
    
            return page;
        }
    

    注意,在多表关联的实体中,必须引入相关的实体类(以集合或实体类对象的方式),并标注@OneToMany等注解。

    源码:https://github.com/lingbao08/springboot-example.git
    注意源码为后来补充,boot版本为2.0.1版本。

    相关文章

      网友评论

          本文标题:Springboot与springdata JPA

          本文链接:https://www.haomeiwen.com/subject/oztxjxtx.html