认识Hibernate

1. Hibernate的体系结构

Hibernate的持久化解决方案是将用户从原始的JDBC访问中释放出来,用户无须关注底层的JDBC操作,而是以面向对象的方式进行持久层操作。底层数据库连接的获取、数据访问的实现、事务控制都无须用户关心。这是一种“全面解决”的体系结构方案,将应用层从底层JDBC/JTA API中抽取出来。通过配置文件管理底层的JDBC连接,让Hibernate解决持久化访问的实现。如下是Hibernate全面解决方案的体系架构。


下面对这张图进行解释。

1)        SessionFactory:这是Hibernate的关键对象,它是单个数据库映射关系经过编译后的内存镜像,也是线程安全的。它是生成Session的工厂,本身需要依赖于ConnectionProvider。该对象可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存。

2)        Session:它是应用程序与持久存储层之间交互操作的一个单线程对象。它也是Hibernate持久化操作的关键对象,所有持久化对象必须在Session管理下才可进行持久化操作。此对象生存期很短。它底层封装了JDBC连接,它也是Transaction的工厂。Session对象持有必选的一级缓存,显示执行flush之前,所有持久化操作的数据都在缓存中的Session对象处。

3)        持久化对象(Persistent Object):系统创建的POJO实例,一旦与特定的Session关联,并对应数据表的指定记录,该对象就处于持久化状态,这一系列对象都被称为持久化对象。在程序中对持久化对象执行的修改,都将自动被转换为对持久层的修改。持久化对象完全可以是普通的JavaBeans/POJO,唯一的区别是正与一个Session关联。

4)        瞬间对象和脱管对象:系统通过new关键字创建的Java实例,没有与Session相关联,此时处于瞬态。瞬态实例可能是在被应用程序实例化后,尚未进行持久化的对象。如果一个曾经持久化过的实例,如果Session被关闭则是转化为脱管状态。

5)        事务(Transacton):代表一次原子操作,这它具有数据库事务的概念。Hibernate事务是对底层具体的JDBC、JTA以及CORBA事务的抽象。在某些情况下,一个Session之内可能包含多个Transaction对象。虽然事务操作是可选的,但所有操作都应该在事务管理下进行,即使是只读操作。

6)        连接提供者(ConnectionProvider):它是生成JDBC连接工厂,它通过抽象将应用程序与底层DataSource或DriverMananger隔离开。这个对象无须应用程序直接访问,仅应用程序需要扩展时使用。

7)        事务工厂(TransactionFactory):它是生成Transaction对象实例工厂。该对象也无须应用程序直接访问。它负责对底层具体的事务实现进行封装,将底层具体的事务抽象成Hiberate事务。

2. Hibernate简单应用

1)        将普通的JavaBean进行持久化,这个持久化需要为这个POJO添加一些注解。

 @Entity
@Table(name="news_inf")
public class News
{
	// 消息类的标识属性
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	// 消息标题
	private String title;
	// 消息内容
	private String content;

	// id的setter和getter方法
	public void setId(Integer id)
	{
		this.id = id;
	}
	public Integer getId()
	{
		return this.id;
	}

	// title的setter和getter方法
	public void setTitle(String title)
	{
		this.title = title;
	}
	public String getTitle()
	{
		return this.title;
	}

	// content的setter和getter方法
	public void setContent(String content)
	{
		this.content = content;
	}
	public String getContent()
	{
		return this.content;
	}
}

上面的注解解释:

a)        @Entity注解声明该类是一个Hibernate的持久化类。

b)        @Table指定该类映射的表。此处指定该类映射到news_inf表。

c)        @Id用于指定该类的标识属性。所谓标识属性,就是可以唯一标识该对象的属性,标识属性通常映射到数据表的主键列。

d)        @GeneratedValue用于指定主键生成策略,其中strategy属性指定了主键生成策略为IDENTITY策略,也就是采用自动增长的主键生成策略。

2)        Hibernate配置文件既可以使用*.properties属性文件,也可以使用XML文件属性。在实际应用中,通常使用XML文件配置。下面,我们配置hibernate.cfg.xml文件。

 <?xml version="1.0" encoding="GBK"?>
