关闭

Hibernate基础知识(2)

标签: Hibernate
336人阅读 评论(0) 收藏 举报
分类:

Hibernate 核心配置和核心API

1、 hibernate体系结构

      Hibernate位于应用程序和数据库之间,将数据库底层完全封装,应用程序只需要操作持久化对象(Persistent Object),通过Hibernate生成SQL语句,完成对数据表中记录的操作。

hibernate 支持两种核心配置文件:

      src/hibernate.properties(key-value文件键值对,主要配置Hibernate基本属性)

            hibernate.connection.driver_class=com.mysql.jdbc.Driver

      src/hibernate.cfg.xml (完成基本属性配置,加载hbm映射文件)
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <mapping resource="lsq/hibernate/domain/Customer.hbm.xml"/> 加载hbm映射

      * hibernate.properties 无法加载 hbm映射 , 采用properties方式,必须手动编程加载 hbm文件或者 持久化类

2、 hibernate的常用属性

      必须属性
      hibernate.dialect   操作数据库方言
      hibernate.connection.driver_class  连接数据库驱动程序
      hibernate.connection.url   连接数据库URL
      hibernate.connection.username  数据库用户名
      hibernate.connection.password   数据库密码

      可选属性 
      hibernate.show_sql  true 在控制台上输出SQL语句
      * hibernate 自己完成的,并没有使用日志系统 ,当关闭日志后,控制台仍然有SQL语句 
      hibernate.format_sql  true  格式化控制台输出的SQL语句
      * SQL 会自动换行,对于比较长的sql 查看方便


      hibernate.hbm2ddl.auto  create/create-drop/update/validate  DDL策略
      * DDL 主要建表语句,和表结构更新语句 
      create:表示启动的时候先drop,再create (测试人员 准备标准测试数据)
      create-drop: 也表示创建,只不过再系统关闭前执行一下drop  (测试程序是否正确)
      update: 这个操作启动的时候会去检查schema是否一致,如果不一致会做scheme更新 (建表,更新表结构【只能加】)
      validate: 启动时验证现有schema与你配置的hibernate是否一致,如果不一致就抛出异常,并不做更新 

      *** 在产品开发中 update 和 validate 使用较多

      hibernate.connection.autocommit  true 事务是否自动提交
      * 用于解决 没有开启事务的操作时,事务如何自动处理 
      * 默认事务 自动回滚

3、 Hibernate 核心 API 详解

1) Configuration : 加载hibernate 配置
      加载 hibernate.properties 和 hibernate.cfg.xml
      持久化类与数据表的映射关系(*.hbm.xml 文件)


      加载核心属性配置:

      方式一:Configuration cfg = new Configuration();   去src 读取 hibernate.properties 属性配置文件

      方式二:Configuration cfg = new Configuration().configure();  去src读取 hibernate.cfg.xml,

                      Configuration cfg = new Configuration().configure("自定义文件.xml"); 去src 加载指定文件

      手动加载hbm映射配置:

      如果没有对PO类进行hbm映射,运行时会报错:org.hibernate.MappingException: Unknown entity: lsq.hibernate.domain.Customer

      需要手动加载hbm文件:

      configuration.addResource("lsq/hibernate/domain/Customer.hbm.xml"); 加载hbm文件

      或者

      configuration.addClass(Customer.class); 加载Class,自动搜索hbm映射文件 

      ** 如果使用 hibernate.cfg.xml配置,将映射配置xml中 <mapping resource="lsq/hibernate/domain/Customer.hbm.xml"/>


2)SessionFactory

      Hibernate操作数据库,它的核心对象是Session,但是要想得到Session,需要先构造SessionFactory。

      SessionFactory保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。

      预定义SQL:

      在配置文件中定义SQL,给SQL命名,在程序中通过预定义SQL名称(login)使用SQL

      <sql-query name="login">
            <![CDATA[select * from user where username= ? and password =?]]>
      </sql-query>

      SessionFactory对象是线程安全的。

      SessionFactory负责维护Hibernate的二级缓存。


      主要API:

      Session   openSession():随机从内部维护连接池中获取一个连接,构造Session对象。

      Session   getCurrentSession():获得一个与线程绑定Session的对象。(ThreadLocal)


      SessionFactory内部维护数据库连接池很浪费资源,通常一个应用程序只有一个SessionFactory对象。

      *抽象一个HibernateUtils工具类,确保只有一个SessionFactory(Static)

      SessionFactory默认使用连接池时内置连接池,由DriverManagerConnectionProvider 类提供

      * DriverManagerConnectionProvider 内部使用 DriverManager.getConnection 获得连接

      

