`

jpa相关说明---OpenJpa

    博客分类:
  • JPA
 
阅读更多

各个字段的映射:

 

@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");这种删除会不会起作用呢?是不会起作用的,因为配置里那四项都是针对实体管理器的对应的方法。

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics