美文网首页
Hibernate(二)

Hibernate(二)

作者: jacob_ | 来源:发表于2019-05-11 13:59 被阅读0次

1 缓存

1.1 什么是缓存?

  • 数据存到数据库里面,数据库本身是文件系统,使用流操作文件效率不是很高。将数据存在内存里面不需要使用流的方式,可以直接读取内存中的数据。把数据收到内存中可以提高读取效率。
  • 提供缓存的目的是为了让数据访问的速度适应CPU的处理速度

1.2 Hibernate的一级缓存

  • hibernate的一级缓存是默认打开的。
  • hibernate的一级缓存的使用范围是session的范围,即从session被实例化到被关闭的过程
  • hibernate的一级缓存中,存储的数据必须是持久态(由session获得的)的数据。
  • hibernate的二级缓存默认不是打开的,并且现在都用redis去代替它,其使用范围为sessionFactory范围

1.3 验证一级缓存的存在

  • 验证方式:两次查询uid = 1的对象,第一次会查数据库,第二次就会从缓存中取
        Students students = session.get(Students.class,3);
        Students students2 = session.get(Students.class,3);

只有第一句会向数据库发送sql语句。

1.4 一级缓存的执行过程

  • 调用Students students = session.get(Students.class,3);后
  • 首先查询一级缓存区,查看是否存在id = 3的这个对象,如果存在则直接返回。
  • 如果不存在,则向数据库发送请求,返回的对象再存入一级缓存中。

1.5 一级缓存特性-持久态自动更新数据库

  • 持久态数据会自动更新数据库而不需要去调用类似session.update()方法。
Students students = session.get(Students.class,3);
students.setName("jacob");
//session.update(students);//不需要调用update也会更新数据库
  • 原理如下图:


    特性执行过程

2 事务标准写法

    @Test
    public void testTX(){
        StandardServiceRegistry standardServiceRegistry = null;
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        try {
            standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
            sessionFactory = new MetadataSources(standardServiceRegistry).buildMetadata().buildSessionFactory();
            session = sessionFactory.openSession();
            //开启事务
            tx = session.beginTransaction();
            Students students = session.get(Students.class,3);
            students.setGender("女");
            //抛出异常,回滚,性别仍是男
            int a = 1/0;
            System.out.println(a);
            students.setGender("男");
            tx.commit();
        }catch (Exception e){
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }

3 三种查询api

  • Query对象
            Query query = session.createQuery("from Students");
            List<Students> list = query.list();
            for(Students student:list){
                System.out.println(student);
            }
  • Criteria对象
            Criteria criteria = session.createCriteria(Students.class);
            List<Students> list = criteria.list();
            for(Students student:list){
                System.out.println(student);
            }
  • SQLQuery对象
//返回数组类型
            SQLQuery sqlQuery  = session.createSQLQuery("select * from students");
            List<Object[]> list = sqlQuery.list();
            for(Object[] objects:list){
                System.out.println(Arrays.toString(objects));
            }
//返回对象类型
            SQLQuery sqlQuery  = session.createSQLQuery("select * from students");
            sqlQuery.addEntity(Students.class);
            List<Students> list = sqlQuery.list();
            for(Students students:list){
                System.out.println(students);
            }

4 一对多操作

4.1 一对多配置

  • 以联系人与客户为例,客户是一,联系人是多。
  1. 创建两个实体类,客户和联系人。
  2. 让两个实体类互相表示。
  3. 创建映射文件,配置一对多关系。(映射文件中,表示所有联系人)
  4. 配置多对一关系。(映射文件中,表示所属客户)。
  5. 将映射文件引入核心配置文件。
  • 接来下是各个步骤对应的代码:
    1/2. 实体类创建并互相表示
import java.util.List;

public class Customer {
    private Integer cid;
    private String custName;
    private String custLevel;
    private String custSource;
    private String custPhone;
    private String custMobile;
    private List<Contacter> list;

    public List<Contacter> getList() {
        return list;
    }

    public void setList(List<Contacter> list) {
        this.list = list;
    }

    public Customer() {
    }

    public Customer(Integer cid, String custName, String custLevel, String custSource, String custPhone, String custMobile, List<Contacter> list) {
        this.cid = cid;
        this.custName = custName;
        this.custLevel = custLevel;
        this.custSource = custSource;
        this.custPhone = custPhone;
        this.custMobile = custMobile;
        this.list = list;
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCustName() {
        return custName;
    }

    public void setCustName(String custName) {
        this.custName = custName;
    }

    public String getCustLevel() {
        return custLevel;
    }

    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    public String getCustSource() {
        return custSource;
    }

    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }

    public String getCustPhone() {
        return custPhone;
    }

    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }

    public String getCustMobile() {
        return custMobile;
    }

    public void setCustMobile(String custMobile) {
        this.custMobile = custMobile;
    }
}
public class Contacter {
    private Integer conId;
    private String conName;
    private String conGender;
    private String conPhone;
    private Customer customer;

