Hibernate学习笔记(3)

两年前曾经学习过Hibernate,也通过博客将Hibernate的学习过程记录下来了,地址如下:

Hibernate学习笔记(1)

Hibernate学习笔记(2)

最近在复习Hibernate,在重新学习的过程中,有了一些新的体会和收获,现在将其总结成博客,供以后作为参考资料使用。


一、导入相应的jar包

目前Hibernate更新到了4.x版本,在官网下载后,找到lib文件加中的required文件夹,此外还需要额外导入log4j和数据库驱动包。


二、创建Hibernate配置文件

在src目录下创建相应的hibernate.cfg.xml在这个文件中加入相应的数据库配置信息,而Hibernate.cfg.xml文件可以在Hibernate下载文件夹中找到模板。

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<property name="show_sql">true</property>
		<!-- hibernate基本配置 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 配置方言,用来确定连接的数据库 -->
		<!-- 数据库的连接 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">123456</property>
		<!-- 自动完成类到数据包的转化 -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		
		<!-- 加入实体类的映射文件 -->
		<mapping resource="com/hib/model/User.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

三、创建实体类

public class User {

	private int id;
	private String username;
	private String password;
	private String nickname;
<span style="white-space:pre">	</span>//省略setter和getter方法

实体类创建好了,需要创建相应的hbm文件:

<?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 package="com.hib.model">

	<class name="User" table="t_user">
		<id name="id">
			<generator class="native" /> <!-- native自动递增 -->
		</id>
		
		<property name="username"/>
		<property name="password"/>
		<property name="nickname"/>
		<property name="born" type="timestamp"/>

	</class>

</hibernate-mapping>

并将User.bhm.xml文件在Hibernate的配置文件中注册:

<mapping resource="com/hib/model/User.hbm.xml"/>

四、创建HibernateUtil.java类

创建SessionFactory,它是线程安全的,所以整个SessionFactory应该基于单例的模式来创建。

public class HibernateUtil {

	private final static SessionFactory FACTORY = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {
		Configuration cfg = new Configuration().configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
				.applySettings(cfg.getProperties()).buildServiceRegistry();
		SessionFactory factory = cfg.buildSessionFactory(serviceRegistry);
		return factory;
	}

	public static SessionFactory getSessionFactory() {
		return FACTORY;
	}

	public static Session openSession() {
		return FACTORY.openSession();
	}

	public static void close(Session session) {
		if (session != null) {
			session.close();
		}
	}
}

五、CRUD操作

5.1 测试插入数据

        @Test
	public void testAdd() {
		Session session = null;
		Transaction transaction = null;
		try {
			session = HibernateUtil.openSession();
			transaction = session.beginTransaction();
			User u = new User(1, "悟净", "123456", "沙僧", new Date());
			session.save(u);
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
			if(session != null){
				transaction.rollback();
			}
		}finally{
			HibernateUtil.close(session);
		}
	}

5.2 测试load方法

        @Test
	public void testLoad() {
		Session session = null;
		try {
			session = HibernateUtil.openSession();
			User u = (User) session.load(User.class, 1); <span style="font-family: Arial, Helvetica, sans-serif;">//只有当使用user时,才发出sql语句,否则不发sql语句</span>
			User user = (User) session.get(User.class, 2); //无论是否使用user,都会发出sql语句
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			HibernateUtil.close(session);
		}
	}
延迟加载:当完成了load操作以后,并不会马上发出sql语句,只有在使用该对象时才会发出sql。当完成load之后,其实返回一个代理对象,这个代理对象中仅仅只有一个id的值,所以,如果仅仅是打印id,则是不会发出sql语句的。
而Hibernate的get方法无论是否使用user,都会发出sql语句去查询,没有延迟加载的问题。


5.3 测试update方法

        @Test
	public void testUpdate() {
		Session session = null;
		Transaction transaction = null;
		try {
			session = HibernateUtil.openSession();
			transaction = session.beginTransaction();
			User u = (User) session.load(User.class, 1);
			u.setNickname("小四");
			session.update(u);
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
			if(session != null){
				transaction.rollback();
			}
		}finally{
			HibernateUtil.close(session);
		}
	}

5.4 测试delete方法

        @Test
	public void testDelete() {
		Session session = null;
		Transaction transaction = null;
		try {
			session = HibernateUtil.openSession();
			transaction = session.beginTransaction();
			User u = new User();
			u.setId(1);
			session.delete(u);
			transaction.commit();
		} catch (Exception e) {
			e.printStackTrace();
			if(session != null){
				transaction.rollback();
			}
		}finally{
			HibernateUtil.close(session);
		}
	}

5.5 测试List方法

        @Test
	public void testList() {
		Session session = null;
		try {
			session = HibernateUtil.openSession();
			List<User> users = session.createQuery("from User").list();
			System.out.println(users);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			HibernateUtil.close(session);
		}
	}

5.6 测试分页

        @Test
	public void testPager() {
		Session session = null;
		try {
			session = HibernateUtil.openSession();
			List<User> users = session.createQuery("from User").setFirstResult(0).setMaxResults(2).list();
			System.out.println(users);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			HibernateUtil.close(session);
		}
	}

六、Hibernate的三种状态

临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;

持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;

游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;

已经有人对Hibernate的三种状态做了详细的描述,请参考:http://www.cnblogs.com/xiaoluo501395377/p/3380270.html

技术分享


七、ManyToOne单向

所谓ManyToOne的关系,如Student和Classroom的关系,多个Student对应一个Classroom。一般是在many的一方添加外键:

public class Classroom {
	private int id;
	private String name;
	private int grade;

public class Student {
	private int id;
	private String name;
	private String no;
	private Classroom classroom;

在添加数据的时候,应该先添加One,再添加Many:

//先添加one
Classroom classroom = new Classroom(1, "计算机网络", 2015);
session.save(classroom);
//再添加many
Student stu1 = new Student(1, "孙悟空", "001", classroom);
session.save(stu1);
Student stu2 = new Student(1, "猪八戒", "002", classroom);
session.save(stu2);


<!-- many-to-one用来映射多对一,name表示对象中属性名称,column表示属性名称 -->
<!-- 当设置了cascade时,会自动完成关联对象,会自动创建一个关联对象 -->
<!-- 如果没有特殊情况,不要使用cascade,可能使用cascade的地方,一般都是one的一方进行删除时使用,特殊需求才会使用cascade,正常情况add方法都是由程序员完成添加 -->
<many-to-one name="classroom" column="cid" cascade="all"></many-to-one>


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。