Hibernate——自动创建数据库表 & 对象的三种状态

自动创建数据库表

如果需要Hibernate根据映射关系自动创建数据库,则需要配置hibernate.cfg.xml文件

<property name="hbm2ddl.auto">create</property>

这里有四个配置,分别是:create、update、create-drop和validate

  • create:当我们的应用程序加载hibernate.cfg.xml(比如new Configuration().configure())时,就会根据映射文件,创建出数据库,每次都会删掉已经存在的数据库重新创建;
  • update:如果数据库中没有该表,则创建表,如果有表,则看表有没有变化,如果有变化,则更新(比如增加一列);
  • create-drop:在显示关闭sessionFactory时,将drop掉数据库的schema
  • validate:相当于每次插入数据之前都会验证数据库中的表结构和hbm文件的结果是否一致

下面我们对update属性做简单的测试,首先我们创建一个数据库test

这里写图片描述

可以看到,当前数据库中没有任何数据表。

接着,我们创建项目HibernateHbmToDDL,手动创建一个domain对象Student,如下:

package com.gavin.domain;

public class Student {
    private Integer id;
    private String name;
    private String sex;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

并且手动配置其对象关系映射文件Student.hbm.xml,如下:

<?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="com.gavin.domain.Student" table="student" schema="test">
        <id name="id" column="id" type="java.lang.Integer"/>
        <property name="name" column="name" type="java.lang.String" length="64"/>
        <property name="sex" column="sex" type="java.lang.String" length="8"/>
    </class>
</hibernate-mapping>

接着,我们对Hibernate进行配置。hibernate.cfg.xml文件如下:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">gavin</property>

        <!-- DB schema will be updated if needed -->
         <property name="hbm2ddl.auto">update</property>
        <mapping resource="com/gavin/domain/Student.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

可以看到,在这里我们配置了<property name="hbm2ddl.auto">update</property>,所以如果数据库没有表的时候,Hibernate会自动帮我们建表。

下面写一个主方法保存一个Student对象:

import com.gavin.domain.Student;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;

public class Main {

    public static void main(final String[] args) throws Exception {
        Session session = new Configuration().configure().buildSessionFactory().openSession();
        Transaction transaction = session.beginTransaction();

        Student student = new Student();
        student.setId(1);
        student.setName("Gavin");
        student.setSex("M");

        session.save(student);
        transaction.commit();
        session.close();
    }
}

运行之后,我们可以再看数据库:

这里写图片描述

发现已经数据库已经创建好了student表,而且存入了刚刚程序中的数据。此时我们可以查看student表的表结构:

这里写图片描述

可以看到name字段是varchar(64)类型,也就是长度为64,sex长度为8,这就是之前我们在对象映射文件Student.hbm.xml文件中配置的length属性起的作用。

对象的状态

瞬时(transient)

数据库中没有数据与之对应,超过作用域会被JVM垃圾回收期回收,一般是new出来且与session没有关联的对象。

持久(persistent)

数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(Hibernate能检测到)

脱管/游离(detached)

数据库中有数据与之对应,但当前没有session与之关联;托管对象状态发生改变,Hibernate不能检测到。

三种状态的转换图如下:

这里写图片描述

示例代码如下:

// 对象的三种状态
// 刚刚创建的时候,course就是瞬时态
Course course = new Course();
course.setCcredit(3);
course.setCname("PHP");
SessionFactory sessionFactory = HibernateSessionFactory.getSessionFactory();
Session session = null;
Transaction transaction = null;
try {
    session = sessionFactory.openSession();
    transaction = session.beginTransaction();
    session.save(course);
    // 此时course既处于Session的管理之下(因为Session还没有关闭)
    // 同时course被保存在了数据库中,故其处于持久态
    System.out.println("course.getCname() = " + course.getCname());

    transaction.commit();
    session.close();

    // 这是course被保存到数据库中,同时没有处于session的管理之下
    // 故此时course处于游离态
    System.out.println("course.getCname() = " + course.getCname());
} catch (Exception e) {

}

猜你喜欢

转载自blog.csdn.net/gggavin/article/details/79491778