package lsq.hibernate.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hibernate操作工具类,只创建一个SessionFactory
 * @author Daniel Li
 *
 */
public class HibernateUtils {
	private static Configuration configuration;
	private static SessionFactory sessionFactory;
	
	static{
		//只对SessionFactory初始化一次
		configuration = new Configuration().configure();
		sessionFactory = configuration.buildSessionFactory();
	}
	
	/**
	 * 获得Hibernate操作会话对象
	 * @return
	 */
	public static Session openSession(){
		return sessionFactory.openSession();
	}
	
}

      配置c3p0连接池:

      第一步 导入 c3p0-0.9.1.jar
      第二步 在hibernate.cfg.xml 修改连接提供者
      <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
      第三步 (选作) 配置c3p0连接池属性 
      <property name="c3p0.min_size">5</property>
      <property name="c3p0.max_size">20</property>
      <property name="c3p0.timeout">120</property>
      <property name="c3p0.idle_test_period">3000</property>

      

3)Session

      代表hibernate操作会话对象,相当于 Connection。

      Session是应用程序与数据库之间交互操作的一个单线程对象,是Hibernate运作的中心。线程不安全(在方法内部定义和使用Session,不会出现线程问题)

      Session进行PO对象的常见持久化操作,存在一级缓存。

      常用方法:

      save():插入;

      update():完成修改;

      delete():完成删除;

      get/load():根据主键字段查询;

      createQuery、createSQLQuery:创建查询对象,Query接收HQL,SQLQuery接收SQL;

      createCriteria():面向对象条件查询


4)Transaction

      commit():提交相关联的session实例。

      rollback():撤销事务操作。

      wasCommitted():检查事务是否提交。

      如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务。

      *设置事务是否提交

      <property name="hibernate.connection.autocommit">false</property> 事务不提交
      <property name="hibernate.connection.autocommit">true</property> 事务提交 
      默认false


5)Query

      Query代表面向对象的一个Hibernate查询操作。session.createQuery() 获得,接收参数 HQL语句

      步骤:

      获得Hibernate Session对象
      编写HQL语句
      调用session.createQuery 创建查询对象
      如果HQL语句包含参数,则调用Query的setXXX设置参数
      调用Query对象的list() 或uniqueResult() 方法执行查询


      Query还包含两个方法用于控制返回结果。

      setFirstResult(int   firstResult):设置返回结果从第几条开始。

      setMaxResults(int   maxResults):设置返回结果记录条数。

      

      案例一:查询所有数据 from Customer;

      案例二:分页查询

      案例三:通过select关键字,查询指定属性对应列

              select name,age from Customer; 返回每条数据 保存 Object[] ----- List<Object[]>(返回的每条数据会保存到对象数组中,最后返回List)

              如果想将查询结果,保存Customer对象中--->使用构造方法 !!!!!(在Customer类中,定义name和age属性构造器)

              select new Customer(name,age) from Customer

      案例四:通过where语句添加查询条件

              无名字参数 from Customer where name= ? ;  设置参数 query.setParameter(0,"Curry"); 

              有名字参数 from Customer where name= :myname;  设置参数 query.setParameter("myname","Curry");

package lsq.hibernate.test;

import java.util.List;

import lsq.hibernate.domain.Customer;
import lsq.hibernate.utils.HibernateUtils;

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

/**
 * Hibernate的查询操作Query、Criteria
 * @author Daniel Li
 *
 */
public class HibernateTest2 {
	//使用Query对象的查询
	@Test
	public void testQuery(){
		//获得session
		Session session = HibernateUtils.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		
		//1、查询所有数据
		String hql = "from Customer";
		Query query = session.createQuery(hql);
		List<Customer> list = query.list();
		System.out.println(list);
		
		transaction.commit();
		session.close();
	}
	
	//批量插入100条数据
	@Test
	public void testBatchInsert(){
		Session session = HibernateUtils.openSession();
		Transaction transaction = session.beginTransaction();
		
		for (int i = 0; i < 100; i++) {
			Customer customer = new Customer();
			customer.setName("name"+i);
			customer.setAge(i);
			customer.setCity("北京");
			session.save(customer);
		}
		
		transaction.commit();
		session.close();
	}
	
