Java EE编程技术学习笔记(5)-JPA

JPA

配置文件:persistence.xml,定义与数据库连接相关的数据源、持久化实现、事务属性等内容。

<persistence-unit name=”JPADemoPU” transaction-type=”JTA”>...</persistence-unit>

EntityJPA操作的基本单元,采用注解@Entity@Id@GeneratedValue(strategy = GenerationType.IDENTITY)等。

EntityManager

@PersistenceContext(unitName = “MyJPADemoPU”)

private EntityManager em;

@Resource

private UserTransaction utx;

...

utx.begin();

em.persist(person);

utx.commit();

 

3.ORM

(1)Entity

@Entity @ID @Table(name=”customer”)

(2)主键

@GenerateValue Table(表生成主键) Sequence(数据库机制) Identity(自动增长列) Auto四种策略

(3)复合主键

主键类用@Embeddable注解,重写equals(),hashCode(),实现Serializable接口,@EmbeddedId

@WebServlet(name=”CreateOrderServlet”, urlPattern{“/CreateOrderServlet”})

...

@PersistenceContext(unnitName=”MyJPADemoPU”)

private EntityManager em;

@Resource

private javax.transaction.UserTransaction utx;

...

MyOrder temp = em.find(MyOrder.class, oid);

...

(4)属性

@Column: name unique nullable insertable updateable length precision scale

@Temporal 如果使用java.util包中的时间日期类型,必须额外标注@Temporal注解来说明转化成java.sql包中的哪种类型

@Transient 标识不需要持久化的属性

@Lob char[]Character[]映射为CLOBbyte[]Byte[]映射为Blob,通常使用惰性加载方式,与@Basic(fetch=FetchType.LAZY)同时使用

@ElementCollection 将集合属性映射到一个单独的子表中,CollectionTable(name=”Tag”)@Column(name=”Value”)@OrderColumn@MapKeyColumn

@Enumerated 可以持久化名称或值,枚举类型默认为int,可以用@Enumerated(EnumType.STRING)

 

(5)关联映射

一对一:

cascadeCascadeType.PERSIST, CascadeType.MERGE, CascadeType.Remove, CascadeType.refresh

fetchEAGER, LAZY

optionaltrue

单向关联:

@Entity

...Customer {

@OneToOne(fetch=FetchType.LAZY, optional=true)

private Address address;

...

}

双向关联:

@Entity

...Discoount {

@OneToOne(mappedBy=”discount”)

Customer cid;

private Address address;

...

}

一对多:

@OneToMany

@JoinColumn(name=”customer_id”)

Private List<CUstomerOrder> orders;

多对一:

@ManyToOne

private Customer customerid;

...

@OneToMany(mappedBy=”customerid”)

Private List<CustomerOrder> orders;

多对多:

可以使用@ManyToMany

 

(6)加载方式

EGER:主动加载

LAZY:被动加载

(7)顺序

@OrderBy(“name DESC”)

Private List<Subject> subjects;

 

(8)继承映射

Single-table 父类和子类新添加的属性映射到一张数据库表

Joined-subclass Entity不含有从根Entity继承来的属性,通过共享主键关联

Table-per-concrete-class 每一个Entity映射到一个单独的表,含有继承来的属性

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

 

4.Entity管理

(1)获取EntityManager

8.2节,通过@PersistContext注解找到配置文件,声明EntityManager实例

(2)持久化上下文

EME的任何操作都是首先保存到持久化上下文,最后才更新到数据库

有两种类型,事务范围的和扩展范围的

操作Entity之前如果没有事务范围的上下文会要求创建否则抛出异常,事务提交时Entity同步到数据库,上下文销毁

扩展范围的上下文应用在有状态会话Bean中,移除Bean时,Entity同步到数据库,上下文销毁

 

(3)Entity操作

新增:utx.persist(c)

查询:em.find(Address.class, 2L)em.getReference(Address.class, 2L),区别find返回nullgetReference抛异常,另外getReference不保证Entity已被初始化

修改:c.setName(“hyl”),在事务中同一个id只存在一个实例,不使用事务find会获得新的实例

c=em.find...

c.setName(“Peter”);

utx.begin();

em.flush();

c2=em.find...

c2.getName();

utx.commit();//属性没有修改,因为begin新开事务,flush清空了之前的上下文,将修改放在事务中即可

除了将修改放在事务中,还可以在beginflush之间em.merge(c)detached状态的c加入到新的持久化上下文

删除:em.remove(c)

EM还有一些有用的方法如refreshclearcontainsdetach

 

EM管理下的E有四种状态:NewManagedDetachedRemoved

 

(4)级联操作

cascade属性包含PERSISTMERGEREMOVEREFRESHDETACHALL关联主体进行操作时,关联的另一端做相应的操作

 

5.JPQL

SQL语法一致,区别是JPQL操作的是抽象的持久化模型,包括Entity,属性,关联等。

(1)动态查询:

Em.createQuery(“SELECT c FROM Customer c”)

query.getResultList()query.getSingleResult返回第一个Entity

query可以是TypedQuery<Customer>得到的是类型安全的

(2)参数设置

命名参数:...where c.id=:Id;query.setParameter(“Id”, new Integer(1))

位置参数:...where c.id=?1;query.setParameter(1, new Integer(1))

(3)命名查询

@Entity

@NamedQueries({

@NamedQuery(name=..., query=...),

@NamedQuery(name=..., query=...)

})

...

em.createNamedQuery(“(name)”);

(4)属性查询

查询不是整个Entity提高性能

Iterator iterator = Result.iterator();

Object[] row = iterator.next();

row[1],row[2]...c.id,c.Name

(5)使用构造器

“select new com.jpa.demo.SimpleCustomer(c.id, c.Name) from ...”

 

6.本地查询

@Entity

@NamedNativeQuery(name=”findAll”, query=”select * from t_customer”)//返回的是Customer集合

@Table(name=”t_customer”)

 

7.基于Criteria API的安全查询

针对查询字符串中存在语法错误

CriteriaBuilder builder = em.getCriteriaBuilder();

CriteriaQuery<Customer> query = builder.createQuery(Customer.class);

Root<Customer> c = query.from(Customer.class);

Query.select(c).where(builder.equal(c.get(“Name”),”zx”));

TypedQuery<Customer> typedQuery = em.createQuery(query);

...

Criteria API要求每个Entity生成一个原模型类,一般由开发工具自动生成,可以防止参数值拼写错误与Entity属性不一致

...

@Generated(value...

@StaticMetamodel(Customer.class)

public class Customer_{

Public static volatile SingularAttribute<Customer, Long> id;

...

}

Query.select(c).where(builder.greaterThan(c.get(Customer_.id),100L));

 

8.生命周期回调方法

@PreUpdate @PostUpdate @PreRemove @PostRemove @PostLoad

 

9.校验框架

支持Bean Validation API@Pattern(regexp=..., message=”{invalid.email}”)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值