EJB之JPA(注解)_转
import java.io.Serializable; import java.security.acl.Group; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.Lob; import javax.persistence.ManyToMany; import javax.persistence.OneToOne; import javax.persistence.OrderBy; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.xml.registry.infomodel.User; /** * 核心提示:JPA 注解的几个要点 1.设置Pojo为实体 @Entity //标识这个pojo是一个jpa实体 public class Users implements Serializable{ } 2.设置表名 @Entity @Table (name= users ) //指定表名为users public class Users implements Serializable{ } 3.设置主键 public JPA 注解的几个要点 */ //2.设置表名 @Entity //@Entity 标识这个pojo是一个jpa实体 @Table(name = "users") //指定表名为users public class test implements Serializable { /** * */ private static final long serialVersionUID = 1L; } //3.设置主键 public class Users implements Serializable { @Id private String userCode; //4.主键生成策略 public class Users implements Serializable { @Id @GeneratedValue(strategy=GenerationType.IDENTITY)//主键自增,注意,这种方式依赖于具体的数据库,如果数据库不支持自增主键,那么这个类型是没法用的 @Column(name = "user_id", nullable = false) private int userId; public class Users implements Serializable { @Id @GeneratedValue(strategy=GenerationType.TABLE)//通过一个表来实现主键id的自增,这种方式不依赖于具体的数据库,可以解决数据迁移的问题,但是还要设置table的其他属性。关于这个可以看本BLOG的前几篇日志。有关于TABLE的设置 @Column(name = "user_code", nullable = false) private String userCode; public class Users implements Serializable { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE)//通过Sequence来实现表主键自增,这种方式依赖于数据库是否有SEQUENCE,如果没有就不能用 @SequenceGenerator(name="seq_user") @Column(name = "user_id", nullable = false) private int userId; /** * 设置自动识别数据库选择是用sequence方式还是identity方式。我一般都是选择这个方式。 * nullable与name选项一般都不用设置。nullable 是否可以为空,name如果不设置默认是字段名称 */ public class Users{ @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; /*** * 5. 设置字段类型 通过@Column注解设置,包含的设置如下 .name:字段名 如果不设置默认则是字段名 .unique:是否唯一 .nullable:是否可以为空 .inserttable:是否可以插入 .updateable:是否可以更新 .columnDefinition: 定义建表时创建此列的DDL .secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。 下面是JAVAEE 1.5的API 文档说明 可以看一下 String columnDefinition The SQL fragment that is used when generating the DDL for the column. boolean insertable Whether the column is included in SQL INSERT statements generated by the persistence provider. int length The column length. String name The name of the column. boolean nullable Whether the database column is nullable. int precision The precision for a decimal (exact numeric) column. int scale The scale for a decimal (exact numeric) column. String table The name of the table that contains the column. boolean unique Whether the property is a unique key. boolean updatable Whether the column is included in SQL UPDATE statements generated by the persistence provider. */ @Column(name = "user_code", nullable = false, length=32)//设置属性userCode对应的字段为user_code,长度为32,非空 private String userCode; @Column(name = "user_wages", nullable = true, precision=12, scale=2)//设置属性wages对应的字段为user_wages,12位数字可保留两位小数,可以为空 private double wages; /** * 注解时间类型要用@Temporal,通过设置@Temporal的value来设置注解时间的类型 * @Temporal的value一共有三种,分别是: * TemporalType.DATE map as java.sql.Date 日期型 精确到日 EG:2008-08-08 * TemporalType.TIME map as java.sql.Time 时间型 精确到秒 EG:20:00:00 * TemporalType.TIMESTAMP map as java.sql.Timestamp 时间型 精确到纳秒 EG:2008-08-08 20:00:00.000000001 * 所以根据自己不同的需求来设置TemporalType的值 */ @Temporal(TemporalType.DATE)//设置为时间类型 private Date joinDate; /** API:An orderby_list, specified as follows: orderby_list::= orderby_item [,orderby_item]* orderby_item::= property_or_field_name [ASC | DESC] If ASC or DESC is not specified, ASC (ascending order) is assumed. * 6.字段排序 在加载数据的时候可以为其指定顺序,使用@OrderBy注解实现 这个个人感觉用的还是比较少的。所以就没深入。如果有人用的比较好。希望补充 */ @Table(name = "USERS") public class User { @OrderBy(name = "group_name ASC, name DESC") private List books = new ArrayList(); } /** * ManyToOne API: * CascadeType[] cascade The operations that must be cascaded to the target of the association. FetchType fetch Whether the association should be lazily loaded or must be eagerly fetched. boolean optional Whether the association is optional. Class targetEntity The entity class that is the target of the association. * 一对多映射关系 * 有Group和User两个表。先是来映射一对多。GROUP是一,User是多。一个组里面可以包含多个用户。但是一个用户只能属于一个组。 * 为了方便。其他属性就简单映射了 */ /** * @ManyToOne 默认情况下,JPA 为指向具有多对一多重性的其他实体类的单值关联自动定义一个 ManyToOne 映射。 使用 @ManyToOne 批注: 140 将获取类型配置为 LAZY 141 如果空值不适合于应用程序,则将映射配置为禁止空值(针对非基元类型) 142 配置关联的目标实体(如果无法从被引用的对象类型推断出它) 143 配置必须层叠到关联目标的操作:例如,如果删除了拥有实体,则确保还删除关联的目标 cascade 默认值: CascadeType 的空数组。 默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。 如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括: 143 ALL —针对拥有实体执行的任何持续性操作均层叠到关联的目标。 143 MERGE —如果合并了拥有实体,则将 merge层叠到关联的目标。 143 PERSIST —如果持久保存拥有实体,则将 persist层叠到关联的目标。 143 REFRESH —如果刷新了拥有实体,则 refresh为关联的层叠目标。 143 REMOVE —如果删除了拥有实体,则还删除关联的目标。 fetch 默认值: FetchType.EAGER。 默认情况下,JPA 持续性提供程序使用获取类型 EAGER:这将要求持续性提供程序运行时必须迫切获取数据。 如果这不适合于应用程序或特定的持久字段,请将 fetch 设置为FetchType.LAZY:这将提示持续性提供程序在首次访问数据(如果可以)时应不急于获取数据。 optional 默认值: true。 默认情况下,JPA 持续性提供程序假设所有(非基元)字段和属性的值可以为空。 如果这并不适合于您的应用程序,请将 optional 设置为 false。 targetEntity 默认值:JPA 持续性提供程序从被引用的对象类型推断出关联的目标实体 如果持续性提供程序无法推断出目标实体的类型,则将关联拥有方上的targetEntity 元素设置为作为关系目标的实体的 Class。 * @author bacoo * */ /**One to Many * cascade 默认值: CascadeType 的空数组。 默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。 如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括: 161 ALL - 针对拥有实体执行的任何持续性操作均层叠到关联的目标。 161 MERGE - 如果合并了拥有实体,则将 merge 层叠到关联的目标。 161 PERSIST - 如果持久保存拥有实体,则将 persist 层叠到关联的目标。 161 REFRESH - 如果刷新了拥有实体,则 refresh 为关联的层叠目标。 161 REMOVE - 如果删除了拥有实体,则还删除关联的目标。 fetch 默认值: FetchType.EAGER。 默认情况下,JPA 持续性提供程序使用获取类型 EAGER:它要求持续性提供程序运行时必须急性获取数据。 如果这不适合于应用程序或特定的持久字段,请将 fetch 设置为FetchType.LAZY:它提示持续性提供程序在首次访问数据(如果可以)时应惰性获取数据。 mappedBy 默认值:如果关系是单向的,则该持续性提供程序确定拥有该关系的字段。 如果关系是双向的,则将关联相反(非拥有)方上的 mappedBy 元素设置为拥有此关系的字段或属性的名称()。 targetEntity 默认值:使用一般参数定义的 Collection 的参数化类型。 默认情况下,如果使用通过一般参数定义的 Collection,则持续性提供程序从被引用的对象类型推断出关联的目标实体。 如果 Collection 不使用一般参数,则必须指定作为关联目标的实体类:将关联拥有方上的 targetEntity 元素设置为作为关系目标的实体的 Class。 */ public class Group { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Integer id; @Column private String groupName; @OneToMany(mappedBy="group")//fetch及cascade都有默认值,如果不需要设置,可以不写 private List<User> users; } public class User { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Integer id; @Column private String userName; @Temporal(TemporalType.DATE) private Date birthday; @ManyToOne @JoinColumn(name="groupId") private Group group; } /** * 一对一映射关联 cascade 默认值:空 CascadeType 数组。 默认情况下,JPA 不会将任何持续性操作层叠到关联的目标。 如果希望某些或所有持续性操作层叠到关联的目标,请将 cascade 设置为一个或多个 CascadeType 实例,其中包括: 165 ALL - 针对拥有实体执行的任何持续性操作均层叠到关联的目标。 165 MERGE - 如果合并了拥有实体,则将 merge 层叠到关联的目标。 165 PERSIST - 如果持久保存拥有实体,则将 persist 层叠到关联的目标。 165 REFRESH - 如果刷新了拥有实体,则 refresh 为关联的层叠目标。 165 REMOVE - 如果删除了拥有实体,则还删除关联的目标。 fetch 默认值: FetchType.EAGER。 默认情况下,JPA 持续性提供程序使用获取类型 EAGER:它要求持续性提供程序运行时必须急性获取数据。 如果这不适合于应用程序或特定的持久字段,请将 fetch 设置为FetchType.LAZY:它提示持续性提供程序在首次访问数据(如果可以)时应惰性获取数据。 mappedBy 默认值:JPA 持续性提供程序从被引用的对象类型推断出关联的目标实体 如果持续性提供程序无法推断关联的目标实体,则将关联的相反(非拥有)方上的mappedBy 元素设置为拥有此关系的字段或属性的 String 名称(如 示例 1-64)所示。 optional 默认值: true。 默认情况下,JPA 持续性提供程序假设所有(非基元)字段和属性的值可以为空。 如果这并不适合于您的应用程序,请将 optional 设置为 false。 targetEntity 默认值:JPA 持续性提供程序从被引用的对象类型推断出关联的目标实体 如果持续性提供程序无法推断出目标实体的类型,则将关联的拥有方上的targetEntity 元素设置为作为关系目标的实体的 Class。 */ @Entity @Table(name = "T_ONEA") public class OneA implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "ONEA_ID", nullable = false) private String oneaId; @Column(name = "DESCRIPTION") private String description; @OneToOne(cascade = CascadeType.ALL)//主Pojo这方的设置比较简单,只要设置好级联就可以了。 private OneB oneB; @Entity @Table(name = "T_ONEB") public class OneB implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "ONEA_ID", nullable = false) private String oneaId; @Column(name = "DESCRIPTION") private String description; @JoinColumn(name = "ONEA_ID", referencedColumnName = "ONEA_ID", insertable = false, updatable = false)//设置从方指向主方的关联外键,这个ONEA_ID其实是表T_ONEA的主键 @OneToOne(mappedBy="oneB") private OneA oneA; // 大字段 @Lob //对应Blob字段类型 @Column(name = "PHOTO") private Serializable photo; @Lob //对应Clob字段类型 @Column(name = "DESCRIPTION") private String description; /** * 瞬时字段 不需要与数据库映射的字段,在保存的时候不需要保存倒数据库 */ @Transient private int tempValue; public int getTempValue(){ get tempValue; } public void setTempValue(int value){ this.tempValue = value; }