关于JAP

JPA定义实体之间的关系有如下几种:

@OneToOne @ManyToOne @OneToMany @ManyToMany

在定义它们的时候可以通过fetch属性指定加载方式,有两个值:

FetchType.LAZY:延迟加载 

FetchType.EAGER:急加载

Hibernate单端关联懒加载策略:即在<one-to-one>/<many-to-one>标签上可以配置


懒加载策略。可以取值为:false/proxy/no-proxy



fetch策略


@OneToMany(mappedBy="image",cascade=CascadeType.ALL,fetch=FetchType.EAGER)


@Fetch(value=FetchMode.SUBSELECT)


两者比较:


两者都是设定关联对象的加载策略。前者是JPA标准的通用加载策略注解属性,


后者是Hibernate自有加载策略注解属性。


FetchType可选值意义与区别如下:


FetchType.LAZY: 懒加载,在访问关联对象的时候加载(即从数据库读入内存)


FetchType.EAGER:立刻加载,在查询主对象的时候同时加载关联对象。


FetchMode可选值意义与区别如下:


@Fetch(FetchMode.JOIN) 始终立刻加载,使用外连(outer join)查询的同时加载关联对象,忽略FetchType.LAZY设定。


@Fetch(FetchMode.SELECT) :默认懒加载(除非设定关联属性lazy=false),当访问每一个关联对象时加载该对象,会累计产生N+1sql语句


@Fetch(FetchMode.SUBSELECT)  默认懒加载(除非设定关联属性lazy=false),在访问第一个关联对象时加载所有的关联对象。会累计产生两条sql语句。且FetchType设定有效


 


lazy代表延时加载,lazy=false,代表不延时,如果对象A中还有对象B的引用,会在A的xml映射文件中配置b的对象引用,多对一或一对多,不延时代表查询出对象A的时候,会把B对象也查询出来放到A对象的引用中,A对象中的B对象是有值的.如果lazy=true,代表延时,查询A对象时,不会把B对象也查询出来,只会在用到A对象中B对象时才会去查询,默认好像是false,你可以看看后台的sql语句的变化就明白了,一般需要优化效率的时候会用到.


双向一对多关系,一是关系维护端(owner side),多是关系被维护端(inverse side)。在关系被维护端需要通过@JoinColumn建立外键列指向关系维护端的主键列

 
 
publicclass  Order  implements  Serializable {
     private Set<OrderItem> orderItems  =  new  HashSet<OrderItem>();
          。。。。
     @ OneToMany (mappedBy= "order" ,cascade = CascadeType. ALL , fetch = FetchType. LAZY )
     @ OrderBy (value =  "id ASC" )
     public  Set<OrderItem> getOrderItems() {
         return orderItems ;
     }
}
 
publicclass  OrderItem  implements  Serializable {
private  Order  order ;
。。。。
     @ ManyToOne (cascade=CascadeType. REFRESH ,optional= false )
     @ JoinColumn (name =  "order_id" )
     public  Order getOrder() {
         return order ;
     }
}
@OrderBy(value = "id ASC")  指明加载 OrderItem  时按 id  的升序排序
 
@OneToMany 的属性
1>targetEntity
定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义
 
2>mappedBy
定义类之间的双向关系。如果类之间是单向关系,不需要提供定义如果类和类之间形成双向关系,我们就需要使用这个属性进行定义,否则可能引起数据一致性的问题
该属性的值是“多”方class里的“一”方的变量名
 
3>cascade
该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,而且这种关系是递归调用的。举个例子: Order  OrderItem 有级联关系,那么删除 Order 时将同时删除它所对应的 OrderItem 对象。而如果 OrderItem 还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。
 
cascade 的值只能从 CascadeType.PERSIST (级联新建)、 CascadeType.REMOVE (级联删除)、 CascadeType.REFRESH (级联刷新)、 CascadeType.MERGE (级联更新)中选择一个或多个。还有一个选择是使用 CascadeType.ALL ,表示选择全部四项。
 
4>fatch
可选择项包括: FetchType.EAGER FetchType.LAZY 。前者表示关系类 ( 本例是 OrderItem  ) 在主类 ( 本例是 Order ) 加载的时候同时加载,后者表示关系类在被访问时才加载。默认值是 FetchType.LAZY
 
