Hibernate学习笔记(2)

    在我的前一篇博客中,主要介绍了我的第一个hibernate项目的开发过程。这一篇博客,继续写我在学习hibernate的过程中遇到的问题以及一些hibernate的知识点,作为我学习hibernate的一点总结。

    上一篇关于hibernate的博客,我写的是完全用手动配置的方式来开发hibernate,这一篇,先写写如果在写好了domain对象和mapping对象映射文件之后,如何自动生成数据表。在这里,我切换了数据库,将Oracle切换成MySQL数据库。

    1. 首先把hibernate.cfg.xml重新配置,将原先Oracle配置信息修改成MySQL配置

<?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>
	<!-- hibernate 设计者给我们提供了一些常用的配置可在etc文件夹下找到 -->
	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
	<property name="connection.username">root</property>
	<property name="connection.password">HUHUI</property>
	<property name="connection.url">jdbc:mysql:/localhost:3306/test</property>
	<!-- 配置dialect,明确告诉hibernate连接的是哪种数据库 -->
	<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
	<!-- 显示出对应的SQL语句 -->
	<property name="show_sql">true</property>
	<!-- 让hibernate给我们自动创建表 。create表示如果没有该表,则创建-->
	<property name="hbm2ddl.auto">create</property>
	<!-- 指定对象关系映射文件 -->
	<mapping resource="com/hh/domain/Employee.hbm.xml" />
</session-factory>
</hibernate-configuration>


2. 对对象映射文件进行修改

    主要是对主键生成策略做了修改

<id name="id" column="id" type="java.lang.Integer">
	<generator class="assigned"></generator>
</id>
    这个assigned方式,是用户调用sava()方法,设置主键值


3. 运行TestMain.java文件,程序将在MySQL数据库中自动生成employee表

    在切换数据库的过程中,我没有修改java代码,只是修改了两个配置文件,十分的方便。



下面提供一套模板代码,用于在hibernate中进行回滚操作

//在hibernate中回滚事务
		Session session = MySessionFactory.getSessionFactory().openSession();
		Transaction ts = null;
		try {
			ts = session.beginTransaction();
			Employee employee = (Employee)session.load(Employee.class, 1);//这句话产生一个select语句
			employee.setName("name8");//update.这句话会导致一个update语句产生
			employee.setEmail("abc@sohu.com");
			ts.commit();
		} catch (Exception e) {
			// TODO: handle exception
			if(ts != null){
				ts.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}finally{
			//关闭session
			if(session != null && session.isOpen()){
				session.close(); 
			}
		}

当把hibernate.cfg.xml修改名字或者放在其他包内的时候,应该这样配置:

new Configuration.configure("com/hh/config/hh.cfg.xml");

下面介绍Hibernate的核心类和接口

1. Configuration

    ① 读取hibernate.cfg.xml文件

    ② 管理对象关系映射文件 <mapping resource="">

    ③ 加载hibernate驱动、url、用户名和密码

    ④ 管理hibernate配置信息


2. SessionFactory

    ① 可以加载sql语句和数据(称为session级缓存)

    ② 是一个重量级的类,占用较多内存。

    这里我们讨论通过SessionFactory获取Session的两个方法openSession()和getCurrentSession()

    a. openSession()是获取一个新的session

    b. getCurrentSession()获取的是和当前线程绑定的session,换言之,在同一个线程中,我们获取的session是同一个session,这样可以有利于我们事务的控制

    c. 如果希望使用getCurrentSession(),我们需要配置hibernate.cfg.xml

<property name="current_session_context_class">thread</property>
    关于是配置thread还是jta的问题:

    配置thread是jdbc事务,也即本地事务,是针对一个数据库的事务;

    配置jta是jta事务,也即全局事务,是跨数据库的。  

  d. 如何选择这两个方法,原则如下:

    如果在在同一个线程中,保证使用同一个session,则使用getCurrentSession;如果在一个线程中,需要使用不同的session,则使用openSession

    e. 通过getCurrentSession获取的session在事务提交后,会自动关闭,而用openSession获取的session则必须手动关闭。

    在query查询的时候,如果是使用openSession,则不需要事务处理,但是如果使用的是getCurrentSession,则需要事务处理。

Configuration cf = new Configuration().configure();
SessionFactory sf = cf.buildSessionFactory();
Session s = sf.getCurrentSession();
//Session s = sf.openSession();



3. Session接口

    ① Session一个实例代表与数据库的一次操作

    ② Session实例通过SessionFactory获取,用完需要关闭

    ③ Session是线程不同步的(不安全),因此要保证在同一个线程中使用,可以用getCurrentSession()

    ④ Session可以看做是持久化管理器,它是与持久化操作相关的接口

    Session接口的几个重要方法:

    a) 保存一个对象——sava方法

    b) 删除一个对象——delete方法

    c) 查询一个对象——get/load方法

    d) 修改一个对象——update方法

    

    get()和load()的区别

    ① 如果查询不到数据记录,那么get不会报错,而是返回一个null,而load如果查询不到数据,则抛出一个异常;

    ② 使用get去查询的时候,会立即向DB发出SQL语句查询请求;如果是用load查询,即使查询到了,返回的是一个代理对象,如果后面没有使用查询的结果,则不会向DB发出SQL语句,当程序员使用查询结果的时候,才会真的发出SQL语句,这个现象称为“懒加载”;

    ③ 通过修改配置文件,可以取消load的懒加载,在class中配置lazy=false;

    注:当用load查询时,如果后面使用了查询对象,则向DB发出SQL语句,然后将查询到的结果放在二级缓存中,当下次再查询相同的记录时,则直接在二级缓存中查询。get也是如此,第二次查询记录,也不再发一次SQL语句,而是在缓存中找。


4. Query接口

    通过Query接口我们可以完成更加复杂的查询任务,其基本用法如下:

ts = session.beginTransaction();
//获取query引用
//这里的Employee不是表明,而是domain对象名;where后面的条件,id可以是数据库中的字段名,也可以是domain中属性名
//按照hibernate的推荐,我们还是应该使用类的属性名
Query query = session.createQuery("from Employee where id=1");
//通过list方法获取结果,这个list会自动将结果封装成对应的domain对象
List<Employee> list = query.list();
for(Employee e : list){
	System.out.println(e.getEmail());
}
ts.commit();

5. Criteria接口

    这个接口用的比较少,案例如下:

ts = session.beginTransaction();
Criteria cri = session.createCriteria(Employee.class);
cri.setMaxResults(2);
cri.addOrder(Order.desc("id"));
List<Employee> list = cri.list();
for(Employee e : list){
	System.out.println(e.getId());
}
ts.commit();


下面介绍,如何使用Eclipse进行Hibernate的快速开发:

    之前的开发,都是现在数据库中建好表,然后手写domain对象和对象关系映射文件:DB(table)->手写domain对象->对象关系映射文件

    现在我们希望用工具完成domain对象和对象关系映射文件的工作。但是前提是在DB中已经建立好了表。

1. 创建web项目

2. 通过MyEclipse提供的数据库浏览器(MyEclipse Database Explorer)连接我们Oracle数据库

3. 引入hibernate开发包,同时自动创建hibernate.cfg.xml文件

4. 使用MyEclipse提供的逆向工程,自动创建domain类和对象关系映射文件





点击finish

这样,就自动生成了domain类和对象关系映射文件。

注:自动生成以后,还要配置对象映射文件的主键生成方式。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值