<!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="connection.driver_class">com.mysql.jdbc.Driver</property>
		<!-- 指定连接数据库的url,其中hibernate是本应用连接的数据库名 -->
		<property name="connection.url">jdbc:mysql://localhost/hibernate</property>
		<!-- 指定连接数据库的用户名 -->
		<property name="connection.username">root</property>
		<!-- 指定连接数据库的密码 -->
		<property name="connection.password">32147</property>
		<!-- 指定连接池里最大连接数 -->
		<property name="hibernate.c3p0.max_size">20</property>
		<!-- 指定连接池里最小连接数 -->
		<property name="hibernate.c3p0.min_size">1</property>
		<!-- 指定连接池里连接的超时时长 -->
		<property name="hibernate.c3p0.timeout">5000</property>
		<!-- 指定连接池里最大缓存多少个Statement对象 -->
		<property name="hibernate.c3p0.max_statements">100</property>
		<property name="hibernate.c3p0.idle_test_period">3000</property>
		<property name="hibernate.c3p0.acquire_increment">2</property>
		<property name="hibernate.c3p0.validate">true</property>
		<!-- 指定数据库方言 -->
		<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
		<!-- 根据需要自动创建数据表 -->
		<property name="hbm2ddl.auto">update</property><!--①-->
		<!-- 显示Hibernate持久化操作所生成的SQL -->
		<property name="show_sql">true</property>
		<!-- 将SQL脚本进行格式化后再输出 -->
		<property name="hibernate.format_sql">true</property>
		<!-- 罗列所有持久化类的类名 -->
		<mapping class="com.owen.app.domain.News"/>
	</session-factory>
</hibernate-configuration>

Hibernate配置文件的根元素是<hibernate-configuration…/>,根元素里有<session-factory…/>子元素,该元素依次有很多<property…/>子元素,这些<property…/>子元素配置Hibernate连接数据的必要信息,如连接数据库的驱动、URL、用户名、密码等信息。<session-factory…/>元素还可以接受多个<mapping../>元素,每个元素指定一个持久化类,<mapping…/>元素有class属性指定Hibernate持久化类的类名。

3)        下面是完成消息插入的代码。

 public class NewsManager
{
	public static void main(String[] args)
		throws Exception
	{
		// 实例化Configuration,
		Configuration conf = new Configuration()
		// 不带参数的configure()方法默认加载hibernate.cfg.xml文件,
		// 如果传入abc.xml作为参数,则不再加载hibernate.cfg.xml,改为加载abc.xml
			.configure();
		ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
			.applySettings(conf.getProperties()).build();
		// 以Configuration实例创建SessionFactory实例
		SessionFactory sf = conf.buildSessionFactory(serviceRegistry);
		// 创建Session
		Session sess = sf.openSession();
		// 开始事务
		Transaction tx = sess.beginTransaction();
		// 创建消息对象
		News n = new News();
		// 设置消息标题和消息内容
		n.setTitle("my title");
		n.setContent("owen,"
			+ "网站地址http://www.owen.org");
		// 保存消息
		sess.save(n);
		// 提交事务
		tx.commit();
		// 关闭Session
		sess.close();
		sf.close();
	}
}

3)        例子总结

从上面的例子中我们可以有以下的总结:

a)        开发持久化类,由  POJO+持久化注解组成。

b)        获取Configuration。

c)        获取Session,打开事务。

d)        用面向对象的方式操作数据库。

e)        关闭事务,关闭Session。

      PO与Session的关联关系,PO可有如下三种状态:

a)        瞬态:如果PO实例从未与Session关联过,该PO实例处于瞬态状态。

b)        持久化:如果PO实例与Session关联起来,且该实例应用到数据库记录,则实例处于持久化状态。

c)        脱管:如果PO实例曾经与Session关联过,但因为Session的关闭等原因,PO实例脱离了Session的管理,这种状态被称为脱管状态。

3.连接池概念

       数据源是一种提高数据库连接性能的常规手段,数据源会负责维持一个数据连接池,当程序创建数据源实例时,系统会一次性地创建多个数据库连接,并把这些数据库连接保存在连接池中。当程序需要进行数据库访问时,无须重新获得数据库连接,而是从连接池中取出一个空闲的数据库连接,当程序使用数据库连接访问数据库结束后,无须关闭数据库连接,而是将数据库连接归还给连接池即可。通过这种方式,就可避免频繁地获取数据库连接,关闭数据库连接所导致的性能下降。

4.总结

对比于原先的JDBC两操作数据库的方式,Hibernate以下的好处:

1)        不再需要编写SQL语句,而是允许采用OO方式来访问数据库。

在JDBC访问过程中大量的cheched异常被包装成Hibernate的Runtime异常,从而




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值