JPA常用註解
請參考:http://1194867672-qq-com.iteye.com/blog/1730513
下面根據經驗談談Hibernate的一對多,多對一問題。
(一)雙向一對多的用法
可參考:http://blog.csdn.net/lxl_family/article/details/26523757
雙向一對多關係,一是關係維護端(owner side),多是關係被維護端(inverse side)。數據庫中的表一般都是相互關聯的,它們通過foreign key產生關係。在關係被維護端需要通過@JoinColumn建立外鍵列指向關係維護端的主鍵列。
@Entity //設置一個類爲實體類</span>
@JsonIgnoreProperties(value={"orderItems "}) </span>
@Table(name="Order") //作用:設置實體類對應的表,常與@Entity一起使用</span>
public class Order implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@JsonIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private transient String strbegin;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")</span>
private Date begindate;
private Set<OrderItem> orderItems = new HashSet<OrderItem>();
。。。。
@OneToMany(mappedBy="order",cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OrderBy(value = "id ASC")
public Set<OrderItem> getOrderItems() {
return orderItems;
}
//其他get set方法省略
}
public class OrderItem implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String itenName;
private Order order; //不用再根據表結構定義order_id屬性
。。。。
@ManyToOne(cascade=CascadeType.REMOVE,optional=false)
@JoinColumn(name = "order_id",referencedColumnName="id") //OrderItem表中的order_id字段與order表中的id關聯
public Order getOrder() {
return order;
}
}
通常後臺返回的數據都需要轉換成JSON字符串,以下三個註解都是用於JSON轉換。
@JsonIgnore 也可以直接在屬性上Ignore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 對屬性進行格式轉換,一般用於時間等特殊格式。
如果不處理,可能報錯:
jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:143)
//Json轉換死循環
org.springframework.orm.hibernate3.HibernateQueryException: could not resolve property
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: could not initialize proxy - no Session (through reference chain。。。)
(二)Hql的關聯查詢
1、從One的一方關聯到Many的一方:
查找出球員所屬的球隊,可以使用以下語句:
SELECT DISTINCT t FROM Order t JOIN t.OrderItems p where p.ItemName LIKE :name
或者使用以下語句:
SELECT DISTINCT t FROM Order t,IN(t.OrderItems) p WHERE p.ItemName LIKE :name
上面兩條語句是等價的,產生的SQL語句如下:
select
distinct Order0_.id as id0_,
Order0_.ItemName as ItemName0_
from
Order Order0_
inner join
player OrderItem1_
on Order0_.id=OrderItem1_.Order_id
where
OrderItems1_.ItemName like ?
從SQL語句中可以看到team inner join 到player。inner join要求右邊的表達式必須有返回值。
不能使用以下語句:
<span style="font-size:12px;">SELECT DISTINCT t FROM Order t WHERE t.OrderItem.ItemName LIKE :ItemName </span>
不能使用t.OrderItems.ItenName這樣的方式從集合中取值,要使用join或者in才行。
2、從Many的一方關聯到One的一方:
查找出某個球隊下的所有球員,可以使用以下查詢語句:
<span style="font-size:12px;">SELECT p FROM OrderItem p JOIN p.Order t WHERE t.id = :id </span>
或者使用以下語句
SELECT p FROM OrderItem p, IN(p.Order) t WHERE t.id = :id
這兩條查詢語句是等價的,產生的SQL語句如下:(產生了兩條SQL)
Hibernate:
select
OrderItem0_.id as id1_,
OrderItem0_.ItemName as ItemName1_,
OrderItem0_.Order_id as Order3_1_
from
OrderItem OrderItem0_
inner join
Order Order1_
on OrderItem0_.Order_id=Order1_.id
where
Order1_.id=?
Hibernate:
select
Order0_.id as id2_0_,
Order0_.ItemName as ItemName2_0_
from
Order Order0_
where
Order0_.id=?
從Many關聯到One的查詢,還可以使用以下的查詢語句:
SELECT p FROM OrderItem p WHERE p.Order.id = :id
這條語句產生的SQL如下:(產生了兩條SQL)
SELECT p FROM OrderItem p WHERE p.Order.id = :id
Hibernate:
select
OrderItem0_.id as id1_,
OrderItem0_.name as name1_,
OrderItem0_.Order_id as Order3_1_
from
OrderItem OrderItem0_
where
OrderItem0_.Order_id=?
Hibernate:
select
Order0_.id as id0_0_,
Order0_.name as name0_0_
from
Order Order0
以上從Many到One的關聯查詢都產生了兩條SQL,還可以使用join fetch只產生一條SQL語句。查詢語句如下:
SELECT p FROM OrderItem p JOIN FETCH p.Order t WHERE t.id = :id
這條查詢語句產生的SQL如下:
Hibernate:
select
OrderItem0_.id as id1_0_,
Order1_.id as id2_1_,
OrderItem0_.name as name1_0_,
OrderItem0_.Order_id as Order3_1_0_,
Order1_.name as name2_1_
from
OrderItem OrderItem0_
inner join
Order Order1_
on OrderItem0_.Order_id=Order1_.id
where
Order1_.id=?
可參考:http://www.cnblogs.com/luxh/archive/2012/06/02/2531750.html