@JoinColumn(name = "order_id") 注释指定OrderItem映射表的order_id列作为外键与Order 映射表的主键列关联。
 
@ManyToOne :指明OrderItem和Order之间为多对一关系。
 
@ManyToOne 注释有四个属性:targetEntity、cascade、fetch 和optional,前三个属性的具体含义和@OneToMany的同名属性相同,但@ManyToOne的fetch 属性默认值是FetchType.EAGER
 
optional 属性是定义该关联类是否必须存在值为false 时,关联类双方都必须存在,如果关系被维护端不存在,查询的结果为null。值为true 时, 关系被维护端可以不存在,查询的结果仍然会返回关系维护端,在关系维护端中指向关系被维护端的属性为nulloptional属性的默认值是trueoptional 属性实际上指定关联类与被关联类的join 查询关系,如optional=false 时join 查询关系为inner join, optional=true 时join 查询关系为left join。下面代码片断解释如下:
 
 
 
 
 
有一点需要强调:当业务方法需要把一个实体 Bean 作为参数返回给客户端时,除了实体 Bean 本身需要实现 Serializable  接口之外 ,如果关联类(OrderItem)是延迟加载,还需在返回实体Bean之前通过访问关联类的方式加载关联类(见下例)。否则在客户端访问关联类时将会抛出加载例外。
     public  Order getOrderByID(Integer orderid) {
        Order order =  em .find(Order. class , orderid);        
        //!!!!! 因为是延迟加载,通过执行 size() 这种方式获取订单下的所有订单项
        order.getOrderItems().size();
        return  order;
     }
 
另外不管是否延迟加载,通过join fetch 关联语句都可显式加载关联类 ,如下例:
 
     public  List getAllOrder() {
         Query query =  em .createQuery( "select DISTINCT o from Order o inner
join fetch o.orderItems order by o.orderid" );
         List result = query.getResultList();
         return  result;

     }




hibernate之实体@onetomany和@manytoone双向注解

下面是User类:

@onetomany

@Entity
@Table(name="user")
public class User implements Serializable{
 
     
    private static final long serialVersionUID = 6177417450707400228L;
     
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name="id")
    private int id;
     
    @Column(name="name")
    private String name;
     
    @Column(name="password")
        private String password;
     
    /*
     * cascade:为级联操作,里面有级联保存,级联删除等,all为所有 
     * fetch:加载类型,有lazy和eager二种,
     *   eager为急加载,意为立即加载,在类加载时就加载,lazy为慢加载,第一次调用的时候再加载,由于数据量太大,onetomany一般为lazy
     * mappedBy:这个为manytoone中的对象名,这个不要变哦
     * Set<role>:这个类型有两种,一种为list另一种为set
     * 
     *
     */
    @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,mappedBy="user")
    private Set<role> setRole; 
     
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
     
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    public Set<role> getSetRole() {
        return setRole;
    }
 
    public void setSetRole(Set<role> setRole) {
        this.setRole = setRole;
    }
     
}
</role></role></role></role>




@manytoone

@Entity
@Table(name="role")
public class Role {
     
     
    private static final long serialVersionUID = 6177417450707400228L;   
     
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="role_id")
    private int role_id;
     
    @Column(name="role_name")
    private String role_name;
     
    @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @JoinColumn(name="user_id")//加入一列作为外键
    private User user;
     
    public int getRole_id() {
        return role_id;
    }
    public void setRole_id(int role_id) {
        this.role_id = role_id;
    }
     
    public String getRole_name() {
        return role_name;
    }
    public void setRole_name(String role_name) {
        this.role_name = role_name;
    }
     
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
 
}

有了这二个注解,我们不需要建表,hibernate会为我们自动建立表以及各种表级联系

其中@table为映射表名,@column为映射列名,其他的我不一一细说了。
下面就是操作了,定义了级联操作,下面是保存的。

