﻿<?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/lizhuxin/category/33761.html</link><description>☆</description><language>zh-cn</language><lastBuildDate>Thu, 14 Aug 2008 06:47:49 GMT</lastBuildDate><pubDate>Thu, 14 Aug 2008 06:47:49 GMT</pubDate><ttl>60</ttl><item><title>JPA标签语言的使用和配置</title><link>http://www.blogjava.net/lizhuxin/articles/221958.html</link><dc:creator>☆</dc:creator><author>☆</author><pubDate>Thu, 14 Aug 2008 04:37:00 GMT</pubDate><guid>http://www.blogjava.net/lizhuxin/articles/221958.html</guid><wfw:comment>http://www.blogjava.net/lizhuxin/comments/221958.html</wfw:comment><comments>http://www.blogjava.net/lizhuxin/articles/221958.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lizhuxin/comments/commentRss/221958.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lizhuxin/services/trackbacks/221958.html</trackback:ping><description><![CDATA[JPA标签语言的使用和配置：<br />
<br />
<p>&lt;http://leelun.javaeye.com/blog/36829&gt; 常用的JPA标记</p>
<p>关键字: jpa annotation <br />
Table</p>
<p>Table用来定义entity主表的name，catalog，schema等属性。</p>
<p>元数据属性说明：</p>
<p>* name: 表名 <br />
* catalog: 对应关系数据库中的catalog <br />
* schema：对应关系数据库中的schema <br />
* UniqueConstraints:定义一个UniqueConstraint数组，指定需要建唯一约束的<br />
列 </p>
<p><br />
@Entity<br />
@Table(name="CUST")<br />
public class Customer { ... }<br />
　　</p>
<p>SecondaryTable</p>
<p><br />
一个entity class可以映射到多表，SecondaryTable用来定义单个从表的名字，主键名<br />
字等属性。</p>
<p>元数据属性说明：</p>
<p>* name: 表名 <br />
* catalog: 对应关系数据库中的catalog <br />
* schema：对应关系数据库中的schema <br />
* pkJoin: 定义一个PrimaryKeyJoinColumn数组，指定从表的主键列 <br />
* UniqueConstraints:定义一个UniqueConstraint数组，指定需要建唯一约束的<br />
列 </p>
<p>下面的代码说明Customer类映射到两个表，主表名是CUSTOMER，从表名是<br />
CUST_DETAIL，从表的主键列和主表的主键列类型相同，列名为CUST_ID。</p>
<p><br />
@Entity<br />
@Table(name="CUSTOMER")</p>
<p>@SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_I<br />
D"))<br />
public class Customer { ... }</p>
<p>&nbsp;</p>
<p>SecondaryTables</p>
<p><br />
当一个entity class映射到一个主表和多个从表时，用SecondaryTables来定义各个从<br />
表的属性。</p>
<p>元数据属性说明：</p>
<p>* value： 定义一个SecondaryTable数组，指定每个从表的属性。 </p>
<p><br />
@Table(name = "CUSTOMER")<br />
@SecondaryTables( value = {<br />
@SecondaryTable(name = "CUST_NAME", pkJoin = {<br />
@PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }),<br />
@SecondaryTable(name = "CUST_ADDRESS", pkJoin = {<br />
@PrimaryKeyJoinColumn(name = "STMO_ID", referencedColumnName = "id") }) })<br />
public class Customer {}</p>
<p>&nbsp;</p>
<p>UniqueConstraint</p>
<p>UniqueConstraint定义在Table或SecondaryTable元数据里，用来指定建表时需要建唯<br />
一约束的列。</p>
<p>元数据属性说明：</p>
<p>* columnNames:定义一个字符串数组，指定要建唯一约束的列名。 </p>
<p><br />
@Entity<br />
@Table(name="EMPLOYEE",</p>
<p>uniqueConstraints={@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})}<br />
)<br />
public class Employee { ... }</p>
<p>&nbsp;</p>
<p>Column</p>
<p>Column元数据定义了映射到数据库的列的所有属性：列名，是否唯一，是否允许为空，<br />
是否允许更新等。</p>
<p>元数据属性说明：</p>
<p>* name:列名。 <br />
* unique: 是否唯一 <br />
* nullable: 是否允许为空 <br />
* insertable: 是否允许插入 <br />
* updatable: 是否允许更新 <br />
* columnDefinition: 定义建表时创建此列的DDL <br />
* secondaryTable: 从表名。如果此列不建在主表上（默认建在主表），该属性<br />
定义该列所在从表的名字。 </p>
<p><br />
public class Person {<br />
@Column(name = "PERSONNAME", unique = true, nullable = false,<br />
updatable = true)<br />
private String name;</p>
<p>@Column(name = "PHOTO", columnDefinition = "BLOB NOT NULL",<br />
secondaryTable="PER_PHOTO")<br />
private byte[] picture;</p>
<p>&nbsp;</p>
<p>JoinColumn</p>
<p>如果在entity class的field上定义了关系（one2one或one2many等），我们通过<br />
JoinColumn来定义关系的属性。JoinColumn的大部分属性和Column类似。</p>
<p>元数据属性说明：</p>
<p>* name:列名。 <br />
* referencedColumnName:该列指向列的列名（建表时该列作为外键列指向关系<br />
另一端的指定列） <br />
* unique: 是否唯一 <br />
* nullable: 是否允许为空 <br />
* insertable: 是否允许插入 <br />
* updatable: 是否允许更新 <br />
* columnDefinition: 定义建表时创建此列的DDL <br />
* secondaryTable: 从表名。如果此列不建在主表上（默认建在主表），该属性<br />
定义该列所在从表的名字。 </p>
<p>下面的代码说明Custom和Order是一对一关系。在Order对应的映射表建一个名为<br />
CUST_ID的列，该列作为外键指向Custom对应表中名为ID的列。</p>
<p><br />
public class Custom {</p>
<p>@OneToOne<br />
@JoinColumn(<br />
name="CUST_ID", referencedColumnName="ID", unique=true,<br />
nullable=true, updatable=true)<br />
public Order getOrder() {<br />
return order;<br />
}</p>
<p>&nbsp;</p>
<p>JoinColumns</p>
<p><br />
如果在entity class的field上定义了关系（one2one或one2many等），并且关系存在多<br />
个JoinColumn，用JoinColumns定义多个JoinColumn的属性。</p>
<p>元数据属性说明：</p>
<p>* value: 定义JoinColumn数组，指定每个JoinColumn的属性。 </p>
<p>下面的代码说明Custom和Order是一对一关系。在Order对应的映射表建两列，一列名为<br />
CUST_ID，该列作为外键指向Custom对应表中名为ID的列,另一列名为CUST_NAME，该列<br />
作为外键指向Custom对应表中名为NAME的列。</p>
<p><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 />
}</p>
<p>&nbsp;</p>
<p>Id</p>
<p>声明当前field为映射表中的主键列。id值的获取方式有五种：TABLE, SEQUENCE,<br />
IDENTITY, AUTO, NONE。Oracle和DB2支持SEQUENCE，SQL Server和Sybase支持<br />
IDENTITY,mysql支持AUTO。所有的数据库都可以指定为AUTO，我们会根据不同数据库做<br />
转换。NONE(默认)需要用户自己指定Id的值。元数据属性说明：</p>
<p>* generate():主键值的获取类型 <br />
* generator():TableGenerator的名字（当generate=GeneratorType.TABLE才需<br />
要指定该属性） </p>
<p>下面的代码声明Task的主键列id是自动增长的。(Oracle和DB2从默认的SEQUENCE取值，<br />
SQL Server和Sybase该列建成IDENTITY，mysql该列建成auto increment。)</p>
<p><br />
@Entity<br />
@Table(name = "OTASK")<br />
public class Task {<br />
@Id(generate = GeneratorType.AUTO)<br />
public Integer getId() {<br />
return id;<br />
}<br />
}</p>
<p>&nbsp;</p>
<p>IdClass</p>
<p>当entity class使用复合主键时，需要定义一个类作为id class。id class必须符合以<br />
下要求:类必须声明为public，并提供一个声明为public的空构造函数。必须实现<br />
Serializable接，覆写equals()和hashCode（）方法。entity class的所有id field在<br />
id class都要定义，且类型一样。</p>
<p>元数据属性说明：</p>
<p>* value: id class的类名 </p>
<p>&nbsp;</p>
<p><br />
public class EmployeePK implements java.io.Serializable{<br />
String empName;<br />
Integer empAge;</p>
<p>public EmployeePK(){}</p>
<p>public boolean equals(Object obj){ ......}<br />
public int hashCode(){......}<br />
}</p>
<p><br />
@IdClass(value=com.acme.EmployeePK.class)<br />
@Entity(access=FIELD)<br />
public class Employee {<br />
@Id String empName;<br />
@Id Integer empAge;<br />
}</p>
<p>&nbsp;</p>
<p>MapKey</p>
<p>在一对多，多对多关系中，我们可以用Map来保存集合对象。默认用主键值做key，如果<br />
使用复合主键，则用id class的实例做key，如果指定了name属性，就用指定的field的<br />
值做key。</p>
<p>元数据属性说明：</p>
<p>* name: 用来做key的field名字 </p>
<p>下面的代码说明Person和Book之间是一对多关系。Person的books字段是Map类型，用<br />
Book的isbn字段的值作为Map的key。</p>
<p><br />
@Table(name = "PERSON")<br />
public class Person {</p>
<p>@OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL,<br />
mappedBy = "person")<br />
@MapKey(name = "isbn")<br />
private Map&lt;String, Book&gt; books = new HashMap&lt;String, Book&gt;();<br />
}</p>
<p>&nbsp;</p>
<p>OrderBy</p>
<p><br />
在一对多，多对多关系中，有时我们希望从数据库加载出来的集合对象是按一定方式排<br />
序的，这可以通过OrderBy来实现，默认是按对象的主键升序排列。</p>
<p>元数据属性说明：</p>
<p>* value: 字符串类型，指定排序方式。格式为"fieldName1<br />
[ASC|DESC],fieldName2 [ASC|DESC],......",排序类型可以不指定，默认是ASC。 </p>
<p>下面的代码说明Person和Book之间是一对多关系。集合books按照Book的isbn升序，<br />
name降序排列。</p>
<p><br />
@Table(name = "MAPKEY_PERSON")<br />
public class Person {</p>
<p>@OneToMany(targetEntity = Book.class, cascade = CascadeType.ALL,<br />
mappedBy = "person")<br />
@OrderBy(name = "isbn ASC, name DESC")<br />
private List&lt;Book&gt; books = new ArrayList&lt;Book&gt;();<br />
}</p>
<p>&nbsp;</p>
<p>PrimaryKeyJoinColumn</p>
<p>在三种情况下会用到PrimaryKeyJoinColumn。 </p>
<p>* 继承。 <br />
* entity class映射到一个或多个从表。从表根据主表的主键列（列名为<br />
referencedColumnName值的列），建立一个类型一样的主键列，列名由name属性定义。</p>
<p>* one2one关系，关系维护端的主键作为外键指向关系被维护端的主键，不再新<br />
建一个外键列。 </p>
<p>&nbsp;</p>
<p>元数据属性说明：</p>
<p>* name:列名。 <br />
* referencedColumnName:该列引用列的列名 <br />
* columnDefinition: 定义建表时创建此列的DDL </p>
<p>下面的代码说明Customer映射到两个表，主表CUSTOMER,从表CUST_DETAIL，从表需要建<br />
立主键列CUST_ID，该列和主表的主键列id除了列名不同，其他定义一样。 </p>
<p><br />
@Entity<br />
@Table(name="CUSTOMER")</p>
<p>@SecondaryTable(name="CUST_DETAIL",pkJoin=@PrimaryKeyJoinColumn(name="CUST_I<br />
D"，referencedColumnName="id"))<br />
public class Customer { <br />
@Id(generate = GeneratorType.AUTO)<br />
public Integer getId() {<br />
return id;<br />
}<br />
}</p>
<p>&nbsp;</p>
<p>下面的代码说明Employee和EmployeeInfo是一对一关系，Employee的主键列id作为外键<br />
指向EmployeeInfo的主键列INFO_ID。 </p>
<p><br />
@Table(name = "Employee")<br />
public class Employee {<br />
@OneToOne<br />
@PrimaryKeyJoinColumn(name = "id", referencedColumnName="INFO_ID")<br />
EmployeeInfo info;<br />
}</p>
<p>&nbsp;</p>
<p>PrimaryKeyJoinColumns</p>
<p>如果entity class使用了复合主键，指定单个PrimaryKeyJoinColumn不能满足要求时，<br />
可以用PrimaryKeyJoinColumns来定义多个PrimaryKeyJoinColumn。 </p>
<p>元数据属性说明：</p>
<p>* value: 一个PrimaryKeyJoinColumn数组，包含所有PrimaryKeyJoinColumn。 </p>
<p>下面的代码说明了Employee和EmployeeInfo是一对一关系。他们都使用复合主键，建表<br />
时需要在Employee表建立一个外键，从Employee的主键列id,name指向EmployeeInfo的<br />
主键列INFO_ID和INFO_NAME. </p>
<p><br />
@Entity<br />
@IdClass(EmpPK.class)<br />
@Table(name = "EMPLOYEE")<br />
public class Employee {</p>
<p>private int id;</p>
<p>private String name;</p>
<p>private String address;</p>
<p>@OneToOne(cascade = CascadeType.ALL)<br />
@PrimaryKeyJoinColumns({<br />
@PrimaryKeyJoinColumn(name="id", referencedColumnName="INFO_ID"),<br />
@PrimaryKeyJoinColumn(name="name" ,<br />
referencedColumnName="INFO_NAME")})<br />
EmployeeInfo info;<br />
}</p>
<p>@Entity<br />
@IdClass(EmpPK.class)<br />
@Table(name = "EMPLOYEE_INFO")<br />
public class EmployeeInfo {</p>
<p>@Id<br />
@Column(name = "INFO_ID")<br />
private int id;</p>
<p>@Id<br />
@Column(name = "INFO_NAME")<br />
private String name;<br />
}</p>
<p>&nbsp;</p>
<p>Transient</p>
<p>Transient用来注释entity的属性，指定的这些属性不会被持久化，也不会为这些属性<br />
建表。</p>
<p><br />
@Transient<br />
private String name;</p>
<p>&nbsp;</p>
<p>　　</p>
<p><br />
Version</p>
<p>Version指定实体类在乐观事务中的version属性。在实体类重新由EntityManager管理<br />
并且加入到乐观事务中时，保证完整性。每一个类只能有一个属性被指定为version，<br />
version属性应该映射到实体类的主表上。</p>
<p>下面的代码说明versionNum属性作为这个类的version，映射到数据库中主表的列名是<br />
OPTLOCK。</p>
<p><br />
@Version<br />
@Column("OPTLOCK")<br />
protected int getVersionNum() { return versionNum; }</p>
<p>&nbsp;</p>
<p>Lob</p>
<p>Lob指定一个属性作为数据库支持的大对象类型在数据库中存储。使用LobType这个枚举<br />
来定义Lob是二进制类型还是字符类型。</p>
<p>LobType枚举类型说明：</p>
<p>* BLOB 二进制大对象，Byte[]或者Serializable的类型可以指定为BLOB。 <br />
* CLOB 字符型大对象，char[]、Character[]或String类型可以指定为CLOB。 </p>
<p>元数据属性说明：</p>
<p>* fetch： 定义这个字段是lazy loaded还是eagerly fetched。数据类型是<br />
FetchType枚举，默认为LAZY,即lazy loaded. <br />
* type： 定义这个字段在数据库中的JDBC数据类型。数据类型是LobType枚举，<br />
默认为BLOB。 </p>
<p>下面的代码定义了一个BLOB类型的属性和一个CLOB类型的属性。</p>
<p><br />
@Lob<br />
@Column(name="PHOTO" columnDefinition="BLOB NOT NULL")<br />
protected JPEGImage picture;</p>
<p>@Lob(fetch=EAGER, type=CLOB)<br />
@Column(name="REPORT")<br />
protected String report;</p>
<p>&nbsp;</p>
<p>JoinTable</p>
<p>JoinTable在many-to-many关系的所有者一边定义。如果没有定义JoinTable，使用<br />
JoinTable的默认值。</p>
<p>元数据属性说明：</p>
<p>* table:这个join table的Table定义。 <br />
* joinColumns:定义指向所有者主表的外键列，数据类型是JoinColumn数组。 <br />
* inverseJoinColumns:定义指向非所有者主表的外键列，数据类型是<br />
JoinColumn数组。 </p>
<p>下面的代码定义了一个连接表CUST和PHONE的join table。join table的表名是<br />
CUST_PHONE，包含两个外键，一个外键是CUST_ID，指向表CUST的主键ID，另一个外键<br />
是PHONE_ID，指向表PHONE的主键ID。</p>
<p><br />
@JoinTable(<br />
table=@Table(name=CUST_PHONE),<br />
joinColumns=@JoinColumn(name="CUST_ID", referencedColumnName="ID"),<br />
inverseJoinColumns=@JoinColumn(name="PHONE_ID",<br />
referencedColumnName="ID")<br />
)</p>
<p>&nbsp;</p>
<p>TableGenerator</p>
<p>TableGenerator定义一个主键值生成器，在Id这个元数据的generate＝TABLE时，<br />
generator属性中可以使用生成器的名字。生成器可以在类、方法或者属性上定义。</p>
<p>生成器是为多个实体类提供连续的ID值的表，每一行为一个类提供ID值，ID值通常是整<br />
数。</p>
<p>元数据属性说明：</p>
<p>* name:生成器的唯一名字，可以被Id元数据使用。 <br />
* table:生成器用来存储id值的Table定义。 <br />
* pkColumnName:生成器表的主键名称。 <br />
* valueColumnName:生成器表的ID值的列名称。 <br />
* pkColumnValue:生成器表中的一行数据的主键值。 <br />
* initialValue:id值的初始值。 <br />
* allocationSize:id值的增量。 </p>
<p>下面的代码定义了两个生成器empGen和addressGen，生成器的表是ID_GEN。</p>
<p><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 />
}</p>
<p>@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 />
}</p>
<p>&nbsp;</p>
<p>SequenceGenerator</p>
<p>SequenceGenerator定义一个主键值生成器，在Id这个元数据的generator属性中可以使<br />
用生成器的名字。生成器可以在类、方法或者属性上定义。生成器是数据库支持的<br />
sequence对象。</p>
<p>元数据属性说明：</p>
<p>* name:生成器的唯一名字，可以被Id元数据使用。 <br />
* sequenceName:数据库中，sequence对象的名称。如果不指定，会使用提供商<br />
指定的默认名称。 <br />
* initialValue:id值的初始值。 <br />
* allocationSize:id值的增量。 </p>
<p>下面的代码定义了一个使用提供商默认名称的sequence生成器。</p>
<p><br />
@SequenceGenerator(name="EMP_SEQ", allocationSize=25) </p>
<p>&nbsp;</p>
<p>DiscriminatorColumn</p>
<p>DiscriminatorColumn定义在使用SINGLE_TABLE或JOINED继承策略的表中区别不继承层<br />
次的列。</p>
<p>元数据属性说明：</p>
<p>* name:column的名字。默认值为TYPE。 <br />
* columnDefinition:生成DDL的sql片断。 <br />
* length:String类型的column的长度，其他类型使用默认值10。 </p>
<p>下面的代码定义了一个列名为DISC，长度为20的String类型的区别列。</p>
<p><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 { ... }<br />
</p>
<img src ="http://www.blogjava.net/lizhuxin/aggbug/221958.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lizhuxin/" target="_blank">☆</a> 2008-08-14 12:37 <a href="http://www.blogjava.net/lizhuxin/articles/221958.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>