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" >
     
     
     
     
     
     
  • 相关阅读:
    数据库表结构变动发邮件脚本
    .net程序打包部署
    无法登陆GitHub解决方法
    netbeans 打包生成 jar
    第一次值班
    RHEL6 纯命令行文本界面下安装桌面
    C语言中格式化输出,四舍五入类型问题
    I'm up to my ears
    How to boot ubuntu in text mode instead of graphical(X) mode
    the IP routing table under linux@school
  • 原文地址:https://www.cnblogs.com/liugch/p/6067020.html
Copyright © 2011-2022 走看看