使用Hibernate 基本原理,步骤,核心,实现增删查改

                                                                                                                   Hibernate              第 一 天

 
 

1   hibernate基本原理

    1) 为什么使用hibernate?

        a  hibernate属于 M(模型层),jdbc相同,都是对数据库的操作

        b  hibernate是对jdbc的封装,底层依然是jdbc

        c  hibernate是ORM框架,O--->Object(实体类对象) R--->Relational(表)  M --->Mapping(映射)

hibernate就是用面向对象的方式,来操作数据库简化程序员的开发

        d  hibernate也叫持久层框架   

        e  市场上能占到40%左右

        f  hibernate因为底层封装jdbc,性能相比jdbc稍弱--------------------------------》*缺点面试时说)

2  简要介绍一下hibernate3.2文件

    1) doc :hibernate3.2的说明文档,包含hibernate的Api(全英文版)

    2) eg:hibernate官方提供的案例,包含User.hbm.xml

            (映射文件:实体类跟数据库表关联桥梁)

4) etc:hibernate中所有的配置,其中最重要hibernate.cfg.xml

(hibernate核心配置文件,hibernate运行必要的文件),包括一些缓存文件ehcache.xml

    4 ) lib :跟hibernate有关所有的第3方jar

    5 ) src : hibernate所有的源代码,开源框架

6 ) hibernate3.jar:hibernate核心jar

归纳hibernate特点:

(1)  简单(对于程序员)

(2)  开源

(3)  orm框架,持久层(M)框架

(4)  可以兼容现在所有主流的数据库

(5)  完全面向对象

(6) 性能不好

3  使用hibernate的步骤

2) 导入jar:hibernate_lib(共16个)

2) 导入核心配置文件:hibernate.cfg.xml,连接到数据库

(在hibernate-3.2.4.ga\hibernate-3.2\etc下有hibernate.cfg.xml

A:eclipse连接数据库:**(jdbc:mysql://localhost:3306/zhanghao?useUnicode=true&characterEncoding=utf8)

          B:配置hibernate.cfg.xml,

              

4) 创建Po类以及修改orm映射文件

A:创建po类

B:hibernate-3.2.4.ga\hibernate-3.2\里搜:XXX.hbm.xml,放在po类中。

C:修改映射文件

    D;把orm映射文件,加载到hibernate.cfg.xml中

4) 使用hibernate的Api操作

跳转至下面:3) Configuration      

案例: 使用hibernate来创建一张表

 t_user

 主键

 id      name         age          pwd

 User.hbm.xml(ORM映射文件)

 class User{

 private int id;

 private String name;

 private int age;

 private String pwd;

    //get、set

 }

 po类的属性,必须跟要创建的表的列一致

4  hibernate核心

  1)hibernate.cfg.xml: 

      a   连接数据库:Driver ,url,用户名, 密码dialect(方言) : 通过配置方言可以帮我们操作任何数据库,

底层对数据库的操作的sql语句,会自动转化对应数据库的sql

      b hibernate自身的属性:

         show_sql:把hibernate底层执行jdbc的sql语句,打印控制台上,使用hibernate必须配置该属性

      c  配置ORM映射文件:hibernate执行的时候,会读取hibernate.cfg.xml文件 ,只有把orm映射文件配置到hibernate.cfg.xml,才能加载到hibernate当中   

 2)  ORM映射文件(注意看提示{指eclipse自带的提示}):

     po类跟数据库中表,之间映射的桥梁

     <class name="com.tarena.po.User"  table="t_user">

<id name="id">//hibernate当中默认主键最重要

//generator :主键生成策略 

identity:每次添加新的数据,主键自动加1

<generator class="identity"></generator>

</id>

<!-- 配置一般属性信息 -->

    <property name="name"></property>

    <property name="age"></property>

    <property name="pwd"></property>             

3) Configuration  (上接4) 使用hibernate的Api操作

       a) 读取配置文件

       hibernate.cfg.xml (核心配置文件)

       xxx.hbm.xml (映射文件)

       b) hibernate程序只要一启动,立刻就会调用

       Configuration读取文件

       

执行Main方法,如果异常提示:

Exception in thread "main" org.hibernate.MappingException: Cannot cache an unknown entity: org.hibernate.test.legacy.Simple

可能是此处错误:将其从核心配置文件:hibernate.cfg.xml删除

    4) SessionFactory

    重量级对象(资源):大量侵占内存资源,功能强大

     a)创建Session (SessionFactory是产生Session的工厂

     b)管理hibernate二级缓存(以后讲)

     c)一个项目对应/一个数据库中对应一个SessionFactory,生命周期很长,跟整个系统生命周期一致   

     

      

     5) Session:

     Hibernate当中最核心的(功能)类,hibernate对数据库中都依赖Session来实现的        

       a) Session:可以实现增删查改

       b)session的生命周期较短,代表一个用户对数据库访问的一个连接

       c)每次对数据库的操作都要使用session,(最好能把session跟当前访问用户绑定在一起)

      6)Transaction:

      hibernate中管理事务:

      Hibernate的事务是手动提交的,必须要开启事务,并提交才可以改变表中的数据

      jdbc 自动的提交事务:关闭jdbc自动提交方法

        

  

