第一个hibernate应用
1. 第一个类
建目录结构:
|- lib
...
|- src
|--|- road2hibernate
|- classes
第一个类:
package road2hibernate;
import java.util.Date;
public class Event {
private String title;
private Date date;
private Long id;
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
id 是 Event 的一个unique id,我们所有的持久化对象都需要这样一个id,
当我们建立hibernate 应用时,一个好的做法是使这个id 与应用逻辑相分离,这意味着我们在程序的任何地方都不要操作他,留给hibernate来做,这就是 setId 为 private 的原因
id 的类型我们使用了 Long, 而不是原始型,这样做会给我们省下不少麻烦,在应用中 id 要尽量使用对象型
2. 映射文件
我们已经有了类,需要告诉hibernate如何持久化他,这时映射文件就要上场了,他告诉hibernate把什么存入数据库以及如何存
Event 的映射文件应与Event 放在同一目录下,内容是这样的:
Event.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>
<class name="de.gloegl.road2hibernate.Event" table="EVENTS">
<id name="id" column="uid" type="long">
<generator class="increment"/>
</id>
<property name="date" type="timestamp"/>
<property name="title" column="eventtitle"/>
</class>
</hibernate-mapping>
在两个hibernate-mapping 标签间包含一个 class 元素,来声明这个映射文件涉及到哪个类,和这个类与数据库中的哪个表对应(Event类与EVENTS表映射)
接下来给hibernate指定一个唯一的标识符id, 我们不必怎么操作这个id, 只需告诉hibernate 如何生成这个id
id 元素是类中id 属性的声明,name="id" 是说属性的名字,column属性指明 EVENTS表中哪一列对应这个id
property 元素告诉hibernate使用哪个 get- set-
title-property 有一个 column属性,而 date-property没有,在没指定column属性时,hibernate会自动用property-name 做列名
title-property 没有 type属性,hibernate回自动匹配正确的类型,但date型的除外,timestamp/time, 所以 date-property指定了 type属性
3. 配置数据库
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>
<!-- Database connection settings -->
<property name="connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/javatest</property>
<property name="connection.username">javauser</property>
<property name="connection.password">javadude</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping resource="Event.hbm.xml"/>
</session-factory>
</hibernate-configuration>
dialect-property 指定所使用数据库的方言,这样hibernate可以更好的与数据库沟通
下面还指定了用JDBC Connection 做事务和一个简单的cache
现在的目录结构是这样:
|- lib
...
|- src
|--|- road2hibernate
|- classes
|--|- hibernate.cfg.xml
|--|- Event.hbm.xml
4. 编写业务逻辑
现在先写一个简单的类启动hibernate, 像这样:
package road2hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
public class EventManager {
public static void main(String[] args) {
Session s = HibernateUtil.currentSession();
HibernateUtil.closeSession();
System.exit(0);
}
}
这个类用了一个叫HibernateUtil 的类来获得 Session实例,HibernateUtil用"ThreadLocal Session Pattern"把当前的session 与当前线程联系起来
HibernateUtil像这样:
package road2hibernate;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
HibernateUtil 在静态初始化块中创建SessionFactory,用两个静态方法获得和关闭session, 用ThreadLocal变量来持有session
通过ThreadLocal存储的数据总与当前线程相关,JVM为每个运行的线程都绑定了私有的本地实例存储空间,为多线程环境的并发问题提供了隔离机制
sessionFactory创建Session,sessionFactory是线程安全的,但Session 不是,所以使用ThreadLocal。
ThreadLocal为每个线程维护一个私有的变量空间,实际就是在JVM中维护一个Map, key 就是当前的线程对象,value 就是通过ThreadLocal.set 保存的对象实例,当用ThreadLocal.get 时会根据当前线程对象的引用,取回Map中对应的对象
Configuration 类负责管理Hibernate 的配置信息,Hibernate 运行时需要获得一些基本的信息,包括:
(1)数据库URL
(2)数据库用户名
(3)数据库密码
(4)JDBC驱动类
(5)数据库dialect, 用于对特定数据库提供支持
当我们调用:
new Configuration().configure();时Hibernate 会自动在CLASSPATH中搜寻hibernate.cfg.xml 将其读取到内存中作为后续操作的基本配置
SessionFactory 负责创建 Session实例,通过Configuration实例创建
Session 是持久层操作的基础,相当于JDBC中的Connection, 通过SessionFactory 实例创建
下面往数据库中插入一条记录,现在EventManager 像这样:
package road2hibernate;
import org.hibernate.*;
import org.hibernate.cfg.*;
import java.util.Date;
public class EventManager {
public static void main(String[] args) {
EventManager em = new EventManager();
Session s = HibernateUtil.currentSession();
String title = "hbm";
Date theDate = new Date();
em.store( title, theDate );
HibernateUtil.closeSession();
System.exit(0);
}
private void store(String title, Date theDate) {
try {
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);
session.save(theEvent);
tx.commit();
HibernateUtil.closeSession();
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
现在的目录结构是这样:
|- lib
...
|- src
|--|- road2hibernate
|--|--|- Event.java
|--|--|- EventManager.java
|--|--|- HibernateUtil.java
|- classes
|--|- hibernate.cfg.xml
|--|- Event.hbm.xml
编写build.xml
<project name="hbmapp" basedir=".">
<property name="src.home" value="${basedir}/src"/>
<property name="classes.home" value="${basedir}/classes"/>
<property name="lib.home" value="${basedir}/lib"/>
<!-- "compile" target -->
<target name="compile">
<javac srcdir="${src.home}" destdir="${classes.home}" debug="on">
<classpath>
<fileset dir="${lib.home}">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<!-- "run" target -->
<target name="run">
<java classname="road2hibernate.EventManager" classpath="${classes.home}">
<classpath>
<fileset dir="${lib.home}">
<include name="*.jar"/>
</fileset>
</classpath>
</java>
</target>
</project>
5. 运行
在命令行: ant compile
然后: ant run
现在查询数据库就可以看到刚刚插入的记录了
建目录结构:
|- lib
...
|- src
|--|- road2hibernate
|- classes
第一个类:
package road2hibernate;
import java.util.Date;
public class Event {
private String title;
private Date date;
private Long id;
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
id 是 Event 的一个unique id,我们所有的持久化对象都需要这样一个id,
当我们建立hibernate 应用时,一个好的做法是使这个id 与应用逻辑相分离,这意味着我们在程序的任何地方都不要操作他,留给hibernate来做,这就是 setId 为 private 的原因
id 的类型我们使用了 Long, 而不是原始型,这样做会给我们省下不少麻烦,在应用中 id 要尽量使用对象型
2. 映射文件
我们已经有了类,需要告诉hibernate如何持久化他,这时映射文件就要上场了,他告诉hibernate把什么存入数据库以及如何存
Event 的映射文件应与Event 放在同一目录下,内容是这样的:
Event.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>
<class name="de.gloegl.road2hibernate.Event" table="EVENTS">
<id name="id" column="uid" type="long">
<generator class="increment"/>
</id>
<property name="date" type="timestamp"/>
<property name="title" column="eventtitle"/>
</class>
</hibernate-mapping>
在两个hibernate-mapping 标签间包含一个 class 元素,来声明这个映射文件涉及到哪个类,和这个类与数据库中的哪个表对应(Event类与EVENTS表映射)
接下来给hibernate指定一个唯一的标识符id, 我们不必怎么操作这个id, 只需告诉hibernate 如何生成这个id
id 元素是类中id 属性的声明,name="id" 是说属性的名字,column属性指明 EVENTS表中哪一列对应这个id
property 元素告诉hibernate使用哪个 get- set-
title-property 有一个 column属性,而 date-property没有,在没指定column属性时,hibernate会自动用property-name 做列名
title-property 没有 type属性,hibernate回自动匹配正确的类型,但date型的除外,timestamp/time, 所以 date-property指定了 type属性
3. 配置数据库
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>
<!-- Database connection settings -->
<property name="connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/javatest</property>
<property name="connection.username">javauser</property>
<property name="connection.password">javadude</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping resource="Event.hbm.xml"/>
</session-factory>
</hibernate-configuration>
dialect-property 指定所使用数据库的方言,这样hibernate可以更好的与数据库沟通
下面还指定了用JDBC Connection 做事务和一个简单的cache
现在的目录结构是这样:
|- lib
...
|- src
|--|- road2hibernate
|- classes
|--|- hibernate.cfg.xml
|--|- Event.hbm.xml
4. 编写业务逻辑
现在先写一个简单的类启动hibernate, 像这样:
package road2hibernate;
import org.hibernate.SessionFactory;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
public class EventManager {
public static void main(String[] args) {
Session s = HibernateUtil.currentSession();
HibernateUtil.closeSession();
System.exit(0);
}
}
这个类用了一个叫HibernateUtil 的类来获得 Session实例,HibernateUtil用"ThreadLocal Session Pattern"把当前的session 与当前线程联系起来
HibernateUtil像这样:
package road2hibernate;
import org.hibernate.*;
import org.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
HibernateUtil 在静态初始化块中创建SessionFactory,用两个静态方法获得和关闭session, 用ThreadLocal变量来持有session
通过ThreadLocal存储的数据总与当前线程相关,JVM为每个运行的线程都绑定了私有的本地实例存储空间,为多线程环境的并发问题提供了隔离机制
sessionFactory创建Session,sessionFactory是线程安全的,但Session 不是,所以使用ThreadLocal。
ThreadLocal为每个线程维护一个私有的变量空间,实际就是在JVM中维护一个Map, key 就是当前的线程对象,value 就是通过ThreadLocal.set 保存的对象实例,当用ThreadLocal.get 时会根据当前线程对象的引用,取回Map中对应的对象
Configuration 类负责管理Hibernate 的配置信息,Hibernate 运行时需要获得一些基本的信息,包括:
(1)数据库URL
(2)数据库用户名
(3)数据库密码
(4)JDBC驱动类
(5)数据库dialect, 用于对特定数据库提供支持
当我们调用:
new Configuration().configure();时Hibernate 会自动在CLASSPATH中搜寻hibernate.cfg.xml 将其读取到内存中作为后续操作的基本配置
SessionFactory 负责创建 Session实例,通过Configuration实例创建
Session 是持久层操作的基础,相当于JDBC中的Connection, 通过SessionFactory 实例创建
下面往数据库中插入一条记录,现在EventManager 像这样:
package road2hibernate;
import org.hibernate.*;
import org.hibernate.cfg.*;
import java.util.Date;
public class EventManager {
public static void main(String[] args) {
EventManager em = new EventManager();
Session s = HibernateUtil.currentSession();
String title = "hbm";
Date theDate = new Date();
em.store( title, theDate );
HibernateUtil.closeSession();
System.exit(0);
}
private void store(String title, Date theDate) {
try {
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
Event theEvent = new Event();
theEvent.setTitle(title);
theEvent.setDate(theDate);
session.save(theEvent);
tx.commit();
HibernateUtil.closeSession();
} catch (HibernateException e) {
e.printStackTrace();
}
}
}
现在的目录结构是这样:
|- lib
...
|- src
|--|- road2hibernate
|--|--|- Event.java
|--|--|- EventManager.java
|--|--|- HibernateUtil.java
|- classes
|--|- hibernate.cfg.xml
|--|- Event.hbm.xml
编写build.xml
<project name="hbmapp" basedir=".">
<property name="src.home" value="${basedir}/src"/>
<property name="classes.home" value="${basedir}/classes"/>
<property name="lib.home" value="${basedir}/lib"/>
<!-- "compile" target -->
<target name="compile">
<javac srcdir="${src.home}" destdir="${classes.home}" debug="on">
<classpath>
<fileset dir="${lib.home}">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<!-- "run" target -->
<target name="run">
<java classname="road2hibernate.EventManager" classpath="${classes.home}">
<classpath>
<fileset dir="${lib.home}">
<include name="*.jar"/>
</fileset>
</classpath>
</java>
</target>
</project>
5. 运行
在命令行: ant compile
然后: ant run
现在查询数据库就可以看到刚刚插入的记录了
irini
2005-12-28 22:35:01
评论:0
阅读:460
引用:0
