1.建立User类
package com.hi.model; import java.util.Date; public class User { private String id; private String name; private String password; private Date createTime; private Date expireTime; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getExpireTime() { return expireTime; } public void setExpireTime(Date expireTime) { this.expireTime = expireTime; } }
2.建立User.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"> <!-- Generated 2014-6-21 21:14:56 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.hi.model.User" table="USER"> <id name="id" type="java.lang.String"> <column name="ID" /> <generator class="assigned" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="password" type="java.lang.String"> <column name="PASSWORD" /> </property> <property name="createTime" type="java.util.Date"> <column name="CREATETIME" /> </property> <property name="expireTime" type="java.util.Date"> <column name="EXPIRETIME" /> </property> </class> </hibernate-mapping>
3.我们也映射完毕了,但是hibernate怎么知道我们映射完了呢,以及如何映射的呢?这就需要我们把我们自己的映射文件告诉hibernate,即:在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="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property> <property name="hibernate.connection.password">lh</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/info</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="javax.persistence.validation.mode">none</property>
<!-- 添加的映射文件--> <mapping resource="User.hbm.xml"/>
</session-factory> </hibernate-configuration>
4.对于sessionFactory的util类
package com.hi.util; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; public class HibernateUtil { /** * 一个Session代表一个单线程的单元操作,SessionFactory则是一个线程安全的全局对象,只需要创建一次。 */ public static SessionFactory sessionFactory=null; static { try { // Create the SessionFactory from hibernate.cfg.xml Configuration cfg = new Configuration().configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build(); sessionFactory = cfg.buildSessionFactory(serviceRegistry); } 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> session = new ThreadLocal<Session>(); 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(); // Store it in the ThreadLocal variable session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = (Session) session.get(); if (s != null) s.close(); session.set(null); } }
5.service操作方法
package com.hi.test; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import com.hi.model.User; import com.hi.util.HibernateUtil; public class Service { Session session = null; public Service(){ session = HibernateUtil.currentSession(); } public void closeSession(){ if(session.isOpen()) session.close(); } /** * 向数据库中添加一行 */ public void addRow(){ session.beginTransaction(); User user = new User(); user.setId("4"); user.setName("lisi"); user.setPassword("456"); user.setCreateTime(new Date()); user.setExpireTime(new Date()); //保存User对象 session.save(user); //提交事务 session.getTransaction().commit(); } /** * 获取到数据库的一行 * load用来加载一个持久化的对象实例,这种加载就是根据持久化类的标识属性值加载持久化实例-其实质就是根据逐渐从数据库表中加载一条新的记录 * 如果没有匹配的数据库记录,则会报HibernateException异常。吴国我们再类映射的时候制定了延迟加载,则load()会返回一个未初始化的代理对象 * ,这个代理对象并没有装载数据记录,直到程序调用该代理对象的某方法时,Hibernate才会去访问数据库 */ public void loadRow(){ session.beginTransaction(); User user = (User) session.load(User.class, new String("1")); System.out.println(user.getId()); System.out.println(user.getName()); System.out.println(user.getPassword()); System.out.println(user.getCreateTime()); } //get 与 load的主要区在于是否延迟加载使用load方法将具有延迟加载功能,load方法不会立即访问数据库,当试图加载的记录不存在时,load方法可能返回一个未初始化的 //代理对象。而get方法总会立即访问数据库,当试图加载的记录不存在的时候,返回null /** * 与load()方法类似的是get(),get()方法也用于根据主键装载持久化实例,但get()方法会立即访问数据库,如果没有u地赢得记录,get() * 方法会返回null,而不是返回一个代理对象。 * */ public void getRow(){ session.beginTransaction(); User user = (User)session.get(User.class, new String("1")); System.out.println(user.getId()); System.out.println(user.getName()); System.out.println(user.getPassword()); System.out.println(user.getCreateTime()); } /** * 一旦加载了该持久化实例后,该尸体就处于持久化状态,在代码中对持久化实例所做的修改。 * 这种修改将被保存到数据库,对标题的修改被映射成修改数据表的特定行的特定列。 * 程序对持久化实例所做的修改会在session flush之前被自动保存到数据库中,无需调用别的方法。 */ public void setUpdate(){ session.beginTransaction(); User user = (User)session.get(User.class, new String("1")); user.setName("Lisinopril"); session.flush(); } }
文件目录结构
最后添加一点:
对于一个曾经持久化过的、但是现在已脱离了Session管理的持久化对象,我们把它称为处于托管状态。当我们修改托管对象的状态后,程序应该使用新的session来保存这些修改。Hibernate提供了update、Merge。和UpdateOrSave 等方法来保存这些修改。
例如下面:
News n = firstSess.load(News.class,New Integer(pk)); //第一个session已经关闭 firstSess.close(); n.setTitle("new"); //打开第二个session Session secondsess=...... //保存托管对象所做的修改 secondsess.update(n);
当我们用另外一个session来保存这种修改后,该托管对象再次回到session的管理之下,也就是再次回到了就持久化对形象。
当需要使用update来保存程序对持久化对象所做的修改时,如果不清楚该对象是否曾经持久化过,那么程序可以选择使用updateOrSave()方法,该方法自动判断对象是否曾经持久化,如果曾经持久化过,就使用update操作,否则使用save()。
merge()方法也可以将程序对托管对象所做的修改保存到数据库,但是merger()与update()方法最大的区别是:merge()方法不会持久化给定的对象。例如:当我们执行sess.update(a)代码后,a对象将会变成持久化状态;而执行sess.merge(a)代码后,a对象依然不是持久化状态,a对象依然不会被关联到session上。
当程序使用merge()方法来保存程序对托管对象所做的修改时,如果Session中存在相同持久化标识的持久化对象,merge()方法里提供对象的状态将覆盖原有持久化实例的状态。如果Session中没有响应的持久化实例,则尝试冲数据库加载或创建新的持久化实例,最后返回该持久化实例。
当我们使用load()或者get()方法时,还可指定一个“锁模式”参数。Hibernate使用LockMode对象代表锁模式,LockMode提供了READ、UPGRADE两个静态属性来代表共享。修改锁。
可以使用
News n = Session.get(News.class,new Integer(pk),LockMode.UPGRADE);