    public Contacter() {
    }

    public Contacter(Integer conId, String conName, String conGender, String conPhone, Customer customer) {
        this.conId = conId;
        this.conName = conName;
        this.conGender = conGender;
        this.conPhone = conPhone;
        this.customer = customer;
    }

    public Integer getConId() {
        return conId;
    }

    public void setConId(Integer conId) {
        this.conId = conId;
    }

    public String getConName() {
        return conName;
    }

    public void setConName(String conName) {
        this.conName = conName;
    }

    public String getConGender() {
        return conGender;
    }

    public void setConGender(String conGender) {
        this.conGender = conGender;
    }

    public String getConPhone() {
        return conPhone;
    }

    public void setConPhone(String conPhone) {
        this.conPhone = conPhone;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
}
  1. 创建映射文件配置一对多关系
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="Customer" table="customer">
        <id name="cid" type="int">
            <column name="cid"/>
            <generator class="native"/>
        </id>
        <property name="custName" type="java.lang.String">
            <column name="custName"/>
        </property>
        <property name="custLevel" type="java.lang.String">
            <column name="custLevel"/>
        </property>
        <property name="custSource" type="java.lang.String">
            <column name="custSource"/>
        </property>
        <property name="custMobile" type="java.lang.String">
            <column name="custMobile"/>
        </property>
        <property name="custPhone" type="java.lang.String">
            <column name="custPhone"/>
        </property>
        <!--name为集合名称 -->
        <set name="list">
            <!--外键名称-->
            <key column="clid">
            </key>
            <one-to-many class="Contacter"/>
        </set>
    </class>
</hibernate-mapping>
  1. 创建多对一关系
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="Contacter" table="contacter">
        <id name="conId" type="int">
            <column name="conId"/>
            <generator class="native"/>
        </id>
        <property name="conName" type="java.lang.String">
            <column name="conName"/>
        </property>
        <property name="conGender" type="java.lang.String">
            <column name="conGender"/>
        </property>
        <property name="conPhone" type="java.lang.String">
            <column name="conPhone"/>
        </property>
        <many-to-one name="customer" class="Customer" column="clid"/>
    </class>
</hibernate-mapping>
  1. 导入配置文件
        <mapping resource="Contacter.hbm.xml"/>
        <mapping resource="Customer.hbm.xml"/>
  1. 编写工具类 + 测试
public class HibernateUtils {
    static StandardServiceRegistry ssregistry = null;
    static SessionFactory sessionFactory = null;
    static {
        ssregistry = new StandardServiceRegistryBuilder().configure().build();
        sessionFactory = new MetadataSources(ssregistry).buildMetadata().buildSessionFactory();
    }
    public static Session getSessionObject(){
        return sessionFactory.getCurrentSession();
    }
    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }
    public static void main(String []args){

    }
}

运行该类即可发现数据库创建了两张表。

结果

4.2 级联保存

  • 方式一:
