实例学习
Hibernate
Http://blog.csdn.net/fenglibing(20070914)
学习方式,采用做一个小型的留言本,因为要很好的使用Hibernate,在做系统之前,就必须把整个系统要做什么、要做些什么内容、怎么做等处理好,这样才能够在使用的过程中,较少的回去更改配置文件和程序。
1、 整个系统要做什么?
做一个系统留言系统,方便用户留言
2、要做些什么内容?
1)、实现简单的留言功能
2)、可以查看留言
3)、可以删除留言
4)、可以更改留言
5)、可以回复留言
3、怎么做?
语言是JSP+Hibernate
4、数据表设计
1)数据库选择:MySQL5.X
2)数据表设计:
LeaveMSG(留言表)
| ||
字段名
|
类型
|
说明
|
Id
|
自增型
|
ID主键
|
author
|
Text(50)
|
留言者
|
ldate
|
Text(50)
|
留言日期
|
msg
|
memo
|
留言内容
|
ReplyMSG(留言回复表)
| ||
字段名
|
类型
|
说明
|
Id
|
自增型
|
ID主键
|
lid
|
LeaveMSG ID
|
留言表的ID
|
rauthor
|
Text(50)
|
回复人
|
rdate
|
Text(50)
|
回复日期
|
rmsg
|
memo
|
回复内容
|
3)建表SQL语句:
a.建立数据库:Create database msg;
b.更改数据库:Use msg;
c.建立表LeaveMSG:Create table LeaveMSG(id int AUTO_INCREMENT primary key not null,author varchar(50),ldate varchar(20),msg text);
d.建立表ReplyMSG:Create table ReplyMSG(id int AUTO_INCREMENT primary key not null,lid int not null,rauthor varchar(50),rdate varchar(20),rmsg text);
e.建立外键关系:alter table replymsg add foreign key (lid) references leavemsg(id)
5、生成“.hbm.xml”配置文件:
使用Hiddlegen-Hibernate-r5生成配置文件,详细步骤可以参看文章:
(
注:最好是用middlegen2.1
,我现在用的是这个,功能更强大,可以生成好多种的配置文件)
成功配置运行好,会出现如下界面:
这时可以到build/gen-src看刚刚生成的Leavemsg.hbm.xml和Replymsg.hbm.xml了。
6、启动JDeveloper,并建立工程,将Hibernate的包导入到类路径、并MYSQL的JDBC驱动程序导入类路径。
(操作实例的时候出问题了)
注:因为做双表关联的映射出错,但是如果只做单表,不做双表关联,就不会出错,这里我还是把只做一个表操作的详细写下来,也算是宽慰宽慰自己吧:
1)、工程文件图如下:
文件结构图如下:
2)我这里用的是Mysql数据库,需要用的文件内容如下:
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">
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:mysql://localhost/msg</property>
<property name="connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">admin</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<!-- thread is the short name for
org.hibernate.context.ThreadLocalSessionContext
and let Hibernate bind the session automatically to the thread
-->
<property name="current_session_context_class">thread</property>
<mapping resource="msg/hibernate/Leavemsg.hbm.xml" />
</session-factory>
</hibernate-configuration>
Leavemsg.java
的内容如下:
package msg.hibernate;
import java.io.Serializable;
public class Leavemsg implements Serializable {
public Leavemsg() {
}
int id;
String author;
String ldate;
String msg;
…//下面都是一些get及set方法,用Eclipse和Jdeveloper都可以自动生成
}
这个很简单,就是一个实实在在的POJO JAVA BEAN,这个只要你定义了变量名,Eclipse和JDeveloper都可以自动为你生成get及set 方法。
Leavemsg.hbm.xml
的内容如下:
<?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>
<!--
Created by the Middlegen Hibernate plugin 2.1
http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->
<class
name="msg.hibernate.Leavemsg"
table="leavemsg"
>
<meta attribute="class-description" inherit="false">
@hibernate.class
table="leavemsg"
</meta>
<id
name="id"
type="java.lang.Integer"
column="id"
>
<meta attribute="field-description">
@hibernate.id
generator-class="assigned"
type="java.lang.Integer"
column="id"
</meta>
<generator class="assigned" />
</id>
<property
name="author"
type="java.lang.String"
column="author"
length="50"
>
<meta attribute="field-description">
@hibernate.property
column="author"
length="50"
</meta>
</property>
<property
name="ldate"
type="java.lang.String"
column="ldate"
length="20"
>
<meta attribute="field-description">
@hibernate.property
column="ldate"
length="20"
</meta>
</property>
<property
name="msg"
type="java.lang.String"
column="msg"
length="65535"
>
<meta attribute="field-description">
@hibernate.property
column="msg"
length="65535"
</meta>
</property>
<!-- Associations -->
<!-- bi-directional one-to-many association to Replymsg -->
<set
name="replymsgs"
lazy="true"
inverse="true"
cascade="none"
>
<meta attribute="field-description">
@hibernate.set
lazy="true"
inverse="true"
cascade="none"
@hibernate.collection-key
column="lid"
@hibernate.collection-one-to-many
class="msg.hibernate.Replymsg"
</meta>
<key>
<column name="lid" />
</key>
<one-to-many
class="msg.hibernate.Replymsg"
/>
</set>
</class>
</hibernate-mapping>
因为做这里只做单表测试,所以,我把绿色部分去掉了,即去掉和replymsg
之间的映射,因为现在做映射还会出错。
显然, 为了能对实体对象进行ORM, 我们需要的到一个Session 对象, Session 从哪里
来呢? 由SessionFactory 创建, SessionFactory 呢? 除了直接使用Hibernate 自带的之外,
MyEclipse 可以生成如下的包装代码:
HSFactory.java:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HSFactory {
static ThreadLocal threadLocal = new ThreadLocal();
static Configuration configuration = new Configuration();
static SessionFactory sessionFactory;
static String configFile = "/hibernate.cfg.xml";
//返回本地线程的Session实例。对SessionFactory采用lazy初始化
public static Session getCurrentSession() {
Session session = (Session)threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null)
rebuildSessionFactory();
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
//关闭本地线程的Session实例
public static void closeCurrentSession() {
Session session = (Session)threadLocal.get();
session.close();
}
//重新构建SessionFactory对象
public static void rebuildSessionFactory() {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
}
}
下面这段代码一并演示了单表的CRUD, 包括全查和全删
:
MsgDAO.java:
import java.util.List;
import msg.hibernate.Leavemsg;
import org.hibernate.*;
public class MsgDAO {
private Session session;
public Session getSession() {
return HSFactory.getCurrentSession();
}
public void setSession(Session session) {
this.session = session;
}
public void save(Leavemsg obj) {
getSession().save(obj);
}
public void delete(Leavemsg obj) {
getSession().delete(obj);
}
public void update(Leavemsg obj) {
getSession().update(obj);
}
public Leavemsg findByPK(Integer id) {
return (Leavemsg)getSession().get(Leavemsg.class, id);
}
public List findAll() {
Query query = getSession().createQuery("from Leavemsg");
return query.list();
}
public int deleteAll() {
Query query = getSession().createQuery("delete from Leavemsg");
return query.executeUpdate();
}
}
测试类,直接运行该类就可以:
Test.java:
import msg.hibernate.Leavemsg;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class Test {
public static void main(String[] args) {
Session session = HSFactory.getCurrentSession();
Leavemsg msg = new Leavemsg();
msg.setAuthor("FLB");
msg.setLdate("2007-09-12");
msg.setMsg("A first hibernate!");
MsgDAO dao = new MsgDAO();
dao.setSession(session);
Transaction tx = null;
try {
//开始事务
tx = session.beginTransaction();
dao.save(msg);
//提交事务
tx.commit();
} catch (Exception e) {
//回滚事务
if (tx != null)
tx.rollback();
} finally {
HSFactory.closeCurrentSession();
}
}
}