学习方式,采用做一个小型的留言本,因为要很好的使用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;
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(); } } }