SpringBoot之Jpa 多數據源

前言:JPA全稱Java Persistence API.JPA經過JDK 5.0註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中,在Spring 2.0.1中,正式提供對JPA的支持,這也促成了JPA的發展,要知道JPA的好處在於能夠分離於容器運行,變得更加的簡潔。以前上一家公司就是用的jpa,感受很簡單,特別是註解的實現徹底解決了xml配置的繁瑣,這個案例只是一個超級簡單的demo,若是須要分頁和一對多關聯關係須要本身查閱一下其餘資料,反正我是不推薦使用join 創建表關聯關係。java

1 .導入maven依賴mysql

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
 <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <scope>runtime</scope>
 </dependency>

2.配置數據庫鏈接屬性spring

spring.datasource.url=jdbc:mysql:///test?useUnicode=true&characterEncoding=utf8&autoReconnect=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driverClassName=com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database=MYSQL
# Show or not log for each sql query
spring.jpa.show-sql=true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto=update
# Naming strategy
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

以上配置就是hibernate的相關配置sql

3.建立實體類數據庫

@Entity
@Table(name = "good")
public class Good {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column
    private String goodName;
    @Column
    private Integer number;
}

@Table註解的name是數據庫的表名maven

@Id 聲明id爲主鍵ide

@GeneratedValue 爲主鍵生成的規則spring-boot

@Column 設置該屬性爲字段  能夠用name指定名length指定長度測試

org.hibernate.cfg.ImprovedNamingStrategy 會自動 映射屬性和字段名(goodName ==> good_name) 通常沒有特殊狀況 一致就好了。ui

4.建立Dao數據訪問層

@Repository
public interface GoodDao extends JpaRepository<Good, Serializable> {
     Good findByGoodName(String goodName);
}

 默認的 經常使用方法都有了  save(保存更新)  findAll  delete findOne.....

若是須要find某個屬性的話 只須要findByGoodName  屬性名首字母大寫就能夠了,須要實現這個接口 

若是須要自定義sql的話 ,也是能夠加@Query註解來自定義

@Query(value = "select  id from User where name=:name",nativeQuery = true)
public  Integer  getId(String name);

5.測試就能夠了

Good good = goodDao.getOne(1);

6.分頁加排序

Sort sort = new Sort(Sort.Direction.ASC,"name");
        Pageable pageable = new PageRequest(0, 20,sort);
        Page<User> page = dao.findAll(pageable);
        List<User> users = page.getContent();
        System.out.println("一共多少條:" + page.getTotalElements());//一共多少條
        System.out.println("一共多少頁:" + page.getTotalPages());//一共多少頁
        System.out.println("開始位置:" + page.getNumber());//開始位置
        System.out.println("顯示多少行" + page.getSize());//顯示多少行
        System.out.println(page.getSort());

7.多數據源

7.1 配置兩個數據庫的鏈接用戶名密碼

datasource.primary.url=jdbc:mysql://12.12.12.12/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true
datasource.primary.username=root
datasource.primary.password=root
datasource.primary.driverClassName=com.mysql.jdbc.Driver

datasource.secondary.url=jdbc:mysql://11.11.11.11/test_db?useUnicode=true&characterEncoding=utf8&autoReconnect=true
datasource.secondary.username=root
datasource.secondary.password=root
datasource.secondary.driverClassName=com.mysql.jdbc.Driver

7.2  配置兩個DatasourceBean

@Configuration
public class DataSourceConfiguration {
    @Bean(name = "primaryDataSource")
    @Primary
    @Qualifier("primaryDataSource")
    @ConfigurationProperties(prefix = "datasource.primary")
    public DataSource primaryDataSource() {
        System.out.println("-------------------- primaryDataSource初始化 ---------------------");
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix = "datasource.secondary")
    public DataSource secondaryDataSource() {
        System.out.println("-------------------- secondaryDataSource初始化---------------------");
        return DataSourceBuilder.create().build();
    }

7.3  分開配置 EntityManager以及JpaProperties

package com.wangnian.repositoryConfig;

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.wangnian.model1"})//設置dao(repo)所在位置
public class RepositoryPrimaryConfig {
    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDS;