	//使用Query对象实现分页查询
	@Test
	public void testQueryPage(){
		//获得session
		Session session = HibernateUtils.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		
		String hql = "from Customer";
		Query query = session.createQuery(hql);
		query.setFirstResult(20);//索引20代表第21条数据
		query.setMaxResults(10);
		List<Customer> list = query.list();
		System.out.println(list);
		
		transaction.commit();
		session.close();
	}	

	//使用Query对象查询指定属性对应列
	@Test
	public void testQuerySpecifiedColumn(){
		//获得session
		Session session = HibernateUtils.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		
		//这里name和age是
//		String hql = "select name,age from Customer";
		String hql = "select new Customer(name,age) from Customer";
		Query query = session.createQuery(hql);
		List<Customer> list = query.list();
		System.out.println(list);
		
		transaction.commit();
		session.close();
	}
	
	//使用Query对象查询带有条件的查询(匿名参数)
	@Test
	public void testQueryCondition1(){
		//获得session
		Session session = HibernateUtils.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		
		//匿名参数
		String hql = "from Customer where name = ? and age = ?";
		Query query = session.createQuery(hql);
		
		//设置参数
		query.setParameter(0, "Curry");
		query.setParameter(1, 28);
		
		List<Customer> list = query.list();
		System.out.println(list);
		
		transaction.commit();
		session.close();
	}

	//使用Query对象查询带有条件的查询(有名称的参数)
	@Test
	public void testQueryCondition2(){
		//获得session
		Session session = HibernateUtils.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		
		//匿名参数
		String hql = "from Customer where name = :cname and age = :cage";
		Query query = session.createQuery(hql);
		
		//设置参数
		query.setParameter("cname", "Curry");
		query.setParameter("cage", 28);
		
		List<Customer> list = query.list();
		System.out.println(list);
		
		transaction.commit();
		session.close();
	}
	
}

6)Criteria接口

      主要为了解决多条件查询问题,以面向对象的方式添加条件,无需拼接HQL语句 

      获得对象
      Criteria criteria = session.createCriteria(Customer.class);

      步骤 
      获得Hibernate的Session对象
      通过Session获得Criteria对象
      使用Restrictions的静态方法创建Criterion条件对象
      向Criteria对象中添加Criterion 查询条件
      执行Criterita的 list() 或uniqueResult() 获得结果

      * Criteria查询 可以实现 和Query 一样效果

      案例一 查询所有 
            Criteria criteria = session.createCriteria(Customer.class);
      案例二 分页 
            criteria.setFirstResult(1);
            criteria.setMaxResults(2);
      案例三 条件查询
            criteria.add(Restrictions.eq("name", "Curry"));
            criteria.add(Restrictions.lt("age", 30));
            criteria.add(Restrictions.like("name", "C%"));

      ** 当多条件组合查询时,criteria 更加方便

package lsq.hibernate.test;

import java.util.List;

import lsq.hibernate.domain.Customer;
import lsq.hibernate.utils.HibernateUtils;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

/**
 * 使用Criteria查询
 * @author Daniel Li
 *
 */
public class HibernateTest3 {
	@Test
	public void testCriteria(){
		//获得session
		Session session = HibernateUtils.openSession();
		//开启事务
		Transaction transaction = session.beginTransaction();
		
		//1、查詢所有数据
//		Criteria criteria = session.createCriteria(Customer.class);
//		List<Customer> list = criteria.list();
//		System.out.println(list);
		
		//2、分页查询
//		Criteria criteria = session.createCriteria(Customer.class);
//		criteria.setFirstResult(1);
//		criteria.setMaxResults(2);
//		List<Customer> list = criteria.list();
//		System.out.println(list);
		
		//3、带有查询条件的查询
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.add(Restrictions.eq("name", "Curry"));
		criteria.add(Restrictions.lt("age", 30));
		List<Customer> list = criteria.list();
		System.out.println(list);
		
		transaction.commit();
		session.close();
	}
}



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:35087次
    • 积分:896
    • 等级:
    • 排名:千里之外
    • 原创:50篇
    • 转载:31篇
    • 译文:0篇
    • 评论:2条
    最新评论