Java框架 Hibernate入门笔记三 对象状态和表间关系

一.Hibernate中的对象的三种状态

实体类对象在Hibernate中有3种状态
分别是瞬时,持久和脱管

瞬时 指的是没有和hibernate发生任何关系,在数据库中也没有对应的记录,一旦JVM结束,这个对象也就消失

持久 指得是一个对象和hibernate发生联系,有对应的session,并且在数据库中有对应的一条记录

脱管 指的是一个对象虽然在数据库中有对应的一条记录,但是它所对应的session已经关闭了

new 了一个Product();,在数据库中还没有对应的记录,这个时候Product对象的状态是瞬时的。

通过Session的save把该对象保存在了数据库中,该对象也和Session之间产生了联系,此时状态是持久的。

最后把Session关闭了,这个对象在数据库中虽然有对应的数据,但是已经和Session失去了联系,相当于脱离了管理,状态就是脱管的

二.表间关系

在数据库中有一些表之间是存在外键关系的, 比如我现在有一个Category表和一个Product表, 在Product表中有一列是pid是作为外键reference到Category里面的主键id, 现在我希望在Hibernate中设定一个这样的外键关系, 首先对于Product表而言, 存在一种多个product可以对应一个category的多对一关系;

对于Category表而言, 存在一种一个category可以对应多个product的一对多关系;

所以在配置文件中可以这样来声明这种关系:

//Category.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="Entity">
    <class name="Category" table="category_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />

        <set name="products" cascade="all"  lazy="false">
            <key column="cid" not-null="false" />
            <one-to-many class="Product" />
        </set>

    </class>

</hibernate-mapping>

在Category中设置一个对应的外键关系, 对应于实体类Category中的一个Set(集合, 也可以是list), 名为products, 然后指定一对多关系, 指定到另一个实体类Product, 我在此处设置了级联为all

几种级联设置的区别:

  1. 级联设为delete: 如果删除掉了主表(Category)中的某一行, 那么对应于此行的外键都会被删除, 即所有这个category的product都会被删掉, 比如:
Category c = (Category) s.get(Category.class, 3);
s.delete(c);
  1. 级联设为save-update, 这就意味着把一些瞬时对象存储到某个Category类的集合中, 这些瞬时对象会自动持久化, 听起来比较抽象, 举个例子就是:
Category c = (Category) s.get(Category.class, 5);

Product p1 = new Product();
p1.setName("product_501");
Product p2 = new Product();
p2.setName("product_502");
Product p3 = new Product();
p3.setName("product_503");

c.getProducts().add(p1);
c.getProducts().add(p2);
c.getProducts().add(p3);

比如这样新建了一些product, 但是我并没有用s.save来存这些对象, 而只是把他们加入到了获取的Category c中,但是实际运行发现, 设置了级联的save-update之后, 这些对象就被自动插入到了Product表中;

级联还有两种设置

  1. all: 就是同时有save-update和delete的功能;

  2. none: 就是同时关闭了save-update和delete的功能, 默认就是none的;

然后我设置lazy属性为false

这个是延迟加载功能, 指的是Hibernate并不会在获取某个对象的第一瞬间加载这个对象, 而是用到这个对象的时候再加载这个对象;

除了一对多和多对一的关系之外, 还有一种是多对多的关系, 但是在数据库表的设计中是不能出现这种关系的, 往往都要用一张新表做中间映射, 来形成两个一对多的关系;

比如这样:

//User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="com.how2java.pojo">
    <class name="User" table="user_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
 
        <set name="products" table="user_product" lazy="false">
            <key column="uid" />
            <many-to-many column="pid" class="Product" />
        </set>       
         
    </class>
     
</hibernate-mapping>
//Product.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="com.how2java.pojo">
    <class name="Product" table="product_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
        <property name="price" />
        <many-to-one name="category" class="Category" column="cid" />
         
        <set name="users" table="user_product" lazy="false">
            <key column="pid" />
            <many-to-many column="uid" class="User" />
        </set>       
                 
    </class>
     
</hibernate-mapping>

设定外键集合的时候要设置table为user_product的第三张新表;

猜你喜欢

转载自blog.csdn.net/qq_33982232/article/details/87673376