1. 写一个工具类专门处理session
import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;
public class HibernateUtils {
private static SessionFactory factory; static { try { Configuration cfg = new Configuration().configure(); factory = cfg.buildSessionFactory(); }catch(Exception e) { e.printStackTrace(); } } public static SessionFactory getSessionFactory() { return factory; } public static Session getSession() { return factory.openSession(); } public static void closeSession(Session session) { if (session != null) { if (session.isOpen()) { session.close(); } } }}
2. 用junit来做测试,状态转换基本例子
import java.util.Date;
import org.hibernate.Session;import org.hibernate.Transaction;
import junit.framework.TestCase;
public class SessionTest extends TestCase {
public void testSave1() { Session session = null; Transaction tx = null; User user = null; try { session = HibernateUtils.getSession(); tx = session.beginTransaction(); //Transient状态 user = new User(); user.setName("李四"); user.setPassword("123"); user.setCreateTime(new Date()); user.setExpireTime(new Date()); //persistent状态。此时user的id属性被赋值,但是user只在缓存没在数据库中。由此将生成insert语句
session.save(user);
/* session.save() 方法具体理解:
1、这个例子走到save时,不会生成insert语句,但是会分配id值。是因为generator为uuid时,由hibernate负责计算id值。等到commit时,才会执行insert语句。
2、如果 generator为native(既由数据库生成主键值时),走到save时,会生成执行insert语句,由数据库给主键分配值。 但是!此时查数据库并不会看到这条数据(这条数据已经存在),这是跟数据库的隔离级别有关。因为有回滚机制,如果出错,这条被插入的数据还是会被删除。 */
user.setName("王五");// 由此将生成update语句 //session.update(user); tx.commit(); }catch(Exception e) { e.printStackTrace(); tx.rollback(); }finally { HibernateUtils.closeSession(session); } //detached状态 user.setName("张三"); try { session = HibernateUtils.getSession(); session.beginTransaction(); //persistent状态 session.update(user); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
}
3、get()方法, 只能根据主键加载
public void testReadByGetMethod1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); //马上发出查询sql,加载User对象 User user = (User)session.get(User.class, "402880d01b9bf210011b9bf2a2ff0001"); System.out.println("user.name=" + user.getName()); //persistent状态,当属性发生改变的时候,hibernate会自动和数据库同步 user.setName("龙哥");
// 注意 这里再拿一次这个对象时,输出的name是新的数据:‘龙哥’。而数据库中的数据还是老数据(因为到commit时才能写入 数据库)
// 这说明了 session对于用户可以理解为一个最前方的数据库。get取的对象如果session中存在,就不会去数据库拿
user = (User)session.get(User.class, "402880d01b9bf210011b9bf2a2ff0001"); System.out.println("user.name=" + user.getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
public void testReadByGetMethod2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); //采用get加载数据,如果数据库中不存在相应的数据,返回null User user = (User)session.get(User.class, "asdfsafsdfdsf");
session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
4、load()例子, 只能根据主键加载
public void testReadByLoadMethod1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); //不会发出查询sql,因为load方法实现了lazy(懒加载或延迟加载) //延迟加载:只有真正使用这个对象的时候,才加载(发出sql语句) //hibernate延迟加载实现原理是代理方式 User user = (User)session.load(User.class, "402880d01b9bf210011b9bf2a2ff0001"); System.out.println("user.name=" + user.getName()); //persistent状态,当属性发生改变的时候,hibernate会自动和数据库同步 user.setName("发哥"); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
public void testReadByLoadMethod2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); //采用load加载数据,如果数据库中没有相应的数据 //那么抛出ObjectNotFoundException User user = (User)session.load(User.class, "55555555"); System.out.println(user.getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); throw new java.lang.RuntimeException(); }finally { HibernateUtils.closeSession(session); } }
5、 update()例子
public void testUpdate1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); //手动构造的detached状态的对象 User user = new User(); user.setId("402880d01b9be8dc011b9be9b23d0001"); user.setName("德华"); session.update(user); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
6、delete()例子
public void testDelete1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); // //手动构造的detached状态的对象// User user = new User();// user.setId("402880d01b9be8dc011b9be9b23d0001");// user.setName("德华");// session.delete(user); User user = (User)session.load(User.class, "402880d01b9be8dc011b9be9b23d0001"); session.delete(user); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } //transient状态 }
小结:
了解get和load的区别? * get不支持lazy,load支持lazy * 采用get加载数据,如果没有匹配的数据,返回null,而load则抛出异常 transient状态的特征? * 在数据库中没有与之匹配的数据 * 没有纳入session的管理 persistent状态的特征? * persistent状态的对象在数据库中有与之匹配的数据 * 纳入了session的管理 * 在清理缓存(脏数据检查)的时候,会和数据库同步 detached状态的特征? * 在数据库中有与之匹配的数据 * 没有纳入session的管理
相关资源:敏捷开发V1.0.pptx