5  使用hibernate来实现增删查改

     1) load get

          a) load 去数据库查询一个不存在的数据,会直接抛出一个异常(ObjectNotFoundException)

                get去数据库查询一个不存在的数据,会返回一个null值对象;

           b)load方法支持延迟加载,当访问该对象的属性,才发出sql对数据库查询

                 get方法不支持延迟加载,使用get方法立刻发出sql语句,去数据库中查询

      2) 延迟加载:需要才发出sql,去数据库中查询

      3) hibernate底层怎么实现延迟加载的/load返回对象是什么类型的? 

        Emp emp =  (Emp) session.load(Emp.class, 1);  

           a) load返回的对象,不是emp对象,没有去数据库中真实查询,所以没有发出sql语句

            b)load返回的是一个代理对象(代替要查询的对象叫做代理对象),该代理对象来暂时代替emp对象

            c) 该代理对象是目标对象的子类对象

     (该子类对象是hibernate内部自动生成,跟我们无关)

   eg: class  Student extends Person{}

         Person person = new Student();   

            d) 这是代理模式:cglib动态代理,能提高hibernate性能,减少对数据库的访问次数 

案例:hibernate_day01Pm

创建一张员工表t_emp

id          name        age         birthday    salary

实现增删查改,全部使用hibernate

package com.tarena.test;

import java.util.Date;

import org.hibernate.Session;
import org.junit.Test;

import com.tarena.po.Emp;
import com.tarena.util.HibernateUtils;

public class SessionTest {
//保存emp到数据库中
	@Test
	public void testSave(){
		Session session = null;
		try {
			session = HibernateUtils.getSession();
//			开启事务
     		session.beginTransaction();//使用session直接开启事务
			Emp emp = new Emp();
			emp.setName("liu");
			emp.setAge(29);
			emp.setBirthday(new Date());
			emp.setSalary(100000.0);
			session.save(emp);
//        	session.getTransaction().commit():
//	获得开启事务Transaction对象,然后commit(提交)
//	如果保存没有提交事务的话,在控制台会发出sql
//	语句,但数据库中没有该数据,而且主键自动增1		
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
//	查询id = 1的数据
//	1  查询一个数据库中,不存在的数据
//	    会返回一个nulll
	@Test
	public void testGet1(){
		Session session = null;
		try {
			session = HibernateUtils.getSession();
//session.get(类名.class,主键的值):返回的结果是
//			Object类型的对象,需强制类型转化
			Emp emp = (Emp)session.get(Emp.class, 300);
			System.out.println(emp);
//			System.out.println(emp.getName()+" , "+emp.getSalary());
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
//	 判断 get()什么时候发出sql语句
	@Test
	public void testGet2(){
		Session session = null;
		try {
			session = HibernateUtils.getSession();
//	发出sql:当调用get方法立刻对数据库发出sql,
//			做出查询操作
			Emp emp = (Emp) session.get(Emp.class, 1);
			System.out.println("---------------------------");
			System.out.println(emp.getAge());
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
	
//	load什么时候发出的sql
    @Test
    public void testLoad2(){
    	Session session = null;
    	try {
			session= HibernateUtils.getSession();
			Emp emp =  (Emp) session.load(Emp.class, 1);
			System.out.println("--------------------------------");
//发出sql语句:因为load支持延迟加载(需要才去
//	发出sql语句,访问数据库),load返回的emp
//	是hibernate通过cglib代理返回Emp类的子类对象
//	只有当我们真实去访问该对象的属性的时候,
//	该代理对象才发出sql语句,去访问数据库					
			System.out.println(emp.getAge());
			System.out.println("-------------------------------");
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			HibernateUtils.closeSession(session);
		}
    }
    
	
	
	
//	select emp0_.id as id0_0_, emp0_.name as name0_0_, emp0_.age as age0_0_, emp0_.birthday as birthday0_0_, emp0_.salary as salary0_0_ from t_emp emp0_  where emp0_.id=?
	
//	使用load,也是用来查询对象
//	1 使用load查询一个数据库中,不存在的数据
//	   抛出ObjectNotFoundException:对象没有找到
	@Test
	public void testLoad1(){
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			Emp  emp =  (Emp) session.load(Emp.class, 100);
			System.out.println(emp.getAge()+" , "+emp.getName());
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
//	删除
	@Test
	public void testDelete1(){
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Emp emp =(Emp) session.load(Emp.class, 3);
			session.delete(emp);
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
//	生成对象,然后把该对象id属性设为要删除数据库
//	数据主键
	@Test
	public void testDelete2(){
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Emp emp = new Emp();
			emp.setId(1);
			session.delete(emp);
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
//	修改,最好使用load/get,把要修改的数据,从数据库
//	先查询出来,然后再调用update(obj)
//	可以修改需要修改的信息,而且可以保存原有信息
	@Test
	public void testUpdate1(){
		Session session  = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
//	最好使用先load/get,然后再update		
			Emp emp = (Emp) session.load(Emp.class, 1);
//			Emp emp  = new Emp();
//	尽量不要使用,因为凡是没有修改信息,全部设为
//	0或null		
//	        emp.setId(1);
			emp.setName("gaoyuanyuan");
			emp.setAge(35);
			session.update(emp);
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally{
			HibernateUtils.closeSession(session);
		}
	}
	
	
	
	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值