﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-大鱼-随笔分类-JPA</title><link>http://www.blogjava.net/luluyanglu/category/38297.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 15 Mar 2009 17:02:25 GMT</lastBuildDate><pubDate>Sun, 15 Mar 2009 17:02:25 GMT</pubDate><ttl>60</ttl><item><title>JPA 单独使用</title><link>http://www.blogjava.net/luluyanglu/archive/2009/03/16/259907.html</link><dc:creator>大鱼</dc:creator><author>大鱼</author><pubDate>Sun, 15 Mar 2009 16:09:00 GMT</pubDate><guid>http://www.blogjava.net/luluyanglu/archive/2009/03/16/259907.html</guid><wfw:comment>http://www.blogjava.net/luluyanglu/comments/259907.html</wfw:comment><comments>http://www.blogjava.net/luluyanglu/archive/2009/03/16/259907.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/luluyanglu/comments/commentRss/259907.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/luluyanglu/services/trackbacks/259907.html</trackback:ping><description><![CDATA[<h1 class="postTitle"><a class="postTitle2" id="AjaxHolder_ctl01_TitleUrl" href="http://www.cnblogs.com/cxccbv/archive/2009/02/25/1397928.html">&nbsp;</a>&nbsp;</h1>
<div class="postBody">
<p>之前一直在用EJB3，但现在想在J2SE里面使用JPA，因为不大喜欢Hibernate的XML文件配置。</p>
<p>而使用DB4O的时候，出现了一些莫名其妙的问题，一直没解决，就暂时搁下了。</p>
<p>使用myeclipse 6开发jpa如下：</p>
<p>1.创建web project</p>
<p>2.添加jpa capabilities，选择toplink，把自动创建数据库的和更新persistence.xml的勾上</p>
<p>3.切换成database explorer视图，选择表，jpa逆向工程。</p>
<p>4.测试</p>
<p>生成的persistence.xml如下：</p>
<pre><span style="color: #0000ff">&lt;?</span>xml version="1.0" encoding="UTF-8"<span style="color: #0000ff">?&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">persistence</span> <span style="color: #ff0000">xmlns</span>=<span style="color: #0000ff">"http://java.sun.com/xml/ns/persistence"</span>
<span style="color: #ff0000">xmlns</span>:<span style="color: #ff0000">xsi</span>=<span style="color: #0000ff">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span style="color: #ff0000">xsi</span>:<span style="color: #ff0000">schemaLocation</span>=<span style="color: #0000ff">"http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"</span> <span style="color: #ff0000">version</span>=<span style="color: #0000ff">"1.0"</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">persistence</span>-<span style="color: #ff0000">unit</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">"JPAWebPU"</span>
<span style="color: #ff0000">transaction</span>-<span style="color: #ff0000">type</span>=<span style="color: #0000ff">"RESOURCE_LOCAL"</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">provider</span><span style="color: #0000ff">&gt;</span>
oracle.toplink.essentials.PersistenceProvider
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">provider</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">class</span><span style="color: #0000ff">&gt;</span>com.persia.entity.Consumer<span style="color: #0000ff">&lt;/</span><span style="color: #800000">class</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">properties</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">"toplink.jdbc.driver"</span>
<span style="color: #ff0000">value</span>=<span style="color: #0000ff">"com.mysql.jdbc.Driver"</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">"toplink.jdbc.url"</span>
<span style="color: #ff0000">value</span>=<span style="color: #0000ff">"jdbc:mysql://localhost:3306/ejb3"</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">"toplink.jdbc.user"</span> <span style="color: #ff0000">value</span>=<span style="color: #0000ff">"root"</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">"toplink.jdbc.password"</span> <span style="color: #ff0000">value</span>=<span style="color: #0000ff">"root"</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">property</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">"toplink.ddl-generation"</span>
<span style="color: #ff0000">value</span>=<span style="color: #0000ff">"create-tables"</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">properties</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">persistence</span>-unit<span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">persistence</span><span style="color: #0000ff">&gt;</span>
</pre>
<p>&nbsp;</p>
<p>生成的几个类如下：</p>
<p>实体类：</p>
<pre><span style="color: #0000ff">package</span> com.persia.entity;
<span style="color: #0000ff">import</span> javax.persistence.Column;
<span style="color: #0000ff">import</span> javax.persistence.Entity;
<span style="color: #0000ff">import</span> javax.persistence.Id;
<span style="color: #0000ff">import</span> javax.persistence.Table;
<span style="color: #008000">/**
* Consumer entity.
*
* @author MyEclipse Persistence Tools
*/</span>
@Entity
@Table(name = "<span style="color: #8b0000">consumer</span>", catalog = "<span style="color: #8b0000">ejb3</span>", uniqueConstraints = {})
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Consumer <span style="color: #0000ff">implements</span> java.io.Serializable {
<span style="color: #008000">// Fields</span>
<span style="color: #0000ff">private</span> Integer id;
<span style="color: #0000ff">private</span> String name;
<span style="color: #0000ff">private</span> String password;
<span style="color: #008000">// Constructors</span>
<span style="color: #008000">/** default constructor */</span>
<span style="color: #0000ff">public</span> Consumer() {
}
<span style="color: #008000">/** full constructor */</span>
<span style="color: #0000ff">public</span> Consumer(Integer id, String name, String password) {
<span style="color: #0000ff">this</span>.id = id;
<span style="color: #0000ff">this</span>.name = name;
<span style="color: #0000ff">this</span>.password = password;
}
<span style="color: #008000">// Property accessors</span>
@Id
@Column(name = "<span style="color: #8b0000">id</span>", unique = <span style="color: #0000ff">true</span>, nullable = <span style="color: #0000ff">false</span>, insertable = <span style="color: #0000ff">true</span>, updatable = <span style="color: #0000ff">true</span>)
<span style="color: #0000ff">public</span> Integer getId() {
<span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.id;
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setId(Integer id) {
<span style="color: #0000ff">this</span>.id = id;
}
@Column(name = "<span style="color: #8b0000">name</span>", unique = <span style="color: #0000ff">false</span>, nullable = <span style="color: #0000ff">false</span>, insertable = <span style="color: #0000ff">true</span>, updatable = <span style="color: #0000ff">true</span>, length = 45)
<span style="color: #0000ff">public</span> String getName() {
<span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.name;
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setName(String name) {
<span style="color: #0000ff">this</span>.name = name;
}
@Column(name = "<span style="color: #8b0000">password</span>", unique = <span style="color: #0000ff">false</span>, nullable = <span style="color: #0000ff">false</span>, insertable = <span style="color: #0000ff">true</span>, updatable = <span style="color: #0000ff">true</span>, length = 45)
<span style="color: #0000ff">public</span> String getPassword() {
<span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.password;
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> setPassword(String password) {
<span style="color: #0000ff">this</span>.password = password;
}
}</pre>
<pre>&nbsp;</pre>
<p>DAO接口</p>
<pre><span style="color: #0000ff">package</span> com.persia.entity;
<span style="color: #0000ff">import</span> java.util.List;
<span style="color: #008000">/**
* Interface for ConsumerDAO.
*
* @author MyEclipse Persistence Tools
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">interface</span> IConsumerDAO {
<span style="color: #008000">/**
* Perform an initial save of a previously unsaved Consumer entity. All
* subsequent persist actions of this entity should use the #update()
* method. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#persist(Object) EntityManager#persist}
* operation.
*
* &lt;pre&gt;
* EntityManagerHelper.beginTransaction();
* IConsumerDAO.save(entity);
* EntityManagerHelper.commit();
* &lt;/pre&gt;
*
* @param entity
*            Consumer entity to persist
* @throws RuntimeException
*             when the operation fails
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> save(Consumer entity);
<span style="color: #008000">/**
* Delete a persistent Consumer entity. This operation must be performed
* within the a database transaction context for the entity's data to be
* permanently deleted from the persistence store, i.e., database. This
* method uses the
* {@link javax.persistence.EntityManager#remove(Object) EntityManager#delete}
* operation.
*
* &lt;pre&gt;
* EntityManagerHelper.beginTransaction();
* IConsumerDAO.delete(entity);
* EntityManagerHelper.commit();
* entity = null;
* &lt;/pre&gt;
*
* @param entity
*            Consumer entity to delete
* @throws RuntimeException
*             when the operation fails
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> delete(Consumer entity);
<span style="color: #008000">/**
* Persist a previously saved Consumer entity and return it or a copy of it
* to the sender. A copy of the Consumer entity parameter is returned when
* the JPA persistence mechanism has not previously been tracking the
* updated entity. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
* operation.
*
* &lt;pre&gt;
* EntityManagerHelper.beginTransaction();
* entity = IConsumerDAO.update(entity);
* EntityManagerHelper.commit();
* &lt;/pre&gt;
*
* @param entity
*            Consumer entity to update
* @returns Consumer the persisted Consumer entity instance, may not be the
*          same
* @throws RuntimeException
*             if the operation fails
*/</span>
<span style="color: #0000ff">public</span> Consumer update(Consumer entity);
<span style="color: #0000ff">public</span> Consumer findById(Integer id);
<span style="color: #008000">/**
* Find all Consumer entities with a specific property value.
*
* @param propertyName
*            the name of the Consumer property to query
* @param value
*            the property value to match
* @return List&lt;Consumer&gt; found by query
*/</span>
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findByProperty(String propertyName, Object value);
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findByName(Object name);
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findByPassword(Object password);
<span style="color: #008000">/**
* Find all Consumer entities.
*
* @return List&lt;Consumer&gt; all Consumer entities
*/</span>
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findAll();
}</pre>
<p>&nbsp;</p>
<p>DAO类</p>
<pre><span style="color: #0000ff">package</span> com.persia.entity;
<span style="color: #0000ff">import</span> java.util.List;
<span style="color: #0000ff">import</span> java.util.logging.Level;
<span style="color: #0000ff">import</span> javax.persistence.EntityManager;
<span style="color: #0000ff">import</span> javax.persistence.Query;
<span style="color: #008000">/**
* A data access object (DAO) providing persistence and search support for
* Consumer entities. Transaction control of the save(), update() and delete()
* operations must be handled externally by senders of these methods or must be
* manually added to each of these methods for data to be persisted to the JPA
* datastore.
*
* @see com.persia.entity.Consumer
* @author MyEclipse Persistence Tools
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ConsumerDAO <span style="color: #0000ff">implements</span> IConsumerDAO {
<span style="color: #008000">// property constants</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> String NAME = "<span style="color: #8b0000">name</span>";
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> String PASSWORD = "<span style="color: #8b0000">password</span>";
<span style="color: #0000ff">private</span> EntityManager getEntityManager() {
<span style="color: #0000ff">return</span> EntityManagerHelper.getEntityManager();
}
<span style="color: #008000">/**
* Perform an initial save of a previously unsaved Consumer entity. All
* subsequent persist actions of this entity should use the #update()
* method. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#persist(Object) EntityManager#persist}
* operation.
*
* &lt;pre&gt;
* EntityManagerHelper.beginTransaction();
* ConsumerDAO.save(entity);
* EntityManagerHelper.commit();
* &lt;/pre&gt;
*
* @param entity
*            Consumer entity to persist
* @throws RuntimeException
*             when the operation fails
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> save(Consumer entity) {
EntityManagerHelper.log("<span style="color: #8b0000">saving Consumer instance</span>", Level.INFO, <span style="color: #0000ff">null</span>);
<span style="color: #0000ff">try</span> {
getEntityManager().persist(entity);
EntityManagerHelper.log("<span style="color: #8b0000">save successful</span>", Level.INFO, <span style="color: #0000ff">null</span>);
} <span style="color: #0000ff">catch</span> (RuntimeException re) {
EntityManagerHelper.log("<span style="color: #8b0000">save failed</span>", Level.SEVERE, re);
<span style="color: #0000ff">throw</span> re;
}
}
<span style="color: #008000">/**
* Delete a persistent Consumer entity. This operation must be performed
* within the a database transaction context for the entity's data to be
* permanently deleted from the persistence store, i.e., database. This
* method uses the
* {@link javax.persistence.EntityManager#remove(Object) EntityManager#delete}
* operation.
*
* &lt;pre&gt;
* EntityManagerHelper.beginTransaction();
* ConsumerDAO.delete(entity);
* EntityManagerHelper.commit();
* entity = null;
* &lt;/pre&gt;
*
* @param entity
*            Consumer entity to delete
* @throws RuntimeException
*             when the operation fails
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> delete(Consumer entity) {
EntityManagerHelper.log("<span style="color: #8b0000">deleting Consumer instance</span>", Level.INFO, <span style="color: #0000ff">null</span>);
<span style="color: #0000ff">try</span> {
entity = getEntityManager().getReference(Consumer.<span style="color: #0000ff">class</span>,
entity.getId());
getEntityManager().remove(entity);
EntityManagerHelper.log("<span style="color: #8b0000">delete successful</span>", Level.INFO, <span style="color: #0000ff">null</span>);
} <span style="color: #0000ff">catch</span> (RuntimeException re) {
EntityManagerHelper.log("<span style="color: #8b0000">delete failed</span>", Level.SEVERE, re);
<span style="color: #0000ff">throw</span> re;
}
}
<span style="color: #008000">/**
* Persist a previously saved Consumer entity and return it or a copy of it
* to the sender. A copy of the Consumer entity parameter is returned when
* the JPA persistence mechanism has not previously been tracking the
* updated entity. This operation must be performed within the a database
* transaction context for the entity's data to be permanently saved to the
* persistence store, i.e., database. This method uses the
* {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
* operation.
*
* &lt;pre&gt;
* EntityManagerHelper.beginTransaction();
* entity = ConsumerDAO.update(entity);
* EntityManagerHelper.commit();
* &lt;/pre&gt;
*
* @param entity
*            Consumer entity to update
* @returns Consumer the persisted Consumer entity instance, may not be the
*          same
* @throws RuntimeException
*             if the operation fails
*/</span>
<span style="color: #0000ff">public</span> Consumer update(Consumer entity) {
EntityManagerHelper.log("<span style="color: #8b0000">updating Consumer instance</span>", Level.INFO, <span style="color: #0000ff">null</span>);
<span style="color: #0000ff">try</span> {
Consumer result = getEntityManager().merge(entity);
EntityManagerHelper.log("<span style="color: #8b0000">update successful</span>", Level.INFO, <span style="color: #0000ff">null</span>);
<span style="color: #0000ff">return</span> result;
} <span style="color: #0000ff">catch</span> (RuntimeException re) {
EntityManagerHelper.log("<span style="color: #8b0000">update failed</span>", Level.SEVERE, re);
<span style="color: #0000ff">throw</span> re;
}
}
<span style="color: #0000ff">public</span> Consumer findById(Integer id) {
EntityManagerHelper.log("<span style="color: #8b0000">finding Consumer instance with id: </span>" + id,
Level.INFO, <span style="color: #0000ff">null</span>);
<span style="color: #0000ff">try</span> {
Consumer instance = getEntityManager().find(Consumer.<span style="color: #0000ff">class</span>, id);
<span style="color: #0000ff">return</span> instance;
} <span style="color: #0000ff">catch</span> (RuntimeException re) {
EntityManagerHelper.log("<span style="color: #8b0000">find failed</span>", Level.SEVERE, re);
<span style="color: #0000ff">throw</span> re;
}
}
<span style="color: #008000">/**
* Find all Consumer entities with a specific property value.
*
* @param propertyName
*            the name of the Consumer property to query
* @param value
*            the property value to match
* @return List&lt;Consumer&gt; found by query
*/</span>
@SuppressWarnings("<span style="color: #8b0000">unchecked</span>")
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findByProperty(String propertyName, <span style="color: #0000ff">final</span> Object value) {
EntityManagerHelper.log("<span style="color: #8b0000">finding Consumer instance with property: </span>"
+ propertyName + "<span style="color: #8b0000">, value: </span>" + value, Level.INFO, <span style="color: #0000ff">null</span>);
<span style="color: #0000ff">try</span> {
<span style="color: #0000ff">final</span> String queryString = "<span style="color: #8b0000">select model from Consumer model where model.</span>"
+ propertyName + "<span style="color: #8b0000">= :propertyValue</span>";
Query query = getEntityManager().createQuery(queryString);
query.setParameter("<span style="color: #8b0000">propertyValue</span>", value);
<span style="color: #0000ff">return</span> query.getResultList();
} <span style="color: #0000ff">catch</span> (RuntimeException re) {
EntityManagerHelper.log("<span style="color: #8b0000">find by property name failed</span>",
Level.SEVERE, re);
<span style="color: #0000ff">throw</span> re;
}
}
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findByName(Object name) {
<span style="color: #0000ff">return</span> findByProperty(NAME, name);
}
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findByPassword(Object password) {
<span style="color: #0000ff">return</span> findByProperty(PASSWORD, password);
}
<span style="color: #008000">/**
* Find all Consumer entities.
*
* @return List&lt;Consumer&gt; all Consumer entities
*/</span>
@SuppressWarnings("<span style="color: #8b0000">unchecked</span>")
<span style="color: #0000ff">public</span> List&lt;Consumer&gt; findAll() {
EntityManagerHelper.log("<span style="color: #8b0000">finding all Consumer instances</span>", Level.INFO,
<span style="color: #0000ff">null</span>);
<span style="color: #0000ff">try</span> {
<span style="color: #0000ff">final</span> String queryString = "<span style="color: #8b0000">select model from Consumer model</span>";
Query query = getEntityManager().createQuery(queryString);
<span style="color: #0000ff">return</span> query.getResultList();
} <span style="color: #0000ff">catch</span> (RuntimeException re) {
EntityManagerHelper.log("<span style="color: #8b0000">find all failed</span>", Level.SEVERE, re);
<span style="color: #0000ff">throw</span> re;
}
}
}</pre>
<p>&nbsp;</p>
<p>还有一个非常有用的helper</p>
<pre><span style="color: #0000ff">package</span> com.persia.entity;
<span style="color: #0000ff">import</span> java.util.logging.Level;
<span style="color: #0000ff">import</span> java.util.logging.Logger;
<span style="color: #0000ff">import</span> javax.persistence.EntityManager;
<span style="color: #0000ff">import</span> javax.persistence.EntityManagerFactory;
<span style="color: #0000ff">import</span> javax.persistence.Persistence;
<span style="color: #0000ff">import</span> javax.persistence.Query;
<span style="color: #008000">/**
* @author MyEclipse Persistence Tools
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> EntityManagerHelper {
<span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> EntityManagerFactory emf;
<span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> ThreadLocal&lt;EntityManager&gt; threadLocal;
<span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">final</span> Logger logger;
<span style="color: #0000ff">static</span> {
emf = Persistence.createEntityManagerFactory("<span style="color: #8b0000">JPAWebPU</span>");
threadLocal = <span style="color: #0000ff">new</span> ThreadLocal&lt;EntityManager&gt;();
logger = Logger.getLogger("<span style="color: #8b0000">JPAWebPU</span>");
logger.setLevel(Level.ALL);
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> EntityManager getEntityManager() {
EntityManager manager = threadLocal.get();
<span style="color: #0000ff">if</span> (manager == <span style="color: #0000ff">null</span> || !manager.isOpen()) {
manager = emf.createEntityManager();
threadLocal.set(manager);
}
<span style="color: #0000ff">return</span> manager;
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> closeEntityManager() {
EntityManager em = threadLocal.get();
threadLocal.set(<span style="color: #0000ff">null</span>);
<span style="color: #0000ff">if</span> (em != <span style="color: #0000ff">null</span>) em.close();
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> beginTransaction() {
getEntityManager().getTransaction().begin();
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> commit() {
getEntityManager().getTransaction().commit();
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> rollback() {
getEntityManager().getTransaction().rollback();
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> Query createQuery(String query) {
<span style="color: #0000ff">return</span> getEntityManager().createQuery(query);
}
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> log(String info, Level level, Throwable ex) {
logger.log(level, info, ex);
}
}
</pre>
<p>&nbsp;</p>
<p>然后使用helper和dao进行测试</p>
<pre><span style="color: #0000ff">package</span> com.jpa.test;
<span style="color: #0000ff">import</span> java.util.List;
<span style="color: #0000ff">import</span> com.persia.entity.Consumer;
<span style="color: #0000ff">import</span> com.persia.entity.ConsumerDAO;
<span style="color: #0000ff">import</span> com.persia.entity.EntityManagerHelper;
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> JPATest {
<span style="color: #008000">/**
* @param args
*/</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) {
<span style="color: #008000">// 1.创建 DAO</span>
ConsumerDAO dao = <span style="color: #0000ff">new</span> ConsumerDAO();
<span style="color: #008000">// 2.创建实体类</span>
Consumer c = <span style="color: #0000ff">new</span> Consumer();
c.setName("<span style="color: #8b0000">jpa01</span>");
c.setPassword("<span style="color: #8b0000">jianchi</span>");
<span style="color: #008000">// 开始事务 </span>
EntityManagerHelper.beginTransaction();
<span style="color: #008000">// 3. 保存</span>
dao.save(c);
<span style="color: #008000">// 提交事务真正保存实体到数据库</span>
EntityManagerHelper.commit();
<span style="color: #008000">// 4. 列出数据库中所有对象</span>
List&lt;Consumer&gt; result = dao.findAll();
<span style="color: #0000ff">for</span>(Consumer o : result) {
System.out.println(o.getId());
System.out.println(o.getName());
}
}
}
</pre>
<p>&nbsp;</p>
<p>测试实例如下：</p>
<pre><span style="color: #0000ff">package</span> test;
<span style="color: #0000ff">import</span> java.util.List;
<span style="color: #0000ff">import</span> dao.*;
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> JPATest {
<span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) {
<span style="color: #008000">// 1.创建 DAO</span>
StudentDAO dao = <span style="color: #0000ff">new</span> StudentDAO();
<span style="color: #008000">// 2.创建实体类</span>
Student user = <span style="color: #0000ff">new</span> Student();
user.setUsername("<span style="color: #8b0000">hellojpa test</span>");
user.setPassword("<span style="color: #8b0000">jpa password</span>");
user.setAge(20);
<span style="color: #008000">// 开始事务 </span>
EntityManagerHelper.beginTransaction();
<span style="color: #008000">// 3. 保存</span>
dao.save(user);
<span style="color: #008000">// 提交事务真正保存实体到数据库</span>
EntityManagerHelper.commit();
<span style="color: #008000">// 4. 列出数据库中所有对象</span>
List&lt;Student&gt; result = dao.findAll();
<span style="color: #0000ff">for</span>(Student o : result) {
System.out.println(o.getId());
System.out.println(o.getUsername());
}
<span style="color: #008000">// 5. 更改用户名</span>
user.setUsername("<span style="color: #8b0000">测试JPA</span>");
<span style="color: #008000">// 开始事务 </span>
EntityManagerHelper.beginTransaction();
<span style="color: #008000">// 保存（JPA会自动更新变动过的字段）</span>
dao.update(user);
<span style="color: #008000">// 提交事务真正保存实体到数据库</span>
EntityManagerHelper.commit();
<span style="color: #008000">// 6. 查找所有年龄为20的用户，从第1个开始获取（第0个是第一条记录）</span>
result = dao.findByAge(20, 1);
<span style="color: #0000ff">for</span>(Student o : result) {
System.out.println(o.getId());
System.out.println(o.getUsername());
}
<span style="color: #008000">// 7. 根据 ID 查找</span>
user = dao.findById(2);
System.out.println(user.getUsername());
<span style="color: #008000">// 8. 删除</span>
<span style="color: #008000">// 开始事务 </span>
EntityManagerHelper.beginTransaction();
<span style="color: #008000">// 保存（JPA会自动更新变动过的字段）</span>
dao.delete(user);
<span style="color: #008000">// 提交事务真正保存实体到数据库</span>
EntityManagerHelper.commit();
}
}</pre>
<p>&nbsp;</p>
<p>若部署到tomcat，没有什么问题，也不要额外添加什么。</p>
</div>
<img src ="http://www.blogjava.net/luluyanglu/aggbug/259907.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/luluyanglu/" target="_blank">大鱼</a> 2009-03-16 00:09 <a href="http://www.blogjava.net/luluyanglu/archive/2009/03/16/259907.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPA是什么</title><link>http://www.blogjava.net/luluyanglu/archive/2009/03/15/259902.html</link><dc:creator>大鱼</dc:creator><author>大鱼</author><pubDate>Sun, 15 Mar 2009 15:42:00 GMT</pubDate><guid>http://www.blogjava.net/luluyanglu/archive/2009/03/15/259902.html</guid><wfw:comment>http://www.blogjava.net/luluyanglu/comments/259902.html</wfw:comment><comments>http://www.blogjava.net/luluyanglu/archive/2009/03/15/259902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/luluyanglu/comments/commentRss/259902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/luluyanglu/services/trackbacks/259902.html</trackback:ping><description><![CDATA[<div class="postTitle">JPA是什么 </div>
定义 Java Persistence API<br />
JPA通过JDK 5.0注解或XML描述对象－关系表的映射关系，并将运行期的实体对象持久化到数据库中。
<h2>起源</h2>
Sun引入新的JPA ORM规范出于两个原因：其一，简化现有Java EE和Java SE应用的对象持久化的开发工作；其二，Sun希望整合对ORM技术，实现天下归一。<br />
JPA由EJB 3.0软件专家组开发，作为JSR-220实现的一部分。但它不囿于EJB 3.0，你可以在Web应用、甚至桌面应用中使用。JPA的宗旨是为POJO提供持久化标准规范，由此可见，经过这几年的实践探索，能够脱离容器独立运 行，方便开发和测试的理念已经深入人心了。目前Hibernate 3.2、TopLink 10.1.3以及OpenJPA都提供了JPA的实现。<br />
JPA的总体思想和现有Hibernate、TopLink，JDO等ORM框架大体一致。总的来说，JPA包括以下3方面的技术：<br />
<strong>ORM映射元数据</strong><br />
JPA支持XML和JDK 5.0注解两种元数据的形式，元数据描述对象和表之间的映射关系，框架据此将实体对象持久化到数据库表中；<br />
<strong>JPA 的API</strong><br />
用来操作实体对象，执行CRUD操作，框架在后台替我们完成所有的事情，开发者从繁琐的JDBC和SQL代码中解脱出来。<br />
<strong>查询语言</strong><br />
这是持久化操作中很重要的一个方面，通过面向对象而非面向数据库的查询语言查询数据，避免程序的SQL语句紧密耦合。
<h2>JPA的优势</h2>
<strong>1 标准化</strong><br />
JPA 是 JCP 组织发布的 Java EE 标准之一，因此任何声称符合 JPA 标准的框架都遵循同样的架构，提供相同的访问 API，这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。<br />
<strong>2 对容器级特性的支持</strong><br />
JPA 框架中支持大数据集、事务、并发等容器级事务，这使得 JPA 超越了简单持久化框架的局限，在企业应用发挥更大的作用。<br />
<strong>3 简单易用，集成方便</strong><br />
JPA的主要目标之一就是提供更加简单的编程模型：在JPA框架下创建实体和创建Java 类一样简单，没有任何的约束和限制，只需要使用 javax.persistence.Entity进行注释；JPA的框架和接口也都非常简单，没有太多特别的规则和设计模式的要求，开发者可以很容易的 掌握。JPA基于非侵入式原则设计，因此可以很容易的和其它框架或者容器集成。<br />
<strong>4 可媲美JDBC的查询能力</strong><br />
JPA的查询语言是面向对象而非面向数据库的，它以面向对象的自然语法构造查询语句，可以看成 是Hibernate HQL的等价物。JPA定义了独特的JPQL（Java Persistence Query Language），JPQL是EJB QL的一种扩展，它是针对实体的一种查询语言，操作对象是实体，而不是关系数据库的表，而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性，甚至还能够支持子查询。<br />
<strong>5 支持面向对象的高级特性</strong><br />
JPA 中能够支持面向对象的高级特性，如类之间的继承、多态和类之间的复杂关系，这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用，而不需要自行处理这些特性在关系数据库的持久化。
<h2>JPA的供应商</h2>
JPA 的目标之一是制定一个可以由很多供应商实现的API，并且开发人员可以编码来实现该API，而不是使用私有供应商特有的API。因此开发人员只需使用供应 商特有的API来获得JPA规范没有解决但应用程序中需要的功能。尽可能地使用JPA API，但是当需要供应商公开但是规范中没有提供的功能时，则使用供应商特有的API。<br />
<strong>1 Hibernate</strong><br />
JPA是需要Provider来实现其功能的，Hibernate就是JPA Provider中很强的一个，目前来说应该无人能出其右。从功能上来说，JPA现在就是Hibernate功能的一个子集。Hibernate 从3.2开始，就开始兼容JPA。Hibernate3.2获得了Sun TCK的JPA(Java Persistence API) 兼容认证。<br />
只要熟悉Hibernate或者其他ORM框架，在使用JPA时会发现其实非常容易上手。例如 实体对象的状态，在Hibernate有自由、持久、游离三种，JPA里有new，managed，detached，removed，明眼人一看就知 道，这些状态都是一一对应的。再如flush方法，都是对应的，而其他的再如说Query query = manager.createQuery(sql)，它在Hibernate里写法上是session，而在JPA中变成了manager，所以从 Hibernate到JPA的代价应该是非常小的<br />
同样，JDO，也开始兼容JPA。在ORM的领域中，看来JPA已经是王道，规范就是规范。在各大厂商的支持下，JPA的使用开始变得广泛。<br />
<strong>2 Spring</strong><br />
Spring + Hibernate 常常被称为 Java Web 应用人气最旺的框架组合。而在 JCP 通过的 Web Beans JSR ，却欲将JSF + EJB + JPA 、来自 JBoss Seam（Spring 除外）的一些组件和EJB 3（目前能够提供有基本拦截和依赖注入功能的简化 Session Bean 框架）的一个 Web 组合进行标准化。如今的 Spring 2.0 为 JPA 提供了完整的 EJB 容器契约，允许 JPA在任何环境内可以在 Spring 管理的服务层使用（包括 Spring 的所有 AOP 和 DI 增强）。同时，关于下一个Web应用组合会是 EJB、Spring + Hibernate 还是 Spring + JPA 的论战，早已充斥于耳。<br />
在Spring 2.0.1中，正式提供对JPA的支持，这也促成了JPA的发展，要知道JPA的好处在于可以分离于容器运行，变得更加的简洁。<br />
<strong>3 OpenJPA</strong><br />
OpenJPA 是 Apache 组织提供的开源项目，它实现了 EJB 3.0 中的 JPA 标准，为开发者提供功能强大、使用简单的持久化数据管理框架。OpenJPA 封装了和关系型数据库交互的操作，让开发者把注意力集中在编写业务逻辑上。OpenJPA 可以作为独立的持久层框架发挥作用，也可以轻松的与其它 Java EE 应用框架或者符合 EJB 3.0 标准的容器集成。<br />
<strong>4 其它</strong><br />
目前支持的实现包括Toplink、Hibernate Entitymanager等。TopLink以前需要收费，如今开源了。OpenJPA虽然免费，但功能、性能、普及性等方面更加需要加大力度。<br />
对于EJB来说，实体Bean一直是被批评的对象，由于其太复杂和庞大。JPA的出现，很大程度的分离了复杂性。这让EJB的推广也变得容易。<br />
总而言之，JPA规范主要关注的仅是API的行为方面，而由各种实现完成大多数性能有关的调优。尽管如此，所有可靠的实现都应该拥有某种数据缓存，以作为选择。但愿不久的将来，JPA能成为真正的标准。<br />
<strong>小结</strong><br />
EJB 3.0和JPA 毫无疑问将是Java EE 5的主要卖点。在某些领域中，它们给Java社区带来了竞争优势，并使Java 在其他领域与竞争对手不分伯仲（因为，不可否认，目前某些领域尚不存在基于标准的方法）。<br />
过去数年来，Spring Framework一直是EJB在企业领域的主要竞争对手。EJB3.0规范解决了很多促进Spring兴起的问题。随着它的出现，EJB3.0毫无疑问比Spring提供了更好的开发体验——最引人注目的优势是它不需要配置文件。<br />
JPA提供一种标准的OR映射解决方案，该解决方案完全集成到EJB3。0兼容的容器中。JPA的前辈将会继续稳定发展，但是业务应用程序中的 raw 使用将可能会减少。实现 JPA 兼容的实体管理器似乎很可能是此类技术的发展方向。<br />
Java EE系列规范的较大问题与JPA没有任何关系。Java EE 系列规范的问题涉及到 Web和EJB容器之间的集成。Spring在此领域仍然具有主要竞争优势。JBoss的Seam项目尝试使用自定义的方法来解决这一问题。Caucho Resin应用服务器试图扩展容器边界并支持在Web容器中使用@EJB注释。我们希望Java EE 5.1将解决层集成的问题，为我们提供一个全面而标准的依赖性注入方法。<br />
在不久的将来，Sun可能会将JPA作为一个单独的JSR对待，同时JPA还可能作为Java SE的一部分。不过这些都不太重要，重要的是，我们现在已经可以在脱离容器的情况下、在Java SE应用中使用JPA了。 <br />
JPA已经作为一项对象持久化的标准，不但可以获得Java EE应用服务器的支持，还可以直接在Java SE中使用。开发者将无需在现有多种ORM框架中艰难地选择，按照Sun的预想，现有ORM框架头顶的光环将渐渐暗淡，不再具有以往的吸引力。 
<img src ="http://www.blogjava.net/luluyanglu/aggbug/259902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/luluyanglu/" target="_blank">大鱼</a> 2009-03-15 23:42 <a href="http://www.blogjava.net/luluyanglu/archive/2009/03/15/259902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JPA注释参考手册</title><link>http://www.blogjava.net/luluyanglu/archive/2009/03/15/259895.html</link><dc:creator>大鱼</dc:creator><author>大鱼</author><pubDate>Sun, 15 Mar 2009 14:41:00 GMT</pubDate><guid>http://www.blogjava.net/luluyanglu/archive/2009/03/15/259895.html</guid><wfw:comment>http://www.blogjava.net/luluyanglu/comments/259895.html</wfw:comment><comments>http://www.blogjava.net/luluyanglu/archive/2009/03/15/259895.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/luluyanglu/comments/commentRss/259895.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/luluyanglu/services/trackbacks/259895.html</trackback:ping><description><![CDATA[<div>
<h2>Table</h2>
<p>Table用来定义entity主表的name，catalog，schema等属性。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name: 表名
    <li>catalog: 对应关系数据库中的catalog
    <li>schema：对应关系数据库中的schema
    <li>UniqueConstraints:定义一个UniqueConstraint数组，指定需要建唯一约束的列 </li>
</ul>
<div>
<pre>    <br />
@Entity<br />
@Table(name="CUST")<br />
public class Customer { ... }<br />
　　</pre>
</div>
</div>
<div>
<h2>SecondaryTable</h2>
<p>一个entity class可以映射到多表，SecondaryTable用来定义单个从表的名字，主键名字等属性。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name: 表名
    <li>catalog: 对应关系数据库中的catalog
    <li>schema：对应关系数据库中的schema
    <li>pkJoin: 定义一个PrimaryKeyJoinColumn数组，指定从表的主键列
    <li>UniqueConstraints:定义一个UniqueConstraint数组，指定需要建唯一约束的列 </li>
</ul>
<p>下面的代码说明Customer类映射到两个表，主表名是CUSTOMER，从表名是CUST_DETAIL，从表的主键列和主表的主键列类型相同，列名为CUST_ID。 </p>
<div>
<pre>                <br />
@Entity<br />
@Table(name="CUSTOMER")<br />
@SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_ID"))<br />
public class Customer { ... }<br />
<br />
</pre>
</div>
</div>
<div>
<h2>SecondaryTables</h2>
<p>当一个entity class映射到一个主表和多个从表时，用SecondaryTables来定义各个从表的属性。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>value： 定义一个SecondaryTable数组，指定每个从表的属性。 </li>
</ul>
<div>
<pre>                <br />
@Table(name = "CUSTOMER")<br />
@SecondaryTables( value = {<br />
@SecondaryTable(name = "CUST_NAME", pkJoin = { @PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }),<br />
@SecondaryTable(name = "CUST_ADDRESS", pkJoin = { @PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }) })<br />
public class Customer {}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>UniqueConstraint</h2>
<p>UniqueConstraint定义在Table或SecondaryTable元数据里，用来指定建表时需要建唯一约束的列。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>columnNames:定义一个字符串数组，指定要建唯一约束的列名。 </li>
</ul>
<div>
<pre>                <br />
@Entity<br />
@Table(name="EMPLOYEE",<br />
uniqueConstraints={@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})}<br />
)<br />
public class Employee { ... }<br />
<br />
</pre>
</div>
</div>
<div>
<h2>Column</h2>
<p>Column元数据定义了映射到数据库的列的所有属性：列名，是否唯一，是否允许为空，是否允许更新等。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name:列名。
    <li>unique: 是否唯一
    <li>nullable: 是否允许为空
    <li>insertable: 是否允许插入
    <li>updatable: 是否允许更新
    <li>columnDefinition: 定义建表时创建此列的DDL
    <li>secondaryTable: 从表名。如果此列不建在主表上（默认建在主表），该属性定义该列所在从表的名字。 </li>
</ul>
<div>
<pre>        <br />
public class Person {<br />
@Column(name = "PERSONNAME", unique = true, nullable = false, updatable = true)<br />
private String name;<br />
<br />
@Column(name = "PHOTO", columnDefinition = "BLOB NOT NULL", secondaryTable="PER_PHOTO")<br />
private byte[] picture;<br />
<br />
</pre>
</div>
</div>
<div>
<h2>JoinColumn</h2>
<p>如果在entity class的field上定义了关系（one2one或one2many等），我们通过JoinColumn来定义关系的属性。JoinColumn的大部分属性和Column类似。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name:列名。
    <li>referencedColumnName:该列指向列的列名（建表时该列作为外键列指向关系另一端的指定列）
    <li>unique: 是否唯一
    <li>nullable: 是否允许为空
    <li>insertable: 是否允许插入
    <li>updatable: 是否允许更新
    <li>columnDefinition: 定义建表时创建此列的DDL
    <li>secondaryTable: 从表名。如果此列不建在主表上（默认建在主表），该属性定义该列所在从表的名字。 </li>
</ul>
<p>下面的代码说明Custom和Order是一对一关系。在Order对应的映射表建一个名为CUST_ID的列，该列作为外键指向Custom对应表中名为ID的列。 </p>
<div>
<pre>                <br />
public class Custom {<br />
<br />
@OneToOne<br />
@JoinColumn(<br />
name="CUST_ID", referencedColumnName="ID", unique=true, nullable=true, updatable=true)<br />
public order getOrder() {<br />
return order;<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>JoinColumns</h2>
<p>如果在entity class的field上定义了关系（one2one或one2many等），并且关系存在多个JoinColumn，用JoinColumns定义多个JoinColumn的属性。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>value: 定义JoinColumn数组，指定每个JoinColumn的属性。 </li>
</ul>
<p>下面的代码说明Custom和Order是一对一关系。在Order对应的映射表建两列，一列名为CUST_ID，该列作为外键指向Custom对应表中名为ID的列,另一列名为CUST_NAME，该列作为外键指向Custom对应表中名为NAME的列。 </p>
<div>
<pre>                <br />
public class Custom {<br />
@OneToOne<br />
@JoinColumns({<br />
@JoinColumn(name="CUST_ID", referencedColumnName="ID"),<br />
@JoinColumn(name="CUST_NAME", referencedColumnName="NAME")<br />
})<br />
public order getOrder() {<br />
return order;<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>Id</h2>
<p>声明当前field为映射表中的主键列。id值的获取方式有五种：TABLE, SEQUENCE, IDENTITY, AUTO, NONE。Oracle和DB2支持SEQUENCE，SQL Server和Sybase支持IDENTITY,mysql支持AUTO。所有的数据库都可以指定为AUTO，我们会根据不同数据库做转换。NONE (默认)需要用户自己指定Id的值。元数据属性说明： </p>
<ul>
    <li>generate():主键值的获取类型
    <li>generator():TableGenerator的名字（当generate=GeneratorType.TABLE才需要指定该属性） </li>
</ul>
<p>下面的代码声明Task的主键列id是自动增长的。(Oracle和DB2从默认的SEQUENCE取值，SQL Server和Sybase该列建成IDENTITY，mysql该列建成auto increment。) </p>
<div>
<pre>                <br />
@Entity<br />
@Table(name = "OTASK")<br />
public class Task {<br />
@Id(generate = GeneratorType.AUTO)<br />
public Integer getId() {<br />
return id;<br />
}<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>IdClass</h2>
<p>当entity class使用复合主键时，需要定义一个类作为id class。id class必须符合以下要求:类必须声明为public，并提供一个声明为public的空构造函数。必须实现Serializable接，覆写 equals()和hashCode（）方法。entity class的所有id field在id class都要定义，且类型一样。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>value: id class的类名 </li>
</ul>
<p>&nbsp; </p>
<div>
<pre>                <br />
public class EmployeePK implements java.io.Serializable{<br />
String empName;<br />
Integer empAge;<br />
<br />
public EmployeePK(){}<br />
<br />
public boolean equals(Object obj){ ......}<br />
public int hashCode(){......}<br />
}<br />
<br />
<br />
@IdClass(value=com.acme.EmployeePK.class)<br />
@Entity(access=FIELD)<br />
public class Employee {<br />
@Id String empName;<br />
@Id Integer empAge;<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>MapKey</h2>
<p>在一对多，多对多关系中，我们可以用Map来保存集合对象。默认用主键值做key，如果使用复合主键，则用id class的实例做key，如果指定了name属性，就用指定的field的值做key。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name: 用来做key的field名字 </li>
</ul>
<p>下面的代码说明Person和Book之间是一对多关系。Person的books字段是Map类型，用Book的isbn字段的值作为Map的key。 </p>
<div>
<pre>                <br />
@Table(name = "PERSON")<br />
public class Person {<br />
<br />
@OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL, mappedBy = "person")<br />
@MapKey(name = "isbn")<br />
private Map books = new HashMap();<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>OrderBy</h2>
<p>在一对多，多对多关系中，有时我们希望从数据库加载出来的集合对象是按一定方式排序的，这可以通过OrderBy来实现，默认是按对象的主键升序排列。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>value: 字符串类型，指定排序方式。格式为"fieldName1 [ASC|DESC],fieldName2 [ASC|DESC],......",排序类型可以不指定，默认是ASC。 </li>
</ul>
<p>下面的代码说明Person和Book之间是一对多关系。集合books按照Book的isbn升序，name降序排列。 </p>
<div>
<pre>                <br />
@Table(name = "MAPKEY_PERSON")<br />
public class Person {<br />
<br />
@OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL, mappedBy = "person")<br />
@OrderBy(name = "isbn ASC, name DESC")<br />
private List books = new ArrayList();<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>PrimaryKeyJoinColumn</h2>
<p>在三种情况下会用到PrimaryKeyJoinColumn。 </p>
<ul>
    <li>继承。
    <li>entity class映射到一个或多个从表。从表根据主表的主键列（列名为referencedColumnName值的列），建立一个类型一样的主键列，列名由name属性定义。
    <li>one2one关系，关系维护端的主键作为外键指向关系被维护端的主键，不再新建一个外键列。 </li>
</ul>
<p>&nbsp; </p>
<p>元数据属性说明： </p>
<ul>
    <li>name:列名。
    <li>referencedColumnName:该列引用列的列名
    <li>columnDefinition: 定义建表时创建此列的DDL </li>
</ul>
<p>下面的代码说明Customer映射到两个表，主表CUSTOMER,从表CUST_DETAIL，从表需要建立主键列CUST_ID，该列和主表的主键列id除了列名不同，其他定义一样。 </p>
<div>
<pre>            <br />
@Entity<br />
@Table(name="CUSTOMER")<br />
@SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_ID"，referencedColumnName="id"))<br />
public class Customer { <br />
@Id(generate = GeneratorType.AUTO)<br />
public Integer getId() {<br />
return id;<br />
}<br />
}<br />
<br />
</pre>
</div>
<p>下面的代码说明Employee和EmployeeInfo是一对一关系，Employee的主键列id作为外键指向EmployeeInfo的主键列INFO_ID。 </p>
<div>
<pre>            <br />
@Table(name = "Employee")<br />
public class Employee {<br />
@OneToOne<br />
@PrimaryKeyJoinColumn(name = "id", referencedColumnName="INFO_ID")<br />
EmployeeInfo info;<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>PrimaryKeyJoinColumns</h2>
<p>如果entity class使用了复合主键，指定单个PrimaryKeyJoinColumn不能满足要求时，可以用PrimaryKeyJoinColumns来定义多个PrimaryKeyJoinColumn。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>value: 一个PrimaryKeyJoinColumn数组，包含所有PrimaryKeyJoinColumn。 </li>
</ul>
<p>下面的代码说明了Employee和EmployeeInfo是一对一关系。他们都使用复合主键，建表时需要在Employee表建立一个外键，从Employee的主键列id,name指向EmployeeInfo的主键列INFO_ID和INFO_NAME. </p>
<div>
<pre>            <br />
@Entity<br />
@IdClass(EmpPK.class)<br />
@Table(name = "EMPLOYEE")<br />
public class Employee {<br />
<br />
private int id;<br />
<br />
private String name;<br />
<br />
private String address;<br />
<br />
@OneToOne(cascade = CascadeType.ALL)<br />
@PrimaryKeyJoinColumns({<br />
@PrimaryKeyJoinColumn(name="id", referencedColumnName="INFO_ID"),<br />
@PrimaryKeyJoinColumn(name="name" , referencedColumnName="INFO_NAME")})<br />
EmployeeInfo info;<br />
}<br />
<br />
@Entity<br />
@IdClass(EmpPK.class)<br />
@Table(name = "EMPLOYEE_INFO")<br />
public class EmployeeInfo {<br />
<br />
@Id<br />
@Column(name = "INFO_ID")<br />
private int id;<br />
<br />
@Id<br />
@Column(name = "INFO_NAME")<br />
private String name;<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>Transient</h2>
<p>Transient用来注释entity的属性，指定的这些属性不会被持久化，也不会为这些属性建表。 </p>
<div>
<pre>    <br />
@Transient<br />
private String name;<br />
<br />
</pre>
</div>
</div>
<div>
<h2>Version</h2>
<p>Version指定实体类在乐观事务中的version属性。在实体类重新由EntityManager管理并且加入到乐观事务中时，保证完整性。每一个类只能有一个属性被指定为version，version属性应该映射到实体类的主表上。 </p>
<p>下面的代码说明versionNum属性作为这个类的version，映射到数据库中主表的列名是OPTLOCK。 </p>
<div>
<pre>                <br />
@Version<br />
@Column("OPTLOCK")<br />
protected int getVersionNum() { return versionNum; }<br />
<br />
</pre>
</div>
</div>
<div>
<h2>Lob</h2>
<p>Lob指定一个属性作为数据库支持的大对象类型在数据库中存储。使用LobType这个枚举来定义Lob是二进制类型还是字符类型。 </p>
<p>LobType枚举类型说明： </p>
<ul>
    <li>BLOB 二进制大对象，Byte[]或者Serializable的类型可以指定为BLOB。
    <li>CLOB 字符型大对象，char[]、Character[]或String类型可以指定为CLOB。 </li>
</ul>
<p>元数据属性说明： </p>
<ul>
    <li>fetch： 定义这个字段是lazy loaded还是eagerly fetched。数据类型是FetchType枚举，默认为LAZY,即lazy loaded.
    <li>type： 定义这个字段在数据库中的JDBC数据类型。数据类型是LobType枚举，默认为BLOB。 </li>
</ul>
<p>下面的代码定义了一个BLOB类型的属性和一个CLOB类型的属性。 </p>
<div>
<pre>                <br />
@Lob<br />
@Column(name="PHOTO" columnDefinition="BLOB NOT NULL")<br />
protected JPEGImage picture;<br />
<br />
@Lob(fetch=EAGER, type=CLOB)<br />
@Column(name="REPORT")<br />
protected String report;<br />
<br />
</pre>
</div>
</div>
<div>
<h2>JoinTable</h2>
<p>JoinTable在many-to-many关系的所有者一边定义。如果没有定义JoinTable，使用JoinTable的默认值。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>table:这个join table的Table定义。
    <li>joinColumns:定义指向所有者主表的外键列，数据类型是JoinColumn数组。
    <li>inverseJoinColumns:定义指向非所有者主表的外键列，数据类型是JoinColumn数组。 </li>
</ul>
<p>下面的代码定义了一个连接表CUST和PHONE的join table。join table的表名是CUST_PHONE，包含两个外键，一个外键是CUST_ID，指向表CUST的主键ID，另一个外键是PHONE_ID，指向表PHONE的主键ID。 </p>
<div>
<pre>                <br />
@JoinTable(<br />
table=@Table(name=CUST_PHONE),<br />
joinColumns=@JoinColumn(name="CUST_ID", referencedColumnName="ID"),<br />
inverseJoinColumns=@JoinColumn(name="PHONE_ID", referencedColumnName="ID")<br />
)<br />
<br />
</pre>
</div>
</div>
<div>
<h2>TableGenerator</h2>
<p>TableGenerator定义一个主键值生成器，在Id这个元数据的generate＝TABLE时，generator属性中可以使用生成器的名字。生成器可以在类、方法或者属性上定义。 </p>
<p>生成器是为多个实体类提供连续的ID值的表，每一行为一个类提供ID值，ID值通常是整数。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name:生成器的唯一名字，可以被Id元数据使用。
    <li>table:生成器用来存储id值的Table定义。
    <li>pkColumnName:生成器表的主键名称。
    <li>valueColumnName:生成器表的ID值的列名称。
    <li>pkColumnValue:生成器表中的一行数据的主键值。
    <li>initialValue:id值的初始值。
    <li>allocationSize:id值的增量。 </li>
</ul>
<p>下面的代码定义了两个生成器empGen和addressGen，生成器的表是ID_GEN。 </p>
<div>
<pre>                <br />
@Entity public class Employee {<br />
...<br />
@TableGenerator(name="empGen",<br />
table=@Table(name="ID_GEN"),<br />
pkColumnName="GEN_KEY",<br />
valueColumnName="GEN_VALUE",<br />
pkColumnValue="EMP_ID",<br />
allocationSize=1)<br />
@Id(generate=TABLE, generator="empGen")<br />
public int id;<br />
...<br />
}<br />
<br />
@Entity public class Address {<br />
...<br />
@TableGenerator(name="addressGen",<br />
table=@Table(name="ID_GEN"),<br />
pkColumnValue="ADDR_ID")<br />
@Id(generate=TABLE, generator="addressGen")<br />
public int id;<br />
...<br />
}<br />
<br />
</pre>
</div>
</div>
<div>
<h2>SequenceGenerator</h2>
<p>SequenceGenerator定义一个主键值生成器，在Id这个元数据的generator属性中可以使用生成器的名字。生成器可以在类、方法或者属性上定义。生成器是数据库支持的sequence对象。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name:生成器的唯一名字，可以被Id元数据使用。
    <li>sequenceName:数据库中，sequence对象的名称。如果不指定，会使用提供商指定的默认名称。
    <li>initialValue:id值的初始值。
    <li>allocationSize:id值的增量。 </li>
</ul>
<p>下面的代码定义了一个使用提供商默认名称的sequence生成器。 </p>
<div>
<pre>                <br />
@SequenceGenerator(name="EMP_SEQ", allocationSize=25)	<br />
<br />
</pre>
</div>
</div>
<div>
<h2>DiscriminatorColumn</h2>
<p>DiscriminatorColumn定义在使用SINGLE_TABLE或JOINED继承策略的表中区别不继承层次的列。 </p>
<p>元数据属性说明： </p>
<ul>
    <li>name:column的名字。默认值为TYPE。
    <li>columnDefinition:生成DDL的sql片断。
    <li>length:String类型的column的长度，其他类型使用默认值10。 </li>
</ul>
<p>下面的代码定义了一个列名为DISC，长度为20的String类型的区别列。 </p>
<div>
<pre>                <br />
@Entity<br />
@Table(name="CUST")<br />
@Inheritance(strategy=SINGLE_TABLE,<br />
discriminatorType=STRING,<br />
discriminatorValue="CUSTOMER")<br />
@DiscriminatorColumn(name="DISC", length=20)<br />
public class Customer { ... }</pre>
</div>
</div>
<br />
<img src ="http://www.blogjava.net/luluyanglu/aggbug/259895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/luluyanglu/" target="_blank">大鱼</a> 2009-03-15 22:41 <a href="http://www.blogjava.net/luluyanglu/archive/2009/03/15/259895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>