public Role save() {
        User user=new User();
        user.setName("123456");
        user.setPassword("123456");
                 
        Role role=new Role();
        role.setRole_name("student");
        role.setUser(user);
         
        Role roler=registerDao.save(role);
         
        return roler;
    }



  使用HIBERNATE的注解@ManyToOne(fetch = FetchType.lazy) 时候,报出错误 

  1. org.hibernate.LazyInitializationException: could not initialize proxy - no Session  
  2. at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)  
  3. at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)  
  4. at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)  
  5. at com.evolution.warlock.entity.Department_
    _javassist_1.getName(Department__javassist_1.getName(Department_
    _javassist_1.java)  
  6. at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:180)  
  7. at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)  
  8. at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198
找了下答案,主要是因为: 
Html代码   收藏代码
  1. fetch=FetchType.LAZY就等于打开了延迟加载,Hibernate中的get方法不论是否开启延迟加载都会一次加载所有基本数据类型属性的值,而load则不同,开启延迟加载后load(id),返回的对象会被Hibernate加一个壳(持久化上下文中没有缓存该对象的前提下),拦截所有非id属性的访问操作(getter,setter调用),只有id属性中有实际值(其实就是你调用load方法时传的那个),在session没有关闭的之前,如果访问除id外的其他属性才会发sql语句去查询,你这个错误就是因为在当前session关闭以后访问由load()加载的对象的非id属性,此时Hibernate尝试通过当前session发sql查询,但发现session已经关闭,这样才会报错。  


   我测试发现的确是上面所说的,LAZY阻挡了除ID以外的所有访问,所以解决的办法就很多, 
   一.就是只拿ID,再从数据库从新拿一次你需要的东西。 
   二.将FetchType.lazy 改成 EAGER 
   三.配置xml (没试过) 
