Hibernate持久化对象

本文介绍 Hibernate ORM 框架的基本操作,包括对象的状态管理、OID生成策略及一对多关联映射,通过具体示例展示了如何使用 Hibernate 进行数据持久化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 一,持久化对象:
1,置于session管理下的对象叫做持久化状态
2,新建对象叫做临时状态
3,被session释放的对象叫游离状态

例子:

package basic;

import java.util.Iterator;
import java.util.List;
//导入五大核心接口类包
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
 * hibernate基本操作
 * @author chengzh
 *
 */
public class Test {
 //首先声明一个(每个应用只能有一个)数据存储源
 private static SessionFactory sessionFactory = null;
 static{
  //由配置类来构造一个配置文件对象
  Configuration config = new Configuration();
//利用配置类对象类构造一个数据存储源,指定配置文件来由buildSessionFactory方法
//构造sessionFactory,必须告诉具体配置文件路径.
  sessionFactory = config.configure("basic/hibernate.cfg.xml").buildSessionFactory();
 
 }
 
 public void test1() throws Exception{
 //通过sessionFactory得到持久化容器session(相当于JDBC里面获得一个连接)
  Session session =sessionFactory.openSession();
  //声明一个事务
  Transaction tx=null;
  try{
  //通过session获得一个事务
  tx=session.beginTransaction();
  //构造一个持久化类的实例,临时状态
  Student stu=new Student("zhangshan1",20);
  //把对象值存入数据库中,临时状态
  session.save(stu);
  System.out.println(stu);//持久化状态
  stu.setName("wangwu");
//  session.delete(stu);//执行delete后,又回到临时状态,只有在持久和游离状态是才能作删除操作
  tx.commit();//提交后,对上面操作全部更新
  }catch(Exception e){
   tx.rollback();
   throw e;
  }
 
 }
 public void saveStudent(Student student) throws Exception{
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   session.save(student);
   tx.commit();
  }catch(Exception e){
   tx.rollback();
   throw e;
  }finally{
   session.close();
  }
 }
 
 public void findAllStudent() throws Exception{
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   //Query查询类也可删除,为HQL语言,对类对象作操作,Student可以加上包名
   Query query = session.createQuery("from Student as s order by s.age asc");
   List list = query.list();
   for(Iterator it = list.iterator();it.hasNext();){
    System.out.println(it.next());
   }
   tx.commit();
  }catch(Exception e){
   tx.rollback();
   throw e;
  }finally{
   session.close();
  }
 }
 
 public void findStudent(String name) throws Exception{
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
 //由session得到查询器Query.为HQL语言,对类对象作操作,Student可以加上包名
   Query query = session.createQuery("from Student as s where s.name=:stuName order by s.age asc");
   query.setString("stuName",name);
 //由Query的对象来查询数据库,并且将查询上结果以对象的形式返回.存入集合
   List list = query.list();
   for(Iterator it = list.iterator();it.hasNext();){
    System.out.println(it.next());
   }
   tx.commit();
  }catch(Exception e){
   tx.rollback();
   throw e;
  }finally{
   session.close();
  }
 }
 
 public void loadAndUpdateStudent(Long id) throws Exception{
  //根据一个ID号加载一个对象,加载完后会放入session的池中,进入持久化状态
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try{
   tx = session.beginTransaction();
   //当池中没数据时对数据库操作,根据ID号,把对象加载到session池中,之后
   //都对池作操作.都是持久化状态.
   Student student = (Student)session.load(Student.class,id);
   //对name进行更新,
   //student.setName("new1");
   System.out.println(student);
   //当做完一个操作后,对缓存进行刷新(把这次操作放在缓存中的结果
   //提交到数据库中.使session容器一直处在最新状态.
   tx.commit();
   session.close();
   //游离状态
   Session session2 = sessionFactory.openSession();
   Transaction tx2 = session2.beginTransaction();
   student.setName("lisi");
   session2.update(student);//只有从在游离状态时,才能做Update操作.之后下面变成持久状态
   tx2.commit();//持久化状态
   session2.close();//关闭后又回到游离状态.
  }catch(Exception e){
   tx.rollback();
   throw e;
  }finally{
   //session.close();
  }
 }
 
 public void deleteAllStudents() throws Exception {
//  执行delete后,又回到临时状态,只有在持久和游离状态是才能作删除操作
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try {
   tx = session.beginTransaction();
   Query query = session.createQuery("delete Student as s");
   query.executeUpdate();
   tx.commit();

  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw e;
  } finally {
   // No matter what, close the session
   session.close();
  }
 }

 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  Test test = new Test();
