`
yxwang0615
  • 浏览: 560895 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

Hibernate3.2(四)生命周期示例、CRUD操作、Junit 3单元测试

阅读更多

 抽时间 总结junit3和junit4的相关测试方法 ,junit4采用的是annotations

junit3 命名规范: 测试类 xxxTest 测试方法void testxxx() ,方法中可以用断言assertEquals(expected, actual).

测试类需要继承TestCase , 在工程中新建一个source folder,在其中建好包,包名最好和要测的类所在的包一样。

 

1.用Junit 3 编写一个测试类SessionTest来测试 & 探索Hibernate 三种对象的生命周期

 

  熟悉hibernate的CRUD操作,主要方法有:get()、load()、save()、delete()、update()

package com.wyx.hibernate;

import java.util.Date;

import junit.framework.TestCase;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.wyx.hibernate.utils.HibernateUtils;
/**
 * 使用junit做测试多个方法比较方便,junit中还有setup()和Deardown(),用来初始化和销毁
 * setup()一般放的是
 * @author bird
 */
public class SessionTest extends TestCase{
	
	//public 无return
	public void testHello(){
		System.out.println("----------SessionTest.testHello()----------");
		//throw new  java.lang.RuntimeException();
		//this.assertEquals("hello", "no hello");
	}
	public void testSession(){
		Session session = HibernateUtils.getSession();
		Transaction ts = session.beginTransaction();
		User u = new User();
		try {
			//Transient状态
		
			//uid不需要赋值,自动赋值
			u.setName("李四");
			u.setPassword("123");
			u.setCreateTime(new Date());
			u.setExpireTime(new Date());
			session.save(u);//单步调试表明,在执行完save()后,uid的值才产生
			System.out.println("---------mark-----------");
			//save()后变成persistent状态
			u.setName("王五");
			//persistent状态的时候,不需要手动update,hibernate会自动和数据库同步
			//session.update(u);
			ts.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			ts.rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
		//Detached状态
		u.setName("张三");
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			session.update(u);
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			ts.rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}
	
} 

 

 

 运行结果:

----------SessionTest.testHello()----------
---------mark-----------
Hibernate: insert into User (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)
Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?
Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?

 运行结果表明,一个对象处于Persistent状态时,当属性发生改变的时候,Hibernate会自动和数据库同步,Hibernate只是把这些数据放在缓存中处理,而且是在commit()提交的时候才执行所有的数据库操作。

产生多条sql语句的原因是:hibernate在修改数据之前要先照一个快照,接下来修改了对象u.setName("王五"),在commit的时候,需要清理缓存(内从中的对象),脏数据是指没有提交的数据,commit()之前清理缓存的这个过程中要执行脏数据对比,脏数据对比的主要工作是处理哪些数据要发成insert,哪些数据要发成update语句。

当session关闭的时候,session已经不再管理u对象,u对象虽然变成了Detached状态,但是数据库中该条记录依然存在,当执行update的时候,数据库中u对应的那条记录name字段又变成了“张三”,update之后,该u对象又变成了Persistent状态的。

 

 接着在SessionTest中写一个方法,运行:

	public void testReadByGetMethod(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			//将数据库中对应id的那条记录取出来存在User对象中,此时立即产生sql语句
			User u =(User)session.get(User.class, "402881fa2edaffe9012edaffea5c0001");
			System.out.println("-------------mark----------------");
			//修改u , persistent状态的时候,不需要手动update,hibernate会自动和数据库同步
			u.setName("jeff");
			session.getTransaction().commit();
		} catch (HibernateException e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}

 

 运行结果:

Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.password as password0_0_, user0_.createTime as createTime0_0_, user0_.expireTime as expireTime0_0_ from User user0_ where user0_.id=?
-------------mark----------------
Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?

 

 

public void testReadByGetMethod1(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			User u =(User)session.get(User.class, "adfsafa");
			session.getTransaction().commit();
		} catch (HibernateException e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}

 运行结果:Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.password as password0_0_, user0_.createTime as createTime0_0_, user0_.expireTime as expireTime0_0_ from User user0_ where user0_.id=?
调试跟踪表明,u对象值为null,但是单元测试没有报错,所以采用get()加载数据,如果数据中不存在相应的数据,返回null。

 

	public void testReadByLoadMethod1(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			//不会发出查询sql,因为load方法实现了lazy()
			//懒加载 or 延迟加载,真正使用这个对象的时候,才加载(发出sql语句)
			//hibernate延迟加载实现原理是代理方式
			User u =(User)session.load(User.class, "402881e62ed3df84012ed3df85510001");
			System.out.println("----------mark------------");
			System.out.println("u.name: " + u.getName());
			session.getTransaction().commit();
		} catch (HibernateException e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}

 

 

运行结果:

----------mark------------
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.password as password0_0_, user0_.createTime as createTime0_0_, user0_.expireTime as expireTime0_0_ from User user0_ where user0_.id=?
u.name: jeff

代理类是使用CGLIB工具生成代理类,代理类继承了User。

	public void testReadByLoadMethod2(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			//采用load加载数据,如果数据库中没有相应数据,
			//那么抛出ObjectNotFoundException的异常
			User u =(User)session.load(User.class, "adadfafdf");
			System.out.println("----------mark------------");
			System.out.println("u.name: " + u.getName());
			session.getTransaction().commit();
		} catch (HibernateException e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}

 运行结果:

----------mark------------
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.password as password0_0_, user0_.createTime as createTime0_0_, user0_.expireTime as expireTime0_0_ from User user0_ where user0_.id=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.wyx.hibernate.User#adadfafdf]

从上述get和load的测试方法可见:

1. get()不支持lazy, load()是支持lazy的(懒加载);

2. get()查询数据的时候,查不到返回null。而load()抛出org.hibernate.ObjectNotFoundException。注意,执行load方法的时候是不会报错的,在调用保存load的那个对象时才会抛出异常。

 

测试update():

public void testUpdate1(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			//虽然是我们自己new出来的,但是id在数据库中存在,所以这属于手动构造的 Detached 对象
			User u = new User();
			u.setId("402881e62ed40ec1012ed40ec2f10001");
			u.setName("小明");
			u.setPassword("123");
			session.update(u);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}

 测试结果:

Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?

虽然手动构造的Detached对象可以update到数据库,但是,万一有字段没setvalue就会更新空数据进DB,所以最好的做法还是操作一个从数据库get或load的对象,因为该对象已经填充了值。

 

测试Delete():

public void testDelete(){
		Session session = HibernateUtils.getSession();
		try {
			session.beginTransaction();
			User u = (User)session.load(User.class, "402881e62ed40ec1012ed40ec2f10001");
			session.delete(u);
			session.getTransaction().commit();
		} catch (HibernateException e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}

 测试结果:

Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.password as password0_0_, user0_.createTime as createTime0_0_, user0_.expireTime as expireTime0_0_ from User user0_ where user0_.id=?
Hibernate: delete from User where id=?

在删除一条记录的时候,操作的也是对象,所以把对象根据id用get或load获取到,然后session.delete(u);

 

小结:

transient状态的特征:

1. 在数据库中没有与之匹配的记录;

2. 没有纳入session的管理;

Persistent状态的特征:

1. 对象在数据库中有与之匹配的记录;

2. 纳入了session的管理;

3. 在清理缓存(脏数据检查)的时候,会和数据库同步(内存检查、清理缓存的目的是:看缓存发生有没有变化,从而判断到底发什么hql语句,eg:在save完了后,修改了对象,发了两条:一条insert一条update,这就是脏数据检查的好处);

Detached状态的特征:

1. 在数据库中有与之匹配的记录;

2. 没有纳入session的管理;

 

 

在实际应用中,我们经常需要根据表中的非id字段查询一个对象(一条记录),或者全部的数据,就要用到HQL。

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Struts1.3_Spring3.0_hibernate3.3示例

    8. **JUnit测试**:测试数据库操作的正确性,通常包括对Service层方法的单元测试。 通过学习这个示例,开发者可以深入理解SSH框架集成的实践,掌握如何在实际项目中应用这些技术,提高开发效率和代码质量。同时,这...

    maven项目hibernate demo

    Maven的生命周期包括编译、测试、打包、验证等阶段,通过简单的命令行指令即可完成整个构建过程。 接着,Hibernate是一个流行的Java持久层框架,它简化了对象关系映射(ORM),使得开发者可以使用Java对象模型来...

    jpa + hibernate 例子

    3. **持久化(Persistence)**: JPA提供了`EntityManager`接口来管理实体的生命周期,包括创建、读取、更新和删除(CRUD操作)。例如,`entityManager.persist(entity)`用来保存新实体,`entityManager.find(Entity....

    jsf+spring+hibernate示例,使用MyEclipse工具

    8. **单元测试和集成测试**:使用JUnit或其他测试框架对Spring和Hibernate组件进行测试,确保功能的正确性。 9. **最佳实践**:学习如何遵循良好的编码和设计规范,以实现可维护、可扩展的代码结构。 这个示例项目...

    springMvc+hibernate4+spring整合实例

    8. 测试与调试:使用JUnit进行单元测试,确保每个组件正常工作。 通过这样的整合,开发者可以获得一套完整的、松散耦合的Java Web应用程序开发解决方案,能够高效地处理业务逻辑和数据库操作,同时保持代码的可维护...

    Hibernate Recipes

    - **事务管理**: 支持本地事务和JTA事务,通过`Transaction`或`UserTransaction`接口管理事务生命周期。 - **性能调优**: 如调整SQL查询、使用批处理、优化检索策略等手段提高应用程序的整体性能。 6. **集成...

    hibernate基础教程附带光盘源码

    Hibernate提供了四种状态(Transient、Persistent、Detached、Removed)来管理对象的生命周期,以及相应的API(save()、persist()、update()、merge()、delete())来操作这些状态。 6. **懒加载与级联操作** 懒...

    Spring+struts+hibernate整合图解

    整合过程中,Spring作为核心容器,管理着所有组件的生命周期,包括Struts的Action和Hibernate的SessionFactory。Struts处理HTTP请求,调用Spring管理的业务层服务,这些服务又通过Spring的数据访问层接口来操作...

    hibernate学习笔记

    测试实体对象的生命周期通常使用 JUnit,创建测试类并编写以 test 开头的方法。了解 CRUD(Create, Read, Update, Delete)操作是数据库操作的基础。get 和 load 方法的区别在于对懒加载(lazy loading)的支持,get...

    struts2+Hibernate+Spring整合开发代码

    9. **测试**:了解如何使用JUnit进行单元测试,以及如何结合Mockito模拟Spring和Hibernate组件进行集成测试。 通过深入研究这个整合项目,开发者不仅可以掌握三个框架的基本用法,还能学习到如何在实际项目中灵活...

    spring+struts+hibernate整合demo

    在本示例中,Hibernate可能被用来处理数据持久化,通过SessionFactory创建Session对象,进而进行CRUD(Create, Read, Update, Delete)操作。Spring可以管理和初始化Hibernate的SessionFactory,使得数据库操作可以...

    spring-hibernate-example1

    在Spring中,开发者可以利用IoC(Inversion of Control)容器来管理对象的生命周期和相互依赖关系,从而实现松耦合。 Hibernate则是一个强大的ORM框架,它为Java开发者提供了一种将Java对象与数据库表之间进行映射...

    springmvc+hibernate+spring学生表增删改查.zip

    该压缩包文件"springmvc+hibernate+spring学生表增删改查.zip"涉及到的是一个基于Java技术栈的Web应用程序开发示例,主要利用Spring MVC、Hibernate和Spring框架来实现学生信息表的CRUD(创建、读取、更新、删除)...

    hibernate+spring学习例子

    在Spring中,通过配置文件或注解来管理对象的生命周期和依赖关系,使得代码更加模块化和可测试。 其次,Hibernate作为ORM框架,允许开发者用面向对象的方式处理数据库操作。它通过映射Java类到数据库表,将SQL语句...

    Struts2+Hibernate整合实例

    通过JUnit进行单元测试,验证Action和DAO层的功能。同时,可以使用Struts2的开发插件(如Struts2 Debug Plugin)来调试Action的执行流程和结果。 6. **示例项目`Hibernate-Example-1`**: 这个压缩包可能包含了一...

    spring hibernate project

    5. 测试:编写 JUnit 测试用例,验证 CRUD 操作是否正常工作。 文件名 "springhibernate" 可能是指项目主目录或者打包后的文件,其中可能包含了上述所有配置文件、Java 源代码和测试类。为了深入理解这个项目,你...

    spring hibernate demo

    6. **单元测试**: 一个完整的示例项目通常会有相关的测试代码,可能使用JUnit或其他测试框架,以确保Spring和Hibernate的集成工作正常。测试可以帮助验证数据库操作是否正确,以及事务管理是否按预期进行。 7. **...

    spring快速开发入门教程

    - **示例**:例如,可以通过编写功能性测试来验证用户的增删改查(CRUD)操作是否正确无误地执行。 2. **配置Hibernate和Transaction** - Hibernate是一个流行的ORM框架,用于简化Java应用与数据库之间的交互。本...

    HibernateWeb

    在实际开发中,你需要理解Maven的生命周期和构建过程,熟悉Hibernate的配置和映射机制,掌握如何在Java代码中操作Session。此外,了解一些基本的SQL知识也是必要的,因为有时仍需要直接写SQL语句进行复杂查询。 总...

    Struts2+Spring+Hibernate_Demo

    在这个示例中,Spring主要负责管理Bean的生命周期,以及整合其他两个框架。通过Spring的ApplicationContext,我们可以配置Bean之间的依赖关系,实现服务的自动装配。 Hibernate是一个强大的ORM(对象关系映射)框架...

Global site tag (gtag.js) - Google Analytics