使用Hibernate完成对象持久化

来源:互联网 发布:淘宝网上怎样找三唑仑 编辑:程序博客网 时间:2024/06/07 10:17

 

使用Hibernate完成对象持久化

一、 为什么要使用Hibernate

先来回顾一下以前通过DAO怎么操作数据库。

增加学生信息:

public int addStudent(Student stu) {

Connection con = null;

PreparedStatement pstmt = null;

int rowCount = 0;

 

try {

con = DBUtil.getCon();

String sql = "insert into Student values(?, ?, ?, ?, ?)";

pstmt = con.prepareStatement(sql);

pstmt.setString(1, stu.getStuName());

pstmt.setString(2, stu.getStuPwd());

pstmt.setInt(3, stu.getStuAge());

pstmt.setInt(4, stu.getStuSex());

pstmt.setString(5, stu.getStuAddr());

 

rowCount = pstmt.executeUpdate(); //执行更新

catch (Exception ex) {

ex.printStackTrace();

finally {

DBUtil.closeDB(nullpstmt, con);

}

 

return rowCount;

}

 

 

查询学生信息:

public List<Student> findAllStudent() {

Connection con = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

List<Student> stuList = null;

 

try {

con = DBUtil.getCon();

String sql = "select * from Student";

pstmt = con.prepareStatement(sql);

rs = pstmt.executeQuery();

stuList = new ArrayList<Student>();

 

while(rs.next()) {

Student stu = new Student();

stu.setSid(rs.getInt("sid"));

stu.setStuName(rs.getString("stuName"));

stu.setStuPwd(rs.getString("stuPwd"));

stu.setStuAge(rs.getInt("stuAge"));

stu.setStuSex(rs.getInt("stuSex"));

stu.setStuAddr(rs.getString("stuAddr"));

 

stuList.add(stu);

}

catch (Exception ex) {

ex.printStackTrace();

finally {

DBUtil.closeDB(rs, pstmt, con);

}

 

return stuList;

}

 

修改学生信息:

public int updateStudent(Student stu) {

Connection con = null;

PreparedStatement pstmt = null;

int rowCount = 0;

 

try {

con = DBUtil.getCon();

String sql = "update Student set stuName = ?, stuPwd = ?, stuAge = ?, stuSex = ?, stuAddr = ? where sid = ?";

pstmt = con.prepareStatement(sql);

pstmt.setString(1, stu.getStuName());

pstmt.setString(2, stu.getStuPwd());

pstmt.setInt(3, stu.getStuAge());

pstmt.setInt(4, stu.getStuSex());

pstmt.setString(5, stu.getStuAddr());

pstmt.setInt(6, stu.getSid());

 

rowCount = pstmt.executeUpdate(); //执行更新

catch (Exception ex) {

ex.printStackTrace();

finally {

DBUtil.closeDB(null, pstmt, con);

}

 

return rowCount;

}

 

通过以上的代码,我们可以看出,按照以前的方式操作数据库,代码烦琐且容易出错。而且很多代码都基本上是重复的,所以纯“体力”性劳动充斥在我们的开发中,花去了我们大部分的开发时间。

自然的,我们不禁要问,有没有一种方案来解决这个问题,让我们可以早日从这些纯“体力性”的劳动中解放出来,而把绝大部分时间花在系统的业务逻辑上呢。正是在这样的背景下,Hibernate应运而生了,它的出现给Java程序员带来了福音。

 

二、 Hibernate是什么

接下来,我们一起学习关于Hibernate的一些基本概念。

 

HibernateHibernate是一个基于JDBC的主流持久化框架,它提供了对JDBC的薄层封装。它是一个优秀的ORM实现。使用Hibernate,通过对对象的操作就可以完成对关系型数据库的操作。

 

程序中数据的两种状态:

瞬时状态:保存在内存中的程序数据,程序退出后,数据就消失了,称为瞬时状态。

持久状态:保存在磁盘上的程序数据,程序退出后依然存在,称为程序数据的持久状态。

 

有的时候,我们需要对程序中的数据在这两种状态之间进行转换。比如,当用户注册的时候,就需要把数据从内存中写到数据库中,这个时候就是将程序中的数据由瞬时状态转变持久状态。又比如,当用户登陆某个在线商店,想要查看该商店的所有商品,这个时候需要将数据库中的所有商品数据查询到内存中,显示给客户。这个时候就是将程序中的数据由 持久状态转变成瞬时状态。由此,我们引入持久化的概念:

 

持久化:将程序数据在瞬时状态和持久状态进行转换的机制。

 

以前我们是通过JDBC进行数据持久化的。比如如下代码:

瞬时状态 à 持久状态(内存中 à 数据库中)

pstmt = con.prepareStatement(sql);

pstmt.setString(1, stu.getStuName());

pstmt.setString(2, stu.getStuPwd());

pstmt.setInt(3, stu.getStuAge());

pstmt.setInt(4, stu.getStuSex());

pstmt.setString(5, stu.getStuAddr());

rowCount = pstmt.executeUpdate();

 

持久状态 à 瞬时状态 (数据库中 à 内存中)

while(rs.next()) {

Student stu = new Student();

stu.setSid(rs.getInt("sid"));

stu.setStuName(rs.getString("stuName"));

stu.setStuPwd(rs.getString("stuPwd"));

stu.setStuAge(rs.getInt("stuAge"));

stu.setStuSex(rs.getInt("stuSex"));

stu.setStuAddr(rs.getString("stuAddr"));

stuList.add(stu);

}

我们发现,如果数据库中表的字段比较多的话,这个工作量是很大的,通过Hibernate,可以极大的简化该代码。

 

ORMObject Relation Mapping(对象关系映射)

程序语言发展至今,我们多以面向对象的形式来组织整个程序。处于瞬时状态的数据主要以对象的形式保存在内存中,而处于持久状态的数据很多时候都是保存在关系型数据库中。所以,通常情况下,持久化要完成的操作就是把对象(Object)保存到关系型数据库(Relation DataBase)中,或者从关系型数据库中把程序数据取出,然后再以对象的形式进行封装。

 

ORM:完成对象到关系型数据库的映射机制称为对象关系映射,简称为ORM

 

Hibernate提供了对JDBC的封装。也就是说,我们在使用Hibernate编写程序的时候,只需要对对象进行操作即可,Hibernate会自动的生成相应的SQL语句,完成数据的持久化操作。简而言之,通过Hibernate我们通过对对象的操作完成对关系型数据库的操作。

 

注意:我们在编写程序的时候,是以对象的形式进行操作。而在保存数据的时候,是保存到关系型数据库的表中。这个时候,我们必须在对象和表之间建立映射关系。否则,Hibernate就不知道我们对某个对象的操作就是对数据库中某张表的操作;我们对对象的属性的操作就是对表的字段的操作。这个映射关系(类ßà表),我们是通过xml的形式进行配置的,也就是我们稍后要讲到的*.hbm.xml文件。

 

三、 MeEclipse中使用Hibernate开发应用程序的步骤

 

准备工作:

1、 MyEclipse中建立和数据库的连接。

 

选择透视图

 

选择数据库浏览器试图

 

 

出现的界面如下

 

 

在空白区域,右键单击,选择New

 

 

出现界面如下,开始配置数据库连接驱动

 

 

 

下面,以连接SQL Server 2000 为例,配置如下

 

 

点击下一步,再单击Finish即可,效果如下

 

 

右键单击,选择Open Connection

 

 

展开其中的节点,如下效果

 

 

2、 在工程中导入Hibernate的支持库文件

切换到MyEclipse视图中,为工程添加Hibernate支持

 

注意要选中JAR Library Installation的第二个单选按纽

 

 

单击下一步,再单击下一步,为该工程选择连接数据库的驱动配置

 

单击下一步,不用选中创建SessionFactory

 

最后选中Finish即可。

3、 生成Hibernate的配置文件(hibernate.cfg.xml)

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

 

<!-- Generated by MyEclipse Hibernate Tools.                   -->

<hibernate-configuration>

 

<session-factory>

<!-- 驱动类 -->

<property name="connection.driver_class">

com.microsoft.jdbc.sqlserver.SQLServerDriver

</property>

 

<!-- URL -->

<property name="connection.url">

jdbc:microsoft:sqlserver://localhost:1433

</property>

 

<!-- 用户名 -->

<property name="connection.username">sa</property>

 

<!-- 数据库方言:SQL Server -->

<property name="dialect">

org.hibernate.dialect.SQLServerDialect

</property>

 

<property name="myeclipse.connection.profile">sql</property>

 

<!-- 显示SQL语句 -->

<property name="show_sql">true</property>

 

</session-factory>

 

</hibernate-configuration>

 

4、 生成POJO类和相应的映射文件(*.hbm.xml)

 

 

 

 

 

Student.java

package com.westaccp.hibernate.entity;

 

/**

 * Student entity.

 * 

 * @author MyEclipse Persistence Tools

 */

 

public class Student implements java.io.Serializable {

 

// Fields

 

private Integer sid;

private String stuName;

private String stuPwd;

private Integer stuAge;

private Byte stuSex;

private String stuAddr;

 

// Constructors

 

/** default constructor */

public Student() {

}

 

/** minimal constructor */

public Student(String stuName, String stuPwd) {

this.stuName = stuName;

this.stuPwd = stuPwd;

}

 

/** full constructor */

public Student(String stuName, String stuPwd, Integer stuAge, Byte stuSex,

String stuAddr) {

this.stuName = stuName;

this.stuPwd = stuPwd;

this.stuAge = stuAge;

this.stuSex = stuSex;

this.stuAddr = stuAddr;

}

 

// Property accessors

 

public Integer getSid() {

return this.sid;

}

 

public void setSid(Integer sid) {

this.sid = sid;

}

 

public String getStuName() {

return this.stuName;

}

 

public void setStuName(String stuName) {

this.stuName = stuName;

}

 

public String getStuPwd() {

return this.stuPwd;

}

 

public void setStuPwd(String stuPwd) {

this.stuPwd = stuPwd;

}

 

public Integer getStuAge() {

return this.stuAge;

}

 

public void setStuAge(Integer stuAge) {

this.stuAge = stuAge;

}

 

public Byte getStuSex() {

return this.stuSex;

}

 

public void setStuSex(Byte stuSex) {

this.stuSex = stuSex;

}

 

public String getStuAddr() {

return this.stuAddr;

}

 

public void setStuAddr(String stuAddr) {

this.stuAddr = stuAddr;

}

 

}

 

Student.hbm.xml

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- 

    Mapping file autogenerated by MyEclipse Persistence Tools

-->

<hibernate-mapping>

<!-- name:指定类名  table:指定表名 -->

    <class name="com.westaccp.hibernate.entity.Student" table="Student" schema="dbo" catalog="master">

     <!-- 主键配置:name:在类中属性名 type:属性数据类型 -->

        <id name="sid" type="java.lang.Integer">

         <!-- name:对应的数据库表字段名 -->

            <column name="sid" />

            <!-- 主键生成策略 -->

            <generator class="native"></generator>

        </id>

        <!-- 配置属性:name:在类中属性名 type:属性数据类型 -->

        <property name="stuName" type="java.lang.String">

         <!-- 配置字段:name:指定字段名 length:字段程度 not-null:是否非空 -->

            <column name="stuName" length="30" not-null="true" />

        </property>

        <property name="stuPwd" type="java.lang.String">

            <column name="stuPwd" length="30" not-null="true" />

        </property>

        <property name="stuAge" type="java.lang.Integer">

            <column name="stuAge" />

        </property>

        <property name="stuSex" type="java.lang.Byte">

            <column name="stuSex" />

        </property>

        <property name="stuAddr" type="java.lang.String">

            <column name="stuAddr" length="50" />

        </property>

    </class>

</hibernate-mapping>

 

 

此时,hibernate.cfg.xml配置多了如下一行

<mapping

resource="com/westaccp/hibernate/entity/Student.hbm.xml" />

 

 

编写代码:

1、 得到配置对象Configuration

Configuration config  = new Configuration().configure();

 

2、 得到Session工厂SessionFactory

SessionFactory factory = config.buildSessionFactory();

 

3、 通过Session工厂得到Session

Session session = factory.openSession();

 

4、 开始事务

tx = session.beginTransaction();

 

5、 持久化操作

session.save(stu);

 

6、 提交事务

tx.commit();

 

7、 关闭Session

session.close();

 

完整代码如下:

public void addStudent(Student stu) {

Configuration config  = new Configuration().configure();

SessionFactory factory = config.buildSessionFactory();

Session session = factory.openSession();

Transaction tx = null;

 

try {

tx = session.beginTransaction();

session.save(stu);

tx.commit();

catch (Exception ex) {

if(tx != null) {

tx.rollback();

}

ex.printStackTrace();

finally {

session.close();

}

}

 

原创粉丝点击