public class HibernateOneToManyTest {
    @Test
    public void oneToManyTest(){
        Session session = null;
        SessionFactory sessionFactory = null;
        Transaction tx = null;
        try{
            sessionFactory = HibernateUtils.getSessionFactory();
            session = HibernateUtils.getSessionObject();
            tx = session.beginTransaction();
            Customer customer = new Customer();
            customer.setCustLevel("vip");
            customer.setCustMobile("111");
            customer.setCustName("阿里巴巴");
            customer.setCustSource("网络");
            customer.setCustPhone("222");

            Contacter contacter = new Contacter();
            contacter.setConGender("男");
            contacter.setConName("jacob");
            contacter.setConPhone("333");

            customer.getList().add(contacter);
            contacter.setCustomer(customer);
            session.save(customer);
            session.save(contacter);
            tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }finally {
            session.close();
            sessionFactory.close();
        }
    }
}
  • 方式二:
  1. 首先在映射文件中添加配置cascade="save-update"
        <!--name为集合名称 -->
        <set name="list" cascade="save-update">
            <!--外键名称-->
            <key column="clid">
            </key>
            <one-to-many class="Contacter"/>
        </set>
  1. 代码:
            Customer customer = new Customer();
            customer.setCustLevel("vip");
            customer.setCustMobile("111");
            customer.setCustName("因特尔");
            customer.setCustSource("网络");
            customer.setCustPhone("222");

            Contacter contacter = new Contacter();
            contacter.setConGender("男");
            contacter.setConName("rose");
            contacter.setConPhone("333");

            customer.getList().add(contacter);
            session.save(customer);

4.3 级联删除

  • 有外键关联时的删除做法。
    直接删除一个customer是会报错的,因为有外键对其关联。


    删除报错
  • 做法步骤应如下:
  1. 删除从表的对应数据
  2. 删除主表对应数据
  • 级联删除的步骤如下:
  1. 在客户映射文件进行配置
        <!--name为集合名称 -->
        <set name="list" cascade="save-update,delete">
            <!--外键名称-->
            <key column="clid">
            </key>
            <one-to-many class="Contacter"/>
        </set>
            Customer customer = session.get(Customer.class,2);
            session.delete(customer);

4.4 更改联系人

            Customer customer = session.get(Customer.class,1);
            Contacter contacter = session.get(Contacter.class,11);
            customer.getList().add(contacter);
            contacter.setCustomer(customer);
  • 问题在于会进行两次外键设置,使得运行负担较大。
  • 解决方法 inverse="true"
        <set name="list" cascade="save-update,delete" inverse="true">
            <!--外键名称-->
            <key column="clid">
            </key>
            <one-to-many class="Contacter"/>
        </set>

相关文章

  • Hibernate 缓存机制

    Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存。 1.Hibernate...

  • SpringMVC/Hibernate项目实践一

    SpringMVC/Hibernate项目实践一SpringMVC/Hibernate项目实践二SpringMVC...

  • SpringMVC/Hibernate项目实践二

    SpringMVC/Hibernate项目实践一SpringMVC/Hibernate项目实践二SpringMVC...

  • SpringMVC/Hibernate项目实践三

    SpringMVC/Hibernate项目实践一SpringMVC/Hibernate项目实践二SpringMVC...

  • hibernate缓存机制书目录

    hibernate缓存机制 什么是缓存 缓存的范围 Hibernate一级缓存 hibernate二级缓存 hib...

  • springboot使用hibernate validator校

    目录 一、参数校验 二、hibernate validator校验demo 三、hibernate的校验模式 1、...

  • day02

    Hibernate框架第二天 课程回顾:Hibernate框架的第一天 今天内容 Hibernate的持久化类 什...

  • hibernate二

    layout: posttitle: hibernate--多表subtitle: 多表操作...

  • Hibernate(二)

    5. 对象的状态及生命周期及CRUD操作 5.1 对象的状态及生命周期 Transient:瞬时态,session...

  • 二、Hibernate

    1.session 一级缓存对象 缓存:经常访问物理数据库,为了降低应用程序对物理数据源访问的频次,从而提高应用程...

网友评论

      本文标题:Hibernate(二)

      本文链接:https://www.haomeiwen.com/subject/gurznqtx.html