zoukankan      html  css  js  c++  java
  • Hibernate的各种关联关系

    1.有多中映射 方法

    //用XML配置时
    <mapping resource="com/liugch/bean/Student.hbm.xml" />
    //用注解配置时
    <mapping class="com.liugch.bean.Book" />
     

    2.unique-key 与 unique 的区别

    <!-- unique="true" 唯一约束 -->
    <property name="name" column="sName" length="50" type="string" unique="true" />
    <!-- unique-key 组合约束(两个属性都加) -->
    <property name="ip" unique-key="zuhe"/>
    <property name="address" unique-key="zuhe"/>

    3.多对一时(many-to-one:) 生成对应外键和 一端的主键关联起来

    用XML时:

     <many-to-one name="grade" fetch="join" class="com.liugch.bean.Grade" lazy="false" cascade="save-update"/>
     
        name="grade" :对应的类中的属性名
     
        class="com.liugch.bean.Grade":该属性对应的类位置(包名.类名)
     

      lazy:

      是否为延迟加载 (
        默认为延迟加载 lazy="proxy";
     
        延迟加载就是:
        当你要用到时才会执行查询语句   相当于load
        比如要查询学生 但不要他的班级信息, 就不会执行查询班级表的操作
        只有你用到班级里的 某个属性的时候才会执行 查询
      )
      lazy="false"时: 不是延迟加载
      lazy="proxy"时: 延迟加载
      lazy="no-proxy": 增强版的(proxy)同时这种方式需要编译时字节码增强,不然和proxy 没什么不同,
      "编译时字节码增强" 是什么意思?
      "字节码增强"分编译期和运行期2种,编译期是修改java类编译后的class字节码文件,在上面附加“增强”操作。
     

      cascade:

        是否执行级联操作(
        默认为: cascade:"none" 不执行级联操作
     
        就可以免去save班级之后 又save学生
        可以 单单执行save 学生就可以了 hibernate会自动为你执行 save 班级的操作
      )
      cascade:"save-update": 当执行插入和更新的时候执行 级联操作
      cascade:"all": 执行所有的操作都会 级联操作
     
     

     fetch:查询数据表的 方式

      默认 fetch="select": 执行 查询 分开(有两次查询); 另外发送多条条select语句抓取当前对象关联实体或集合
     
      fetch:"join" :通过左外连来执行查询的(一次查询) 使用外连接来加载其关联实体或集合
            如果设置了fetch="join",那么lazy设置会失效
            //在<set>集合中使用 在一的一端使用在查询一端时.当前的实体保存下来(主键的信息)其包含的多端的数据
            就会利用一个子查询把主键给保存下来
            select * from books where authorid in ( select authorid from author );
     

    用注解时:

     
    //targetEntity=com.liugch.bean.Customer.class 目标类
    //cascade = CascadeType.ALL, 设置级联
    //fetch=FetchType.LAZY 是否是懒加载
    //referencedColumnName 所引用表的字段名
     
    //@JoinColumn(name="c_id") 设置了外键的名称 没有设置的话: 默认时: 外键名为:当前属性名_引用的主键名
    @ManyToOne(cascade ={ CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
     
     
     
    @ManyToOne(cascade ={ CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
    @JoinColumn(name="c_id")
     
    //targetEntity=com.liugch.bean.Customer.class 目标类
    //cascade = CascadeType.ALL, 设置级联
    //fetch=FetchType.LAZY 是否是懒加载
    //referencedColumnName 所引用表的字段名
    //@JoinColumn(name="c_id") 设置外键值

    cascade 的值

    *CascadeType.PERSIST:级联新建
    * CascadeType.REMOVE : 级联删除
    * CascadeType.REFRESH:级联刷新
    * CascadeType.MERGE : 级联更新
    * CascadeType.ALL : 以上全部四项
    column="gid":
    //如果説是:xml配置的时候
    从新的定义 数据库表中 外键的名称
    //如果是 注解配置时:
    如果不定义该参数 数据库生成的为默认的外键名及: 属性名_引用的主键名
     
     
    -------------------------------------------------------------------------------------------------
     
     

    4. 组合标签

    <component name="" class=""></component>
     

    5. 主键

             
    /**
    * @Id 映射主键属性,这里采用uuid的主键生成策略
    * @GeneratedValue —— 注解声明了主键的生成策略。该注解有如下属性
    * strategy 指定生成的策略,默认是GenerationType. AUTO
    * GenerationType.AUTO 主键由程序控制
    * GenerationType.TABLE 使用一个特定的数据库表格来保存主键
    * GenerationType.IDENTITY 主键由数据库自动生成,主要是自动增长类型
    * GenerationType.SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列
    * generator 指定生成主键使用的生成器
    */
     

    6. 一对多时: one-many

    xml

    <set name="students" lazy="true" cascade="all">
      <!-- key column 对应的是 外键名称 -->
      <one-to-many class="com.liugch.bean.Student"/>
    </set>
     
    lazy:
    lazy="true|false| extra"
    lazy="true" 默认的
    lazy="extra" 当要查询一端集合的(size() | containt(object) | isEmplete)时:
    不会执行查询全部集合中的全部数据 ,例如要获取集合的大小: 相关的语句
    select count(*) from 表名
    feach:
    feach="select|join|subselect";
    feach="select" 默认 执行多条查询语句
    feach="join" 执行 一条 外连接查询
    feach="subselect" 执行一个子查询操作
     

    注解

    @OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
    @Fetch(FetchMode.SELECT)
     
     
     
     

    7.双向一对多,多对一

    在XML的时:

    <many-to-one name="grade" fetch="select" class="com.liugch.bean.Grade"  lazy="proxy" cascade="save-update">
    ---------------------------------------------------
    <set name="students" <!-- key column 对应的是 外键名称 -->
      <one-to-many class="com.liugch.bean.Student"/>
    </set>
    1.这两个column 必须要一样否则机会 生成两个外键名和主键相连
    2. inverse="true" 属性说明 给 另一方(多的一端)来维护   默认是为false;
     
    3. 一般都是交给多的一端来维护的;如果设置inverse="false" 时:   两边都会维护 会产生不必要的更新的语句
     
     
    4.当没有设置cascade时:
       session.save(student) 时: 先 保存一端一端效率比较高, 如果先保存多的一端执行对应的update语句
       当两方其中一个设置了cascade的时:先保存哪一方都是可以的
     
     
     

    在注解维护时:

     
    @ManyToOne(cascade ={
    CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
    private Customer customer;
    ------------------------------------------
     
    @OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,
    mappedBy="customer")
    private Set<Order> orders = new HashSet<>(0);

    注意:

    如果当一端没有定义 mappedBy="customer" 时:
    1.当两边都没定义2. 当一端定义时:不会生成关系表
    3.在多端定义时:还是会生成关系表, 定义了没有起到作用
    4.当两端都定义不同的 name 值时: 不会生成关系表,但是会生成两个外键列
    5.当两端定义了相同的name 值时: 不会生成关系表,只生成一个外键列
     
    如果定义了:
    由多端来维护表
    1.一端 不管你有没有定义 2.多端定义了 不定义的话:就会有默认的外键名
     
    mappedBy="customer":
      在一端上定义:
        表明是由多端来维护
     
      定义了mappedBy 时:
        就不能在 一端再次定义 joinColumn了 否则就会报错,只能在多的一端来定
     

    8. one-to-one(基于主键关联)

    注解

    @Entity
    @Table(name="t_persion")
    public class Persion {
    //使用当前对象中Idcare属性的主键来作为本对象的主键
    @Id
    @GeneratedValue(generator="pkGenerator")
    @GenericGenerator(name = "pkGenerator", strategy = "foreign", parameters =
    @Parameter(name = "property", value = "idcare"))
    private int pid;
     
    @Column(length=30)
    private String pname;
     
     
    /* optional很重要 指定关联属性不能为空
    如果想要实现延迟加载就一定要将这个属性设置为false
    这是因为JPA需要知道对应的数据是否存在后 才能决定是创建一个"延迟代理"还是"null引用"
    所以就不得不发起一条SQL请求来验证
    */
    @OneToOne(fetch=FetchType.LAZY,optional=false)
    //用当前对象的主键作为当前对象的外键 等价于 @JoinColumn(name="id",referencedColumnName="article_id")
    //@PrimaryKeyJoinColumn
    @JoinColumn( name="pid" ,referencedColumnName="id")
    private Idcare idcare;
     
     
    public int getPid() {
    return pid;
    }
    public void setPid(int pid) {
    this.pid = pid;
    }
    public String getPname() {
    return pname;
    }
    public void setPname(String pname) {
    this.pname = pname;
    }
    public Idcare getIdcare() {
    return idcare;
    }
    public void setIdcare(Idcare idcare) {
    this.idcare = idcare;
    }
    public Persion() {
    super();
    }
    public Persion(int pid, String pname, Idcare idcare) {
    super();
    this.pid = pid;
    this.pname = pname;
    this.idcare = idcare;
    }
    @Override
    public String toString() {
    return "Person [pid=" + pid + ", pname=" + pname + ", idcare=" + idcare + "]";
    }
     
    }
     
     
    @Entity
    @Table(name="t_idcare")
    public class Idcare {
    @Id
    @GeneratedValue
    private int id;
    @Column(length=30)
    private String iname;
     
    @OneToOne(mappedBy="idcare",optional=false)
    private Persion persion;
     
    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public String getIname() {
    return iname;
    }
    public void setIname(String iname) {
    this.iname = iname;
    }
     
     
    public Persion getPersion() {
    return persion;
    }
    public void setPersion(Persion persion) {
    this.persion = persion;
    }
    public Idcare(int id, String iname, Persion persion) {
    super();
    this.id = id;
    this.iname = iname;
    this.persion = persion;
    }
    public Idcare() {
    super();
    // TODO Auto-generated constructor stub
    }
    @Override
    public String toString() {
    return "Idcare [id=" + id + ", iname=" + iname + ", persion=" + persion + "]";
    }
     
    }
     

    (基于外键的关联)

    XML

    <hibernate-mapping>
    <class name="com.liugch.bean.Persion" table="t_persion" >
    <id name="pid">
    <generator class="native"></generator>
    </id>
    <property name="pname" length="30"></property>
     
    <many-to-one name="idcare" >
    <column name="ids"/>
    </many-to-one>
    </class>
     
    <hibernate-mapping>
    <class name="com.liugch.bean.Idcare" table="t_idcare" >
    <id name="id">
    <generator class="native"/>
    </id>
    <property name="iname" length="30"></property>
    <!-- class="com.liugch.bean.Persion" property-ref="idcare"
     
    class:可写可不写, 不写 内部通过放射机制来找到相关的类
    property-ref="idcare" 不写的话 默认和 相关联的类的主键
    相关类的属性的名称加入这外键。如果未指定,则使用关联类的主键。
    -->
    <one-to-one name="persion" property-ref="idcare"></one-to-one>
    </class>
    </hibernate-mapping>

    注解

    @ManyToOne(optional=false)
    @JoinColumn(name="ids")
    private Idcare idcare;
     
     
    @OneToOne(mappedBy="idcare",optional=false)
    private Persion persion;
     

     8.其他

     
    <!--mutable="true" 不可变的 ;optimistic-lock="version" 乐观锁 -->
    <class name="com.liugch.bean.Student" table="t_student" mutable="true"
    optimistic-lock="version" >
     
     
     
     
     
     
  • 相关阅读:
    Eclipse快捷键大全(转载)
    为什么你应该(从现在开始就)写博客 via刘未鹏
    Hadoop琐记
    详解MANIFEST.MF文件
    脚本语言琐记
    因为此版本的应用程序不支持其项目类型(.csproj) .
    求助:关于Activator.CreateInstance
    打印网页指定区域
    CSS中的行为——expression
    ASP.NET使用mysql数据库
  • 原文地址:https://www.cnblogs.com/liugch/p/6067020.html
Copyright © 2011-2022 走看看