首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

jpa相干说明-OpenJpa

2012-09-18 
jpa相关说明---OpenJpa各个字段的映射:?@Entity@Table(nameperson)public class Person { @Id @Generat

jpa相关说明---OpenJpa

各个字段的映射:

?

@Entity@Table(name="person")public class Person { @Id @GeneratedValue  //不写是采用默认策略,即:(Strategy=Generation.AUTO) private Integer id;  //主键且数据库是mysql就自动增长(identified),是Oracle就序列化(sequence) @Column(length=10, nullable=false)  //长度为10,且不能为空 private String name; @Temporal(TemporalType.DATE)  //日期类型 private Date birthday; @Lob    //长整型,对应到mysql数据库为LongText private String info; @Lob @Basic(fetch=FetchType.LAZY)  //二进制数据,且延迟加载 private Byte[] file; @Enumerated(EnumType.STRING) @Column(length=5,nullable=false) //枚举类型,且将值存入数据库 private Gender gender= Gender.MAN; @Transient   //不映射进数据库 private String imagepath;}

?

?

? @Id
?@Column(name="id")
?@GeneratedValue(strategy = GenerationType.IDENTITY)
??? private int id;

?

主键生成,注解

@GeneratedValue

?AUTO: JPA自动选择合适的策略,是默认选项;
?IDENTITY: 采用数据库ID自增长的方式来生成主键值,Oracle不支持这种方式;
?SEQUENCE: 通过序列产生主键,通过@SequenceGenerator注解指定序列名,MySql不支持这种方式;
?TABLE: 采用表生成方式来生成主键值,那怎么样生成呢?很简单,表里面通常有两个字段,第一个字段是给它一个名称(就是个列名而已),第二个字段专门用来累加用的,就是说每访问一次这个表,第二个字段就会累加1,不断累加。就是说你们要得到这个主键值的话,访问这个表,然后update这个表的这个字段,把它累加1之后,然后再把这个值取出来作为主键,再给他赋进去,表生成就是这样。TABLE表生成方式才是通用的,但是这种方式效率并不高。

?

Oracle数据库默认情况下,不能支持用id自增长方式来生成主键值;
mysql在默认情况下不能支持SEQUENCE序列的方式来生成主键值,所以我们一定要注意我们使用的数据库。

?

不知道哪种数据库,用AUTO, 由jpa根据配置,如果用的是mysql,那么它会用IDENTITY。


注意:如果我们把策略strategy设置成@GeneratedValue(strategy=GenerationType.AUTO)的话,AUTO本身就是策略的默认值,我们可以省略掉,就是说简单写成这样@GeneratedValue

?

?

一对多关系(1-n):

OneToMany

Order.java

?

/*? one端
??? @OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE})
??? mappedBy="order": 指明Order类为双向关系维护端,负责外键的更新

???? */
??? @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "order")

OrderItem.java

??? // optional=true:可选,表示此对象可以没有,可以为null;false表示必须存在
??? @ManyToOne(cascade = { CascadeType.REFRESH,CascadeType.PERSIST , CascadeType.MERGE }, optional = true)
??? @JoinColumn(name = "order_id")
??? private Order order;

CascadeType.REFRESH:级联刷新,也就是说,当你刚开始获取到了这条记录,那么在你处理业务过程中,这条记录被另一个业务程序修改了(数据库这条记录被修改了),那么你获取的这条数据就不是最新的数据,那你就要调用实体管理器里面的refresh方法来刷新实体,所谓刷新,大家一定要记住方向,它是获取数据,相当于执行select语句的(但不能用select,select方法返回的是EntityManager缓存中的数据,不是数据库里面最新的数据),也就是重新获取数据。
CascadeType.PERSIST:级联持久化,也就是级联保存。保存order的时候也保存orderItem,如果在数据库里已经存在与需要保存的orderItem相同的id记录,则级联保存出错。
CascadeType.MERGE: 级联更新,也可以叫级联合并;当对象Order处于游离状态时,对对象Order里面的属性作修改,也修改了Order里面的orderItems。
CascadeType.REMOVE:当对Order进行删除操作的时候,也要对orderItems对象进行级联删除操作。

如果在应用中,要同时使用这四项的话,可以改成cascade = CascadeType.ALL


?

应用场合问题:这四种级联操作,并不是对所有的操作都起作用,只有当我们调用实体管理器的persist方法的时候,CascadeType.PERSIST才会起作用;同样道理,只有当我们调用实体管理器的merge方法的时候,CascadeType.MERGE才会起作用,其他方法不起作用。同样道理,只有当我们调用实体管理器的remove方法的时候,CascadeType.REMOVE才会起作用。

注意: Query query = em.createQuery("delete from Person o where o.id=?1");这种删除会不会起作用呢?是不会起作用的,因为配置里那四项都是针对实体管理器的对应的方法。

?

?

?

?

?

?

?

?

?

热点排行