通过昨天的学习和晚上上自习时候的练习对 JPA 有了一定的了解,对学好 JPA 有了很大的信心.呵呵...在学一门新技术的时候,总是感觉它很难可能学不会.这技术有多高深啊,不好掌握.可是每次学完了回头一看,又感觉原来如此啊, 其实不是想的那样.哈哈...还是经验少啊.下面对今天的学习内容总结一下.
1.关系映射
1)多对一
ManyToOne(@ManyToOne)
Class Order{
@ManyToOne
Customer customer ;
2)一对多
@OneToMany(targetEntity=Order.class,mappedby=“customer”)
OneToMany(@OneToMany)
Class Customer{
@OneToMany(mappedBy=“”)
Set<Order> orders = ..
}
设置多对一的级联:@ManyToOne(cascade=CascadeType.PERSIST)
3)多对一自连接映射
@ManyToOne
@JoinColumn(name=“parent_id”,//外键名称
referencedColumnName=“id”)//当前表主键
Category parentCategory;
4)一对一
@OneToOne
class User{
@OneToOne
protected Addr addr;
class Addr{
@OneToOne(mappedBy=“addr", optional="false");
protected User user;
}
5)One-to-one关联
外键关联:
使用@JoinColumn[单向]
class User{
@OneToOne
@JoinColumn(name=“addr_id", referencedColumnName=“addrid",updatable=false)
protected Addr addr;
name指定在用户表中的外键名称.如果没有指定,则生成的外键字段形式如下:
<relationship字段/属性名>_<对端表的主键名>
若双向关联的话:
@Entity
public class Addr {
@OneToOne(mappedBy=“addr”)//控制权问题
protected User user;
主键关联:
One-to-one关联,地址表是自然主键
使用 @PrimaryKeyJoinColumn
class User{
@OneToOne
@PrimaryKeyJoinColumn(name="userid", referencedColumnName=“addrid")
protected Addr addr;
PrimaryKeyJoinColumn的name属性指定当前表的主键名, referenced-ColumnName属性指定关联表中的外键名称.referencedColumnName默认值属性名_主键名
public class Addr {
@Id//自然主键
@Column(name=“userid")private Integer id ;
//@oneToOne(mapped="addr") protected User user;
主键关联时,一定要先插入User,然后手动为Addr指定id才可保存.
6)多对多
@ManyToMany
protected Set<Student> students;
@ManyToMany(mappedBy=“students")
protected Set<Teacher> teachers;
7)联合主键
@JoinTable(name="jpa_teas_stus_links",
joinColumns=
{@JoinColumn(name=“sno1",referencedColumnName=“no1"),
@JoinColumn(name=“sno2",referencedColumnName=“no2"),
@JoinColumn(name=“sno3",referencedColumnName=“no3")}
inverseJoinColumns=
{@JoinColumn(name=“tno1", referencedColumnName=“no1")),
@JoinColumn(name=“tno2", referencedColumnName=“no2")),
@JoinColumn(name=“tno3", referencedColumnName=“no3"))}
protected Set<Stud> studs;
@ManyToMany(mappedBy="items")
protected Set<Teacher> teachers;
8)级联删除
@ManyToMany(mappedName=“teachers”,cascade=CasCadeType.REMOVE)
Set<Student> ..
Em.remove(teacher.class,new CompID(a,b,c));..
2.JPA继承关系
单表策略:所有的信息存放到一个表中(区分符子段)
@Entity
@Table(name=“ess")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=“etype",
discriminatorType=DiscriminatorType.STRING, length=2)
public abstract class Employee{..}
@Entity
@DiscriminatorValue(value=“he")
public class HE extends Employee
@Entity
@DiscriminatorValue(value=“se")
public class SE extends Employee
3.实体状态:
四种状态
New (transient): 创建出来没关联,没有id,没有记录
Managed (persistent): 和当前context关联的实体
Detached: 有id,但不和上下文关联(evict).
Removed: 有id,不和上下文关联,计划从库中删除.
4.持久化相关操作
em.persist(fritz);
em.find( Cat.class, new Long(catId) );
em.getReference(Parent.class, parentId);
em.flush();
em.refresh(cat);
entityManager.find(Seller.class, sellerId);
联合主键检索:
SellerPK sellerKey = new SellerPK();
sellerKey.setFirstName(firstName);
sellerKey.setLastName(lastName);
Seller seller = entityManager.find(Seller.class, sellerKey);
更新实体
O o = em.find(..)
o.setXXX(..);
添加实体:
em.persist(..);
合并实体:
em.merge(..);//更新游离对象
删除实体
entityManager.remove(entityManager.merge(order));
remove只操作托管的实体,如果传递一个游离实体的话,将抛出非法参数异常.
@OneToMany(cascade=CascadeType.REMOVE)//级联删除
//Flush控制清理
em.setFlushMode(FlushModeType.COMMIT);
em.flush();
//Refresh
em.refresh(entity);
5.JPQL查询
1)简单查询 :
Query query = em.createQuery("SELECT c FROM Customer c");
return query.getResultList();
2)命名查询
@Entity
@NamedQuery(name = "findCustomerByName",
query = "SELECT c FROM Customer c
WHERE c.name
LIKE :name ")
class Category{..}
//定义多个命名查询条件
@NamedQueries({@NamedQuery(..), @NamedQuery(..)});
em.createNamedQuery("findAllCustomers")
3)分页
query = em.createNamedQuery("findCustomerByName");
query.setParameter("name", "t,om");
query.setMaxResults(10);
query.setFirstResult(3);
List customers = query.getResultList();
4)设置参数:
SELECT o FROM Order i WHERE i.orderNo = ?1
query.setParameter(1, 100.00);
SELECT o FROM Order i WHERE o.price = :price
query.setParameter("price", 100.00);
5)单个实体检索
query.getSingleResult();
6)使用实体名
@Entity(name = "CustomerEntity")
public class Category
FROM CustomerEntity [as] c
7)查询集合 :
WHERE c.orders IS EMPTY
WHERE CONCAT(c.fname, c.lname) = 't,om'
SELECT c.id, c.name FROM Customer c
8)多态查询
SELECT c FROM Customer c WHERE c.name LIKE :name
9)分组
SELECT o.customer, COUNT(o.id) FROM Order o GROUP BY o.customer
10)排序
order by
11)子查询
SELECT o FROM Order I WHERE o.customer IN
(SELECT c FROM Customer c WHERE c.name LIKE ?1)
12)连接
SELECT o,c FROM Order o, Customer c WHERE o.customer.id = c.id
SELECT o FROM Order o [INNER] JOIN o.customer //内连接
SELECT c FROM Customer c LEFT OUTER JOIN c.orders//外连接
SELECT c FROM Customer c FETCH JOIN c.orders//迫切连接
13)批量更新/删除
UPDATE Customer c SET c.age = ?1 WHERE c.id >=?2
query.setParameter(1, 12);
query.setParameter(2, 5);
int results = query.executeUpdate();