//  Student student = new Student("s1",20);
//  test.saveStudent(student);
//  test.findAllStudent();
//  test.findStudent("s1");
  test.loadAndUpdateStudent(new Long(2));
//  test.deleteAllStudents();
//  test.test1();
  //关闭sessionFactory
  sessionFactory.close();
 
 }

}


二,五大类型的OID生成方式:

1,sequence :序列化,依赖于数据库,对id号生成有序的数字,xml例子在第一天里面有.
2,increment:由hibernate生成,与数据库无关,每次操作,把最大的ID号自动加1.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "/home/soft01/heguanhua/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="basic.Student" table="student1">
  <id name="id" column="id" type="long">
  <generator class="increment"/>
  </id>
  <property name="name" column="name" type="string"/>
  <property name="age" column="age" type="int"/>
 </class>
</hibernate-mapping>
3,identity:要求数据库支持自动增长字段.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="basic2.Student" table="student1">
  <id name="id" column="id" type="long">
   <generator class="identity"/>
  </id>
  <property name="name" column="name" type="string"/>
  <property name="age" column="age" type="int"/>
 </class>
</hibernate-mapping>

4,assign:表示由程序提供主键的生成.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="basic3.Student" table="STUDENT_na1">
  <id name="name" column="name" type="string">
   <generator class="assigned"/>
  </id>
  <property name="age" column="age" type="int"/>
 </class>
</hibernate-mapping>

5,hilo生成方式:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="basic1.Student" table="student1">
  <id name="id" column="id" type="long">
  
   <generator class="hilo">
    <param name="table">hi_value</param>
                <param name="column">next_value</param>
                <param name="max_lo">100</param>
   </generator>
   
   <!--
   <generator class="increment"/>
    -->
  </id>
  <property name="name" column="name" type="string"/>
  <property name="age" column="age" type="int"/>
 </class>
</hibernate-mapping>

 


三,一对多的单向关联

数据库的建立:
CREATE TABLE STUDENT2
(
  ID    bigint primary key,
  NAME  VARCHAR(20),
  AGE   int
)


CREATE TABLE Course2
(
  ID   bigint primary key,
  Name VARCHAR(20),
  SCORE   int,
  Student_id bigint not null
);


alter table Course2 add constraint course2_stu2_fk
foreign key(student_id) references student2(id);

hibernate.cfg.xml 和 course.hbm.xml两个文件与双向关联类似.这里不多写.
Student1.hbm.xml文件为:
HYPERLINK "Student1.hbm.xml"HYPERLINK "Student1.hbm.xml"
HYPERLINK "Student1.hbm.xml"<?xml version="1.0"?>
HYPERLINK "Student1.hbm.xml"<!DOCTYPE hibernate-mapping PUBLIC
HYPERLINK "Student1.hbm.xml" "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
HYPERLINK "Student1.hbm.xml" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
HYPERLINK "Student1.hbm.xml"<hibernate-mapping>
HYPERLINK "Student1.hbm.xml" <class name="onetomany.t1.Student" table="student2">
HYPERLINK "Student1.hbm.xml"  <id name="id" column="id" type="long">
HYPERLINK "Student1.hbm.xml"   <generator class="increment"/>
HYPERLINK "Student1.hbm.xml"  </id>
HYPERLINK "Student1.hbm.xml"  <property name="name" column="name" type="string"/>
HYPERLINK "Student1.hbm.xml"  <property name="age" column="age" type="int"/>
HYPERLINK "Student1.hbm.xml" </class>
HYPERLINK "Student1.hbm.xml"</hibernate-mapping>


Student类与course类缺省,以下是测试类:

