??xml version="1.0" encoding="utf-8" standalone="yes"?> JPAQJava Persistence APIQJava持久化APIQ,定义了对?关系映射QORMQ以及实体对象持久化的标准接口?/p> JPA是JSR-220QEJB3.0Q规范的一部分Q在JSR-220中规定实体对象(EntityBeanQ由JPAq行支持?/p> 所以JPA不局限于EJB3.0Q而是作ؓPOJO持久化的标准规范Q可以脱d器独立运行,开发和试更加方便?/p> JPA在应用中的位|如下图所C: JPAl护一个Persistence ContextQ持久化上下文)Q在持久化上下文中维护实体的生命周期。主要包含三个方面的内容Q?/p> JPA的主要API都定义在javax.persistence包中。如果你熟悉HibernateQ可以很Ҏ做出对应Q?/p> 实体生命周期是JPA中非帔R要的概念Q描qC实体对象从创建到受控、从删除到游ȝ状态变换。对实体的操作主要就是改变实体的状态?/p> JPA中实体的生命周期如下图: EntityManager提供一pd的方法管理实体对象的生命周期Q包括: 如果使用了事务管理,则事务的commit/rollback也会改变实体的状态?/p> ID对应数据库表的主键,是保证唯一性的重要属性。JPA提供了以下几UID生成{略 @TableGenerator( name="myGenerator", table="GENERATORTABLE", pkColumnName = "ENTITYNAME", pkColumnValue="MyEntity", valueColumnName = "PKVALUE", allocationSize=1 ) @GeneratedValue(strategy = GenerationType.TABLE,generator="myGenerator") JPA定义了one-to-one、one-to-many、many-to-one、many-to-many 4U关pR?/p> 对于数据库来_通常在一个表中记录对另一个表的外键关联;对应到实体对象,持有兌数据的一方称为owning-sideQ另一方称为inverse-side?/p> Z~程的方便,我们l常会希望在inverse-side也能引用到owning-side的对象,此时构Z双向兌关系?在双向关联中Q需要在inverse-side定义mappedBy属性,以指明在owning-side是哪一个属性持有的兌数据?/p> 对关联关pL的要点如下Q?/p> 其中 many-to-many关系的owning-side可以使用@JoinTable声明自定义关联表Q比如Book和Author之间的关联表Q?/p> @JoinTable(name = "BOOKAUTHOR", joinColumns = { @JoinColumn(name = "BOOKID", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "AUTHORID", referencedColumnName = "id") }) 兌关系q可以定制gq加载和U联操作的行为(owning-side和inverse-side可以分别讄Q: 通过讄fetch=FetchType.LAZY ?fetch=FetchType.EAGER来决定关联对象是延迟加蝲或立卛_载?/p> 通过讄cascade={options}可以讄U联操作的行为,其中options可以是以下组合: JPA通过在父cd加@Inheritance(strategy=InheritanceType.xxx)来声明承关pRA支持3U承策略: 其中1?能够支持多态,但是1需要允许字DؓNULLQ?需要多个JOIN关系Q?最适合关系数据库,对多态支持不好。具体应用时Ҏ需要取舍?/p> 通过在实体的Ҏ上标注@PrePersistQ@PostPersist{声明即可在事g发生时触发这些方法?/p> JPA提供两种查询方式Q一U是Ҏ主键查询Q用EntityManager的findҎQ?/p> T find(Class entityClass, Object primaryKey) 另一U就是用JPQL查询语言。JPQL是完全面向对象的Q具备ѝ多态和兌{特性,和hibernate HQL很相伹{?/p> 使用EntityManager的createQueryҎQ?/p> Query createQuery(String qlString) 可以在JPQL语句中用参数。JPQL支持命名参数和位|参CU参敎ͼ但是在一条JPQL语句中所有的参数只能使用同一U类型?/p> 举例如下Q?/p> Query query = em.createQuery("select p from Person p where p.personid=:Id"); query.setParameter("Id",new Integer(1)); Query query = em.createQuery("select p from Person p where p.personid=?1"); query.setParameter(1,new Integer(1)); 如果某个JPQL语句需要在多个地方使用Q还可以使用@NamedQuery 或?@NamedQueries在实体对象上预定义命名查询?/p> 在需要调用的地方只要引用该查询的名字卛_?/p> 例如Q?/p> @NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1") @NamedQueries({ @NamedQuery(name="getPerson1", query= "FROM Person WHERE personid=?1"), @NamedQuery(name="getPersonList", query= "FROM Person WHERE age>?1") }) Query query = em.createNamedQuery("getPerson"); JPQL也支持排序,cM于SQL中的语法。例如: Query query = em.createQuery("select p from Person p order by p.age, p.birthday desc"); JPQL支持AVG、SUM、COUNT、MAX、MIN五个聚合函数。例如: Query query = em.createQuery("select max(p.age) from Person p"); Object result = query.getSingleResult(); String maxAge = result.toString(); JPQL不仅用于查询Q还可以用于扚w更新和删除?/p> 如: Query query = em.createQuery("update Order as o set o.amount=o.amount+10"); //update 的记录数 int result = query.executeUpdate(); Query query = em.createQuery("delete from OrderItem item where item.order in(from Order as o where o.amount<100)"); query.executeUpdate(); query = em.createQuery("delete from Order as o where o.amount<100"); query.executeUpdate();//delete的记录数 与SQLcMQJPQLq涉及到更多的语法,可以参考:http://docs.oracle.com/cd/E11035_01/kodo41/full/html/ejb3_langref.html JPA支持本地事务理QRESOURCELOCALQ和容器事务理QJTAQ,容器事务理只能用在EJB/Web容器环境中?/p> 事务理的类型可以在persistence.xml文g中的“transaction-type”元素配置?/p> JPA中通过EntityManager的getTransaction()Ҏ获取事务的实例(EntityTransactionQ,之后可以调用事务的begin()、commit()、rollback()Ҏ?/p> Date: 2012-12-30 16:46:29 CST Author: Holbrook Org version 7.8.11 with Emacs version 241 JPA概述
org.hibernate javax.persistence 说明 cfg.Configuration Persistence d配置信息 SessionFactory EntityManagerFactory 用于创徏会话/实体理器的工厂c?/td> Session EntityManager 提供实体操作APIQ管理事务,创徏查询 Transaction EntityTransaction 理事务 Query Query 执行查询 2 实体生命周期
3 实体关系映射QORMQ?/h2>
3.1 基本映射
对象?/th> 数据库端 annotion 可选annotion Class Table @Entity @Table(name="tablename") property column – @Column(name = "columnname") property primary key @Id @GeneratedValue 详见ID生成{略 property NONE @Transient 3.2 ID生成{略
3.3 兌关系
关系cd Owning-Side Inverse-Side one-to-one @OneToOne @OneToOne(mappedBy="othersideName") one-to-many / many-to-one @ManyToOne @OneToMany(mappedBy="xxx") many-to-many @ManyToMany @ManyToMany(mappedBy ="xxx") 3.4 l承关系
4 事g及监?/h2>
5 Query Language 查询语言
5.1 使用参数
5.2 命名查询
5.3 排序
5.4 聚合查询
5.5 更新和删?/h3>
5.6 更多
6 事务理
]]>
在JAVA加上LOGQ?br />
+ dataSource.getMaxActive() + ") " + "idle: " + dataSource.getNumIdle()
+ "(max: " + dataSource.getMaxIdle() + ")");
l果昄为:
active的数量一直增加,但idle的数量一直ؓ0。当E序向链接池要链接的时候,如果池没有,׃新徏一个,active数就会加1Q关闭链接后Q链接会q回池,idle数加1。idle?则表C池里没有链接?br />
q样说明链接一直在创徏Q没有关闭放回池里。但链接是由SPRING和HIBERNATE理的,代码中没有关闭链接的语句。之后试了N多配|,都还没解冻I如增加maxActive数等。最后,加上q一行,问题才终于解冻I
q里默认值是autoQ如果是用JTA事务才适用Q如果是JDBC事务Q就只能用after_transaction?br />
q样每次事务l束后,׃关闭链接q回链接池?br />
]]>
We had worked on a project where we hand-coded all of our DAOs. This produced four irksome difficulties: (1) Method names and implementations were not altogether consistent. (2) It was a pain to make additional columns sortable or filterable, and as a result, a lot of pages lacked good sorting and filtering. (3) Making additional DAOs was tedious and took a fair amount of time. (4) Writing tests for DAOs is tricky and tedious, so no one really did.
This framework aims to ease our troubles.
*A fairly simple adapter is required for each JPA provider. Right now we only have an adapter for Hibernate Entity Manager. If anyone would like to contribute an adapter for any other JPA provider (OpenJPA, TopLink, etc.), that would be great.
**If time permits, we would like to eventually post our corresponding Adobe Flex 3 framework and utilities.
Wiki Documentation: UserGuide
Javadoc: http://hibernate-generic-dao.googlecode.com/svn/trunk/docs/api/index.html
Blog: http://hibernategenericdao.wordpress.com/
Please post at http://groups.google.com/group/java-generic-dao.
Simply extend the GenericDAO class with the specific type.
public interface ProjectDAO extends GenericDAO<Project, Long> {

}

public class ProjectDAOImpl extends GenericDAOImpl<Project, Long> implements ProjectDAO {

}