Hibernate学习笔记(五):概念(一)

19 篇文章 0 订阅
10 篇文章 0 订阅

整理Hibernate中出现的各种概念

Hibernate的任何对数据有改动的操作,都应该被放在事务里面
Hibernate中的事务由s.beginTransaction();开始
由s.getTransaction().commit();结束 
在事务中的多个操作行为,要么都成功,要么都失败

举栗:
在同一个事务中执行两个操作
1. 删除id=1的产品
2. 修改id=2的产品,使得其产品名称超过了数据库中设置的长度30
提交事务

package com.how2java.test;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Product;
 
public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
 
        Session s = sf.openSession();
        s.beginTransaction();
 
        Product p = (Product) s.get(Product.class, 1);
        s.delete(p);
 
        Product p2 = (Product) s.get(Product.class, 2);
        p2.setName("长度超过30的字符串作为产品名称长度超过30的字符串作为产品名称长度超过30的字符串作为产品名称长度超过30的字符串作为产品名称");
        s.update(p2);
 
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

其中,第二个操作会失败,且因为这两个操作在同一事务中,所以第一个操作没有生效,id=1的产品依然存在

在Mysql中,只有当表的类型是INNODB的时候,才支持事务,所以需要把表的类型设置为INNODB,否则无法观察到事务
查看表的类型的SQL

show table status from test;

修改表的类型为INNODB的SQL:

alter table product_ ENGINE = innodb;
  • 延迟加载

Hibernate中延迟加载(lazyload)分属性延迟加载和关系延迟加载
属性延迟加载
当使用load的方式来获取对象的时候,只有访问了这个对象的属性,hibernate才会到数据库中进行查询,否则不会访问数据库

举栗:

package com.how2java.test;
  
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
import com.how2java.pojo.Product;
  
public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
  
        Session s = sf.openSession();
        s.beginTransaction();
     
        Product p = (Product)s.load(Product.class, 1);
        System.out.println("log1");
        System.out.println(p.getName());
        System.out.println("log2");
 
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

在打印log1之前,是不会打印出sql语句的,只有在访问属性“getName()"的时候,才会访问数据库

关系延迟加载
在one-many,many-many的时候都可以使用关系的延迟加载

举栗:
测试用例TestHibernate

package com.how2java.test;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
import com.how2java.pojo.Category;
 
public class TestHibernate {
    public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
 
        Session s = sf.openSession();
        s.beginTransaction();
        Category c = (Category) s.get(Category.class, 1);
 
        System.out.println("log1");
        System.out.println(c.getProducts());
        System.out.println("log1");
 
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

运行结果:

修改Category.hbm.xml

<set name="products" lazy="false"> 
//改为
<set name="products" lazy="true">

将Category类对products的关系设置为延迟加载
再次运行TestHibernate
运行结果:

可以看到,没有延迟加载时,先查询了表category_和product_,再执行输出
设置延迟加载以后,先查询了表category_,随后输出了第一个log1
在通过category获取products的时候,才对表product_进行查询

什么是级联? 简单的说,没有配置级联的时候,删除分类,其对应的产品不会被删除。 但是如果配置了恰当的级联,那么删除分类的时候,其对应的产品都会被删除掉

包括上述的删除用的级联,级联有4种类型:
all:所有操作都执行级联操作;
none:所有操作都不执行级联操作;
delete:删除时执行级联操作; 
save-update:保存和更新时执行级联操作;
级联通常用在一对多(one-many)和多对多(many-to-many)上,几乎不用在多对一(many-one)上

none级联
不存在级联,默认状态就是none

delete级联
修改Category.hbm.xml,将其与products的关系改为

<set name="products" cascade="delete" lazy="false">

修改TestHibernation,事务内容为

Category c = (Category) s.get(Category.class, 3);
s.delete(c);

运行后表category_中id=3的分类被删除,同时表product_中cid为3的条目也被删除
如果没有修改Category.hbm.xml设置级联,直接运行这个TestHibernation
那么表category_中的分类会被删除,但表product_中相关条目依然存在,只是其cid设置为空

save-update级联
修改Category.hbm.xml,将其与products的关系改为

<set name="products" cascade="save-update" lazy="false">

修改TestHibernation,事务内容为

        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);

运行后,Hibernate在commit()时发现数据有变化,就会自动将数据持久化
省略了s.save(p)和s.update(c)
如果不设置级联直接运行这个TestHibernation,会报错

all级联
all就是delete和save-update级联的效果都有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值