    @Bean(name = "entityManagerPrimary")
    @Primary
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Bean(name = "entityManagerFactoryPrimary")
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(primaryDS)
                .properties(getVendorProperties(primaryDS))
                .packages("com.wangnian.model1") //設置實體類所在位置
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    private Map<String, String> getVendorProperties(DataSource dataSource) {
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Bean(name = "transactionManagerPrimary")
    @Primary
    PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }

}

7.4 使用接口的方式或者使EntityManager測試

/**
 * Created by http://my.oschina.net/wangnian on 2016/10/26.
 */
@Repository
public interface Dao1 extends JpaRepository<User, Serializable> {
}

 

8.使用EntityManager 返回 MAP

query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

上面我設置了自動建立表 update,千萬不要用create,不然會刪點數據重建。

 

9.分頁計算

    第1頁顯示10行   limit 計算公式  (page-1)*count  

   10條數據顯示10行有多少頁    計算公式  (total-1)/count+1 

10.封裝原生sql方法

package com.example;

import java.util.List;
import java.util.Map;

/**
 * Created by wangnian on 2017/3/22.
 */
public interface BaseDao {
    /**
     * 增刪改
     *
     * @param sql        自定義sql語句
     * @param parameters 參數<:key,value>
     * @return 執行條數
     */
    int executeUpdate(String sql, Map<String, Object> parameters);

    /**
     * 查詢
     *
     * @param sql        自定義sql語句
     * @param parameters 參數<:key,value>
     * @param page       第幾頁
     * @param pageSize   顯示多少行
     * @return 集合 Map<列名,值>
     */
    List<Map<String, Object>> getList(String sql, Map<String, Object> parameters, Integer page, Integer pageSize);


    /**
     * 查詢sql的總條數
     *
     * @param sql        自定義sql語句
     * @param parameters 參數<:key,value>
     * @param page       第幾頁
     * @param pageSize   顯示多少行
     * @return 總條數 total,當前第幾頁 pageSize,總共多少頁 sumPage,顯示多少行 count
     */
    Map<String, Object> getListTotal(String sql, Map<String, Object> parameters, Integer page, Integer pageSize);

}
package com.example;

import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wangnian on 2017/3/22.
 */
@Repository
public class BaseDaoImpl implements BaseDao {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseDaoImpl.class);

    @Autowired(required = false)
    private EntityManager entityManager;

    @Override
    @Transactional
    public int executeUpdate(String sql, Map<String, Object> parameters) {
        long startTime = System.currentTimeMillis();
        Query query = entityManager.createNativeQuery(sql);
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        int updateCount = query.executeUpdate();
        LOGGER.info("ExecuteUpdate ExecuteSQL Time:{}ms UpdateCount:{} Sql:{}  {}", System.currentTimeMillis() - startTime, updateCount, sql, parameters);
        return updateCount;
    }

    @Override
    public List<Map<String, Object>> getList(String sql, Map<String, Object> parameters, Integer page, Integer pageSize) {
        long startTime = System.currentTimeMillis();
        Query query = entityManager.createNativeQuery(sql);
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        Integer fistResult = (page - 1) * pageSize;
        query.setFirstResult(fistResult);
        query.setMaxResults(pageSize);
        List<Map<String, Object>> list = query.getResultList();
        LOGGER.info("GetList ExecuteSQL Time:{}ms ResultSize:{} Sql:{} limit {} {}  {} ", System.currentTimeMillis() - startTime, list.size(), sql, fistResult, pageSize, parameters);
        return list;
    }

    @Override
    public Map<String, Object> getListTotal(String sql, Map<String, Object> parameters, Integer page, Integer pageSize) {
        long startTime = System.currentTimeMillis();
        Query query = entityManager.createNativeQuery(sql);
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            query.setParameter(entry.getKey(), entry.getValue());
        }
        BigInteger bigInteger = (BigInteger) query.getSingleResult();
        Integer total = bigInteger.intValue();
        int sumPage = (total + pageSize - 1) / pageSize;
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("total", total);
        resultMap.put("page", page);
        resultMap.put("pageSize", pageSize);
        resultMap.put("sumPage", sumPage);
        LOGGER.info("GetListTotal ExecuteSQL Time:{}ms  Total:{}  Sql:{}  {}", System.currentTimeMillis() - startTime, total, sql, parameters);
        return resultMap;
    }


}

博客地址:http://my.oschina.net/wangnian

相關文章
相關標籤/搜索