Java Persistence API:用於對象持久化的一組API。spring
JPA的思想就是:能夠用Java代碼實現的,爲何還要本身去編寫sql語句?其核心的一切都是圍繞如何拼接SQL語句進行的。sql
Spring Data 是 Spring 的一個子項目。用於簡化數據庫訪問,支持NoSQL 和 關係型數據存儲。其主要目標是使數據庫的訪問變得方便快捷。Spring Data 具備以下特色:數據庫
一、SpringData 項目支持 NoSQL 存儲: express
MongoDB (文檔數據庫)
Neo4j(圖形數據庫)
Redis(鍵/值存儲)
Hbase(列族數據庫)框架
二、SpringData 項目所支持的關係型數據存儲技術: ide
JDBC
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(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建議只使用四個級別,優先級從高到低分別是 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文檔。框架相關的資料大多不完善,找文檔很費時間,點擊方法看看源碼是怎麼實現的,足以解決問題。