Spring Data Jpa

1. JPA是什麼?

Java Persistence API:用於對象持久化的一組API。spring

JPA的思想就是:能夠用Java代碼實現的,爲何還要本身去編寫sql語句?其核心的一切都是圍繞如何拼接SQL語句進行的。sql

二、Spring Data

Spring Data 是 Spring 的一個子項目。用於簡化數據庫訪問,支持NoSQL 和 關係型數據存儲。其主要目標是使數據庫的訪問變得方便快捷。Spring Data 具備以下特色:數據庫

一、SpringData 項目支持 NoSQL 存儲: express

MongoDB (文檔數據庫)
Neo4j(圖形數據庫)
Redis(鍵/值存儲)
Hbase(列族數據庫)框架

二、SpringData 項目所支持的關係型數據存儲技術: ide

JDBC
JPA源碼分析

三、使用jpa須要給實體類加註解

@Entity(name = "t_book")
public class Book {
    private Long id;
    private String name;
    private String author;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
    // 省略其餘getter/setter
}

@Entity註解表示這是一個實體類,那麼在項目啓動時會自動針對該類生成一張表,默認的表名爲類名,若是使用了name屬性表示自定義生成的表名。@Id註解表示這個字段是一個id,@GeneratedValue註解表示主鍵採用自增加策略,對於類中的其餘屬性,默認都會根據屬性名在表中生成相應的字段,字段名和屬性名相同,若是開發者想要對字段進行定製,可使用@Column註解,去配置字段的名稱,長度,是否爲空等等。學習

四、多條件單表查詢

構建謂語

Specification<Product> specification = new Specification<Product>() {
            @Override
            public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Expression<String> idCol = root.get("id");
                Expression<BigDecimal> rewardRateCol = root.get("rewardRate");
                Expression<String> statusCol = root.get("status");
                List<Predicate> predicates = new ArrayList<>();
                if (idList != null && idList.size() > 0) {
                    predicates.add(idCol.in(idList));   //##1
                }
                if (minRewardRate != null && BigDecimal.ZERO.compareTo(minRewardRate) < 0) {
                    predicates.add(cb.ge(rewardRateCol, minRewardRate));     //##2
                }
                if (maxRewardRate != null && BigDecimal.ZERO.compareTo(maxRewardRate) < 0) {
                    predicates.add(cb.le(rewardRateCol, maxRewardRate));
                }
                if (statusList != null && statusList.size() > 0) {
                    predicates.add(statusCol.in(statusList));
                }

                query.where(predicates.toArray(new Predicate[0]));
                return null;
            }
        };
        Page<Product> page = repository.findAll(specification, pageable);

謂語是什麼呢?按個人理解,謂語就是一個條件限定詞。
一、使用Expression的in方法構建了一個包含的條件(或謂語),查詢結果的id須要包含在idList裏。
二、咱們使用criteriaBuilder的ge方法構建了一個大於的條件(或謂語),該條件要求收益率大於指定的值。ui

五、自定義查詢@Query的使用

@Query(value = "SELECT CONCAT_WS('|', order_id,outer_order_id,chan_id,chan_user_id,product_id,order_type,amount,DATE_FORMAT( create_at,'%Y-%m-%d %H:%i:%s')) FROM order_t WHERE order_status = 'success' AND chan_id = ?1 AND create_at >= ?2 AND create_at < ?3",nativeQuery = true)
    List<String> queryVerifiableOrders(String chanId, Date start, Date end);

這裏有三個參數,對應三個佔位符,佔位符是固定寫法。還有另一種使用命名參數的方式。
nativeQuery = true表示這裏使用的是原生態的sql查詢語句。翻譯

六、合法參數校驗

Spring 採用一個 org.springframework.util.Assert 通用類完成這一任務。
Assert 翻譯爲中文爲「斷言」,使用過 JUnit 的讀者都熟知這個概念,它判定某一個實際的運行值和預期想同樣,不然就拋出異常。Spring 對方法入參的檢測借用了這個概念,其提供的 Assert 類擁有衆多按規則對方法入參進行斷言的方法,能夠知足大部分方法入參檢測的要求。這些斷言方法在入參不知足要求時就會拋出 。IllegalArgumentException。
經常使用斷言方法源碼分析:

public static void notNull(@Nullable Object object, String message) {
        if (object == null) {
            throw new IllegalArgumentException(message);
        }
    }

當object爲null時拋出異常。


public static void isTrue(boolean expression, String message) {
        if (!expression) {
            throw new IllegalArgumentException(message);
        }
    }

當 expression 爲true經過,flase時拋出異常。

七、Log4j

Log4j建議只使用四個級別,優先級從高到低分別是 ERROR、WARN、INFO、DEBUG。

經過在這裏定義的級別,您能夠控制到應用程序中相應級別的日誌信息的開關。好比在這裏定義了INFO級別, 則應用程序中全部DEBUG級別的日誌信息將不被打印出來。優先級高的將被打印出來。項目上生產環境時候必定得把debug的日誌級別從新調爲warn或者更高,避免產生大量日誌。

八、配置多數據源

目標

@Test
public void queryOrder(){
    System.out.println(orderRepository.findAll());
    System.out.println(readOrderRepository.findAll());
}

orderRepository.findAll()鏈接的是主庫、生成訂單。

readOrderRepository.findAll()鏈接的是從庫、生成對帳文件、保存渠道的訂單信息。

目標定好了,如何實現呢?
有什麼方法幫助本身找到答案?

九、學習經驗

一、若是若是遇到不太熟悉的代碼,主要經過點擊方法查看源碼尋找答案,JDK相關的纔看官方API文檔。框架相關的資料大多不完善,找文檔很費時間,點擊方法看看源碼是怎麼實現的,足以解決問題。

相關文章
相關標籤/搜索