package onetomany.t1;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {
 private static SessionFactory sessionFactory = null;
 static {
  Configuration config = new Configuration();
  sessionFactory = config.configure("onetomany/t1/hibernate.cfg.xml")
    .buildSessionFactory();

 }

 public void saveStudentAndCourse() throws Exception {
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try {
   tx = session.beginTransaction();
   Student student = new Student("t1", 20);
   session.save(student);
   Course course1 = new Course("math", 60,student);
   Course course2 = new Course("english", 90,student);
   session.save(course1);
   session.save(course2);
   tx.commit();

  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw e;
  } finally {
   session.close();
  }
 }
 
 public void saveStudentAndCourseCaseCade() throws Exception {
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try {
   tx = session.beginTransaction();
   Student student = new Student("t1", 20);
   Course course1 = new Course("math", 60,student);
   Course course2 = new Course("english", 90,student);
   session.save(course1);
   session.save(course2);
   tx.commit();

  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw e;
  } finally {
   session.close();
  }
 }
 
 
 public Student findStudent(Long id) throws Exception{
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try {
   tx = session.beginTransaction();
   Student student = (Student)session.load(Student.class,id);
   tx.commit();
   return student;
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw e;
  } finally {
   session.close();
  }
 }
 
 public List findCourseByStudent(Student student) throws Exception{
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try {
   tx = session.beginTransaction();
   Query query = session.createQuery("from Course as c where c.student.id="+student.getId());
   List courses = query.list();
   tx.commit();
   return courses;
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   throw e;
  } finally {
   session.close();
  }
 }
 

 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  Test test = new Test();
  test.saveStudentAndCourse();
//  test.saveStudentAndCourseCaseCade();
  Student  stu = test.findStudent(new Long(505));
  List list = test.findCourseByStudent(stu);
  for(Iterator it = list.iterator();it.hasNext();){
   Course course = (Course)it.next();
   System.out.println(course.getCouseName());
  }
  sessionFactory.close();
 }

}

 

四,双向一对多关联:

1,HYPERLINK "http://hibernate.cfg.xml/"hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "/home/soft01/heguanhua/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">root</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/tarena</property>
        <property name="hibernate.connection.username">root</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.show_sql">true</property>
  <mapping resource="day2/Student.hbm.xml"/>
  <mapping resource="day2/Course.hbm.xml"/>
 </session-factory>
</hibernate-configuration>


2,HYPERLINK "http://student.hbm.xml/"student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "/home/soft01/heguanhua/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="day2.Student" table="student1">
  <id name="id" column="id" type="long">
   <!-- 由increment生成OID 把表中最大的ID号每次自动加一 -->
   <generator class="increment"/>
  </id>
  <property name="name" column="name" type="string"/>
  <property name="age" column="age" type="int"/>
  <!-- 双向一对多,用集合来映射多个课程 -->
  <!-- name="courses" 学生类中集合 课程名 -->
  <!-- lazy="false" :加载学生类的时候,是否加载与学生关联的课程对象,
            当值为false时是指需要加载 -->
        <!-- cascade :级联更新,当删除或存取学生对象时
        把对应关联的课程对象也做删除或存取操作 -->
        <!-- inverse的意义:当学生的一方的inverse设置为true,能够或避免
            重复的update操作来提升程序性能 -->
  <set
        name="courses" 
        lazy="false"
        cascade="all-delete-orphan"
        inverse="true"
        >
        <!-- 表示指定course的外键是什么 -->
        <key column="Student_id" />
        <!-- 指定一对多的对象的类型为course -->
        <one-to-many class="day2.Course" />
     </set>
 </class>
</hibernate-mapping>


3,course.hbm.xml文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "/home/soft01/heguanhua/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="day2.Course" table="course">
  <id name="id" column="id" type="long">
   <generator class="increment"/>
  </id>
  <property name="couseName" column="name" type="string"/>
  <property name="score" column="SCORE" type="int"/>
  <!-- 从课程来说是多对一的关系 -->
  <!-- 下面的column: 指定外键 -->
  <!-- cascade: 级联更新,保存或更新课程时,同时保存或更新与课程有关联的
   学生信息 -->
  <!-- class: 学生属性所存取的对象存取的类型 -->
  <!-- student属性不能为空 -->
  <many-to-one

   name="student"
   column="Student_id"
   cascade="save-update"
   class="day2.Student"
   not-null="true"
  />
 </class>
</hibernate-mapping>


Student持久化对象类:

package day2;

import java.util.*;
public class Student {
  //双向关联,由于是一对多的关系,把课程用集合来存取
  private Long id;
  private String name;
  private int age;
  private Set courses;
  public Student(String name, int age, Set courses) {
   super();
   // TODO Auto-generated constructor stub
   this.name = name;
   this.age = age;
   this.courses = courses;
  }

  public Student(){
  
  }
 
  public int getAge() {
   return age;
  }
  public void setAge(int age) {
   this.age = age;
  }
  public Long getId() {
   return id;
  }
  public void setId(Long id) {
   this.id = id;
  }
  public String getName() {
   return name;
  }
  public void setName(String name) {
   this.name = name;
  }
  @Override
  public String toString() {
   // TODO Auto-generated method stub
   return "id "+id+" name "+name+" age"+age;
  }