Xml代码   收藏代码
  1. <filter>  
  2.   <filter-name>openSessionInView</filter-name>  
  3.   <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>  
  4. </filter>  
  5.   
  6. <filter-mapping>  
  7.   <filter-name>openSessionInView</filter-name>  
  8.   <url-pattern>/*</url-pattern>  
  9. </filter-mapping>  

   四.在service层使用Hibernate.initialize()将你需要的对象从新持久化 

   五.在MVC里面配置,个人觉得这个办法更好




一、一对多(@OneToMany)
1、单向一对多模型
假设通过一个客户实体可以获得多个地址信息。
对于一对多的实体关系而言,表结构有两种设计策略,分别是外键关联和表关联。
(1) 映射策略---外键关联
在数据库中表customer和表结构address定义,如下:

[sql]  view plain  copy
  1. <code class="hljs sql" style=""><span class="hljs-keyword" style="">create</span> <span class="hljs-keyword" style="">table</span> customer (  
  2.   <span class="hljs-keyword" style="">id</span> <span class="hljs-built_in" style="">int</span>(<span class="hljs-number" style="">20</span>) <span class="hljs-keyword" style="">not</span> <span class="hljs-literal" style="">null</span> auto_increment,  
  3.   <span class="hljs-keyword" style="">name</span> <span class="hljs-built_in" style="">varchar</span>(<span class="hljs-number" style="">100</span>),  
  4.   primary <span class="hljs-keyword" style="">key</span>(<span class="hljs-keyword" style="">id</span>)  
  5. )  
  6.   
  7. <span class="hljs-keyword" style="">create</span> <span class="hljs-keyword" style="">table</span> address (  
  8.   <span class="hljs-keyword" style="">id</span> <span class="hljs-built_in" style="">int</span>(<span class="hljs-number" style="">20</span>) <span class="hljs-keyword" style="">not</span> <span class="hljs-literal" style="">null</span> auto_increment,  
  9.   province <span class="hljs-built_in" style="">varchar</span>(<span class="hljs-number" style="">50</span>),  
  10.   city <span class="hljs-built_in" style="">varchar</span>(<span class="hljs-number" style="">50</span>),  
  11.   postcode <span class="hljs-built_in" style="">varchar</span>(<span class="hljs-number" style="">50</span>),  
  12.   detail <span class="hljs-built_in" style="">varchar</span>(<span class="hljs-number" style="">50</span>),  
  13.   customer_id <span class="hljs-built_in" style="">int</span>(<span class="hljs-number" style="">20</span>),  
  14.   primary <span class="hljs-keyword" style="">key</span> (<span class="hljs-keyword" style="">id</span>)  
  15. )</code>  

注意此时外键定义在多的一方,也就是address表中。

 此时,表customer映射为实体CustomerEO,代码如下:

[java]  view plain  copy
  1. <code class="hljs less" style=""><span class="hljs-variable" style="">@Entity</span>  
  2. <span class="hljs-variable" style="">@Table</span>(name=<span class="hljs-string" style="">"customer"</span>)  
  3. public class CustomerEO implements java.io.Serializable {  
  4.   <span class="hljs-variable" style="">@OneToMany</span>(cascade={ CascadeType.ALL })  
  5.   <span class="hljs-variable" style="">@JoinColumn</span>(name=<span class="hljs-string" style="">"customer_id"</span>)  
  6.   private Collection<AddressEO> addresses = new ArrayList<AddressEO>();  
  7.  ...  
  8. }</code>  
注释@OneToMany的定义代码如下:
[java]  view plain  copy
  1. <code class="hljs java" style=""><span class="hljs-meta" style="">@Target</span>({METHOD, FIELD}) <span class="hljs-meta" style="">@Retention</span>(RUNTIME)  
  2. <span class="hljs-keyword" style="">public</span> <span class="hljs-meta" style="">@interface</span> OneToMany {  
  3.   <span class="hljs-function" style=""><span class="hljs-function" style="">Class </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">targetEntity</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">void</span></span></span><span class="hljs-function" style="">.class</span></span>;  
  4.   CascadeType[] cascade() <span class="hljs-keyword" style="">default</span> {};  
  5.   <span class="hljs-function" style=""><span class="hljs-function" style="">FetchType </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">fetch</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""> LAZY</span></span>;  
  6.   <span class="hljs-function" style=""><span class="hljs-function" style="">String </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">mappedBy</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""""</span></span>;  
  7. }</code>  
使用时要注意一下几点问题: 
a、targetEntity属性表示默认关联的实体类型。如果集合类中指定了具体类型了,不需要使用targetEntity.否则要指定targetEntity=AddressEO.class。 
b、mappedBy属性用于标记当实体之间是双向时使用。 

(2) 映射策略---表关联 
在上面address表中去掉customer_id字段,在增加一个表ref_customer_address,如下: 
[sql]  view plain  copy
  1. <code class="hljs sql" style=""><span class="hljs-comment" style="">--客户地址关系表</span>  
  2. <span class="hljs-keyword" style="">create</span> <span class="hljs-keyword" style="">table</span> ref_customer_address (  
  3.   customer_id <span class="hljs-built_in" style="">int</span>(<span class="hljs-number" style="">20</span>) <span class="hljs-keyword" style="">not</span> <span class="hljs-literal" style="">null</span>,  
  4.   address_id <span class="hljs-built_in" style="">int</span>(<span class="hljs-number" style="">20</span>) <span class="hljs-keyword" style="">not</span> <span class="hljs-literal" style="">null</span> <span class="hljs-keyword" style="">unique</span>  
  5. )</code>  
此时表customer映射为CustomerEO实体,代码如下:
[java]  view plain  copy
  1. <code class="hljs css" style="">@<span class="hljs-keyword" style="">Entity</span>  
  2. @Table(name = <span class="hljs-string" style="">"customer"</span>)  
  3. public class CustomerEO implements java.io.Serializable {  
  4.   ...  
  5.   @<span class="hljs-keyword" style="">OneToMany</span>(<span class="hljs-keyword" style="">cascade</span> = { <span class="hljs-selector-tag" style="">CascadeType</span><span class="hljs-selector-class" style="">.ALL</span> })  
  6.   @<span class="hljs-keyword" style="">JoinTable</span>(<span class="hljs-keyword" style="">name</span>="<span class="hljs-keyword" style="">ref_customer_address</span>",  
  7.            joinColumns={ @<span class="hljs-keyword" style="">JoinColumn</span>(<span class="hljs-keyword" style="">name</span>="<span class="hljs-keyword" style="">customer_id</span>",<span class="hljs-keyword" style="">referencedColumnName</span>="<span class="hljs-keyword" style="">id</span>")},  
  8.            inverseJoinColumns={@<span class="hljs-keyword" style="">JoinColumn</span>(<span class="hljs-keyword" style="">name</span>="<span class="hljs-keyword" style="">address_id</span>",<span class="hljs-keyword" style="">referencedColumnName</span>="<span class="hljs-keyword" style="">id</span>")})  
  9.   private Collection<AddressEO> addresses = new ArrayList<AddressEO>();  
  10.   ...  
  11. }</code>  
表关联@JoinTable,定义如下:
[java]  view plain  copy
  1. <code class="hljs less" style=""><span class="hljs-variable" style="">@Target</span>({METHOD,FIELD})   
  2. public <span class="hljs-variable" style="">@interface</span> JoinTable {  
  3.   String name() default "";  
  4.   String catalog() default "";  
  5.   String schema() default "";  
  6.   <span class="hljs-selector-tag" style="">JoinColumn</span><span class="hljs-selector-attr" style="">[]</span> <span class="hljs-selector-tag" style="">joinColumns</span>() <span class="hljs-selector-tag" style="">default</span> {};  
  7.   <span class="hljs-selector-tag" style="">JoinColumn</span><span class="hljs-selector-attr" style="">[]</span> <span class="hljs-selector-tag" style="">inverseJoinColumns</span>() <span class="hljs-selector-tag" style="">default</span> {};  
  8.   <span class="hljs-selector-tag" style="">UniqueConstraint</span><span class="hljs-selector-attr" style="">[]</span> <span class="hljs-selector-tag" style="">uniqueConstraints</span> <span class="hljs-selector-tag" style="">default</span> {};  
  9. }</code>  

其中:
a、该标记和@Table相似,用于标注用于关联的表。
b、name属性为连接两张表的表名。默认的表名为:“表名1”+“-”+“表名2”,上面例子默认的表名为customer_address。
c、joinColumns属性表示,在保存关系中的表中,所保存关联的外键字段。
d、inverseJoinColumns属性与joinColumns属性类似,不过它保存的是保存关系的另一个外键字段。

(3) 默认关联
在数据库底层为两张表添加约束,如下:

[sql]  view plain  copy
  1. <code class="hljs sql" style=""><span class="hljs-keyword" style="">create</span> <span class="hljs-keyword" style="">table</span> customer_address (  
  2.   customer_id <span class="hljs-built_in" style="">int</span>(<span class="hljs-number" style="">20</span>) <span class="hljs-keyword" style="">not</span> <span class="hljs-literal" style="">null</span>,  
  3.   address_id <span class="hljs-built_in" style="">int</span>(<span class="hljs-number" style="">20</span>) <span class="hljs-keyword" style="">not</span> <span class="hljs-literal" style="">null</span> <span class="hljs-keyword" style="">unique</span>  
  4. )  
  5. <span class="hljs-keyword" style="">alter</span> <span class="hljs-keyword" style="">table</span> customer_address <span class="hljs-keyword" style="">add</span> <span class="hljs-keyword" style="">constraint</span> fk_ref_customer foreign <span class="hljs-keyword" style="">key</span> (customer_id) <span class="hljs-keyword" style="">references</span> customer (<span class="hljs-keyword" style="">id</span>);  
  6.   
  7. <span class="hljs-keyword" style="">alter</span> <span class="hljs-keyword" style="">table</span> customer_address <span class="hljs-keyword" style="">add</span> <span class="hljs-keyword" style="">constraint</span> fk_ref_address foreign <span class="hljs-keyword" style="">key</span> (address_id) <span class="hljs-keyword" style="">references</span> address (<span class="hljs-keyword" style="">id</span>);</code>  

这样,在CustomerEO中只需要在标注@OneToMany即可!


二、多对一@ManyToOne
1、单向多对一模型。
(1) 外键关联
配置AddressEO实体如下:

[java]  view plain  copy
  1. <code class="hljs less" style=""><span class="hljs-variable" style="">@Entity</span>  
  2. <span class="hljs-variable" style="">@Table</span>(name=<span class="hljs-string" style="">"address"</span>)  
  3. public class AddressEO implements java.io.Serializable {  
  4.       
  5.   <span class="hljs-variable" style="">@ManyToOne</span>(cascade = { CascadeType.ALL })  
  6.   <span class="hljs-variable" style="">@JoinColumn</span>(name=<span class="hljs-string" style="">"customer_id"</span>)  
  7.   private CustomerEO customer;  
  8.       
  9.   <span class="hljs-comment" style="">// ...</span>  
  10. }</code>  

@ManyToOne定义如下:

[java]  view plain  copy
  1. <code class="hljs java" style=""><span class="hljs-meta" style="">@Target</span>({METHOD,FIELD}) <span class="hljs-meta" style="">@Retention</span>(RUNTIME)  
  2. <span class="hljs-keyword" style="">public</span> <span class="hljs-meta" style="">@interface</span> ManyToOne {  
  3.   <span class="hljs-function" style=""><span class="hljs-function" style="">Class </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">targetEntity</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">void</span></span></span><span class="hljs-function" style="">.class</span></span>;  
  4.   CascadeType[] cascade() <span class="hljs-keyword" style="">default</span> {};  
  5.   <span class="hljs-function" style=""><span class="hljs-function" style="">FetchType </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">fatch</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""> EAGER</span></span>;  
  6.   <span class="hljs-function" style=""><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">boolean</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">optional</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">true</span></span></span></span>;  
  7. }</code>  


(2) 默认关联
数据库脚本定义的相关字段的约束,创建外键后,直接使用@ManyToOne

三、高级一对多和多对一映射
即双向关联模型,确定了双向关联后,多的一方AddressEO不变使用@ManyToOne,而CustomerEO实体修改为:

[java]  view plain  copy
  1. <code class="hljs less" style=""><span class="hljs-variable" style="">@Entity</span>  
  2. <span class="hljs-variable" style="">@Table</span>(name=<span class="hljs-string" style="">"customer"</span>)  
  3. public class CustomerEO {  
  4.       
  5.   <span class="hljs-variable" style="">@OneToMany</span>(mappedBy=<span class="hljs-string" style="">"customer"</span>)  
  6.   private Collection<AddressEO> addresses = new ArrayList<AddressEO>();  
  7.       
  8.   <span class="hljs-comment" style="">// ...</span>  
  9. }</code>  
其中,@OneToMany标记中的mappedBy属性的值为AddressEO实体中所引用的CustomerEO实体的属性名。 

四、多对多(@ManyToMany)
和一对多类型,不在赘述。@ManyToMany标记的定义如下:

[java]  view plain  copy
  1. <code class="hljs java" style=""><span class="hljs-meta" style="">@Target</span>({METHOD, FIELD}) <span class="hljs-meta" style="">@Retention</span>(RUNTIME)  
  2. <span class="hljs-keyword" style="">public</span> <span class="hljs-meta" style="">@interface</span> ManyToMany {  
  3.   <span class="hljs-function" style=""><span class="hljs-function" style="">Class </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">targetEntity</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">void</span></span></span><span class="hljs-function" style="">.class</span></span>;  
  4.   CascadeType[] cascade() <span class="hljs-keyword" style="">default</span> {};  
  5.   <span class="hljs-function" style=""><span class="hljs-function" style="">FetchType </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">fecth</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""> LAZY</span></span>;  
  6.   <span class="hljs-function" style=""><span class="hljs-function" style="">String </span><span class="hljs-title" style=""><span class="hljs-function" style=""><span class="hljs-title" style="">mappedBy</span></span></span><span class="hljs-params" style=""><span class="hljs-function" style=""><span class="hljs-params" style="">()</span></span></span><span class="hljs-function" style=""> </span><span class="hljs-keyword" style=""><span class="hljs-function" style=""><span class="hljs-keyword" style="">default</span></span></span><span class="hljs-function" style=""""</span></span>;  
  7. }</code>  


五、最后,谈谈关于集合类的选择
在映射关系中可以使用的集合类有Collection、Set、List和Map,下面看下如何选择。
1、定义时使用接口,初始化使用具体的类。
如Collection可以初始化为ArrayList或HashSet;
Set可以初始化为HashSet;
List可以初始化为ArrayList;
Map可以初始化为HashMap.
2、集合类的选择
Collection类是Set和List的父类,在未确定使用Set或List时可使用;
Set集合中对象不能重复,并且是无序的;
List集合中的对象可以有重复,并且可以有排序;
Map集合是带有key和value值的集合。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值