JPA 的根據解析方法名稱自動對接口進行實現的方法能節省大量的資源,以下對於解析規則進行列舉哈
商品實體類
package com.dionren.zhaoxie.entity.trade;
import com.dionren.mvc.entity.EntityBase;
import com.dionren.zhaoxie.entity.EntityShoeSku;
import io.swagger.annotations.ApiModelProperty;
import javax.persistence.*;
import java.math.BigDecimal;
/**
* Created by DionRen on 2015/9/28.
*
* 單件貨物,即SKU+鞋碼+數量,單件貨物不能單獨存在,只能依附到配貨單、訂單、生產單中
*
* 本類是單件貨物的基類,單表繼承方式,即所有子類數據都存到一個表中,通過goodsType來區分
*
*/
@Entity
@Table(name = "trade_goods")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "goodsType", discriminatorType = DiscriminatorType.STRING)
public class EntityTradeGoods extends EntityBase {
@GeneratedValue(strategy= GenerationType.AUTO)
@Id
public Long id; // 序列ID
@ApiModelProperty(value = "SKU的ID號")
@ManyToOne(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
@JoinColumn(name = "skuId")
public EntityShoeSku sku;
@ApiModelProperty(value = "進貨價")
@Column(precision=18, scale=2)
public BigDecimal priceIn;
// public Double priceIn;
@ApiModelProperty(value = "銷售價")
@Column(precision=18, scale=2)
public BigDecimal priceOut;
// public Double priceOut;
@ApiModelProperty(value = "尺碼,按照mm標註")
public Integer size;
@ApiModelProperty(value = "訂貨數量")
public Integer quantity;
}
鞋子的SKU類
package com.dionren.zhaoxie.entity;
import com.dionren.mvc.api.ApiJsonView;
import com.dionren.mvc.entity.EntityBase;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.annotations.ApiModelProperty;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
/**
* Created by DionRen on 2015/9/28.
*
* 鞋樣的數據
*/
@Entity
@Table(name = "shoe_sku")
public class EntityShoeSku extends EntityBase {
@JsonView(ApiJsonView.ListSummary.class)
@GeneratedValue(strategy= GenerationType.AUTO)
@Id
public Long id; // 序列ID
@ApiModelProperty("款型的id")
public Long shoePatternId;
@ApiModelProperty("sku完整編碼")
@Column(length = 32)
public String skuCode;
@ApiModelProperty(value = "sku編碼的後兩位")
@Column(length = 2)
public String colorCode;
@ApiModelProperty(value = "顏色的中文名稱")
@Column(length = 64)
public String colorName;
@ApiModelProperty("sku所屬的企業id,其實可以從patternId查詢,但是爲了加速查詢")
public Long clientCompanyId;
}
方法解析:(findByPriceOutAndSkuSkuCode)
1.首先去掉前綴,如find、findBy、read、readBy、get、getBy,剩下部分進行解析。並且如果方法的最後一個參數是 Sort 或者 Pageable 類型,也會提取相關的信息,以便按規則進行排序或者分頁查詢。
2.經過第一步,方法名剩下PriceOutAndSkuSkuCode,先判斷 PriceOut(根據 POJO 規範,首字母變爲小寫,下同)是否爲 PriceOut的一個屬性,
3.1如果是對象的一個屬性,並且遇到and,則將其作爲查詢條件中的一個繼續步驟2,判斷SkuSkuCode
3.2如果不是對象的一個屬性遇到And,則報錯:對象中沒有對應的屬性,And算是強制拆分。
3.3.如果是,並且也沒有遇到and,則以將此屬性作爲對象,繼續向下判斷,既把SKU作爲一個對象,向下找sku的屬性
如上述:方法findByPriceOutAndSkuSkuCode就會拆分成根據priceOut和 sku.skuCode查詢,
下面舉例理解下上述:
findByPriceIn---->根據priceIn查詢
findByPriceInAndPriceOut---->根據priceIn和PriceOut查詢
findByPriceInAndSkuSkuCode--->根據priceIn丶skuid與sku表主鍵關聯後sku表的skuCode查詢
findByPriceInSkuSkuCode------>報錯,會把priceIn作爲一個對象根據priceIn的sku屬性查詢
正確應該爲findByPriceInAndSkuSkuCode
findBySkuSkuCodeColorCode --->報錯會議sku.skuCode.colorCode查詢,
正確應該爲findBySkuSkuCodeAndSkuColorCode
可能會存在一種特殊情況,比如 AccountInfo 包含一個 user 的屬性,也有一個 userAddress 屬性,此時會存在混淆。讀者可以明確在屬性之間加上 "_" 以顯式表達意圖,比如 "findByUser_AddressZip()" 或者 "findByUserAddress_Zip()"。
在查詢時,通常需要同時根據多個屬性進行查詢,且查詢的條件也格式各樣(大於某個值、在某個範圍等等),Spring Data JPA 爲此提供了一些表達條件查詢的關鍵字,大致如下:
- And --- 等價於 SQL 中的 and 關鍵字,比如 findByUsernameAndPassword(String user, Striang pwd);
- Or --- 等價於 SQL 中的 or 關鍵字,比如 findByUsernameOrAddress(String user, String addr);
- Between --- 等價於 SQL 中的 between 關鍵字,比如 findBySalaryBetween(int max, int min);
- LessThan --- 等價於 SQL 中的 "<",比如 findBySalaryLessThan(int max);
- GreaterThan --- 等價於 SQL 中的">",比如 findBySalaryGreaterThan(int min);
- IsNull --- 等價於 SQL 中的 "is null",比如 findByUsernameIsNull();
- IsNotNull --- 等價於 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
- NotNull --- 與 IsNotNull 等價;
- Like --- 等價於 SQL 中的 "like",比如 findByUsernameLike(String user);
- NotLike --- 等價於 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
- OrderBy --- 等價於 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
- Not --- 等價於 SQL 中的 "! =",比如 findByUsernameNot(String user);
- In --- 等價於 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的參數可以是 Collection 類型,也可以是數組或者不定長參數;
- NotIn --- 等價於 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的參數可以是 Collection 類型,也可以是數組或者不定長參數;
以上與方法解析可以合併用:
舉例
findBySkuSkuCodeAndPriceInLessThanOrderOrderByPriceInAsc("10123",200);
查詢所有Sku的skuCode等於10123,priceIn小於200的貨物列表,並且按升序排列