  public Set getCourses() {
   return courses;
  }

  public void setCourses(Set courses) {
   this.courses = courses;
  }
 
}

 

5,Course持久化对象类:

package day2;

public class Course {
 private Long id;
 private String couseName;
 private int score;
 //在课程来说.是多个课程对一个学生. 把学生当做课程的属性,实现关联
 private Student student;
 
 public Course(String couseName, int score) {
  super();
  // TODO Auto-generated constructor stub
  this.couseName = couseName;
  this.score = score;
 }

 public Course(){ 
 }
 @Override
 public String toString() {
  // TODO Auto-generated method stub
  return " id "+id+" courseName "+couseName+" score = "+score;
 }
 public String getCouseName() {
  return couseName;
 }
 public void setCouseName(String couseName) {
  this.couseName = couseName;
 }
 public Long getId() {
  return id;
 }
 public void setId(Long id) {
  this.id = id;
 }
 public int getScore() {
  return score;
 }
 public void setScore(int score) {
  this.score = score;
 }
 public Student getStudent() {
  return student;
 }
 public void setStudent(Student student) {
  this.student = student;
 }
}

 


6,测试类:

package day2;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {
 private static SessionFactory sessionFactory = null;
 static {
  Configuration config = new Configuration();
  sessionFactory = config.configure("day2/hibernate.cfg.xml")
    .buildSessionFactory();

 }
 /**
  * Student.hbm.xml中将inverse="false",会重复执行多余的SQL语句,因此
  * 在映射一多对的双向关联时,应该将inverse设置为true;
  *
  * @throws Exception
  */
 public void saveStudentAndCourseCascade() throws Exception {
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try {
   tx = session.beginTransaction();
   //一对多的关系,一个学生有多个课程.用SET来存取.
   Student student = new Student("t3",20, new HashSet());
   //添加一个课程
   Course course = new Course("math",60);
   //设置课程对象,里面的Student属性.
   course.setStudent(student);
   //添加学生的多个课程到容器当中,这里只添加了一个.
   student.getCourses().add(course);
   /**提交学生对象到数据库中,查看session池中是否存在有要插入student和
    * course对象的相同的值,因为映射文件的Cascade定义了级联操作.把student
    * 对象插入时,根据映射文件的定义规则.把与之有关的course对象也相应的加载
    * 到数据库和session池中.
    */
   session.save(student);
   tx.commit();
  } catch (Exception e) {
   if (tx != null) {
    // Something went wrong; discard all partial changes
    tx.rollback();
   }
   e.printStackTrace();
  } finally {
   // No matter what, close the session
   session.close();
  }
 }
 
 /**
  * 注意cascade="all-delete-orphan" ,
   表示:
   1,保存或更新Student时,级联保存或更新所有关联的Course对象,相当于cascade=“save-update”
   2,当删除时,相当于"delete"
   3,删除不再和Student对象关联的所有Course对象
  * @throws Exception
  */
 public void deleteStudent() throws Exception {
  Session session = sessionFactory.openSession();
  Transaction tx = null;
  try {
   tx = session.beginTransaction();
   Student student = (Student)session.load(Student.class,new Long(12));
//   删除一个持久对象,是指从数据库中删除相关的纪录,此对象变为临时状态,依然在内存中
   //把学生删除时,与之关联的课程对象也跟着删除.
   session.delete(student);
   tx.commit();
   System.out.println(student);
  } catch (Exception e) {
   if (tx != null) {
    tx.rollback();
   }
   e.printStackTrace();
  } finally {
   session.close();
  }
 }
 
 public void removeCourseFromStudent() throws Exception{
     Session session = sessionFactory.openSession();
     Transaction tx = null;
     try {
       tx = session.beginTransaction();
       Student student=(Student)session.load(Student.class,new Long(13));
       //把课程对象的值都迭代出来,通过学生类中的课程Set来找出所有的课程.
       Course course=(Course)student.getCourses().iterator().next();
       //把学生类中的课程记录都删除
       student.getCourses().remove(course);
       //把课程中的学生对象清空.至此学生与课程完全断连.
       course.setStudent(null);
       tx.commit();

     }catch (Exception e) {
       if (tx != null) {
         tx.rollback();
       }
        e.printStackTrace();
     } finally {
       session.close();
     }
   }
 /**双向一对多关系.
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  Test test = new Test();
  test.saveStudentAndCourseCascade();
//  test.deleteStudent();
//  test.removeCourseFromStudent();
  sessionFactory.close();
 }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值