Java实战之02Hibernate-01简介、常用接口、CRUD操作
一、Hibernate简介
1、Hibernate在开发中所处的位置
2、ORM映射
Object :面向对象领域的
Relational:关系数据库领域的
Mapping:映射
Object: Relational
public class Person{ create table presons(
private String name; name varchar(100),
private int age; age int
// getter and setter
} );
new Person("test",25); sert into presons(name,age)values("test",25);
Hibernate:就是让程序员通过操作对象的方式来操作数据库中的表。
二、搭建开发环境
1、下载Hibernate的资源包
前往官网下载:http://hibernate.org/
2、准备Hibernate运行的必备jar包
前提准备:数据库的驱动jar包
hibernate的必须jar包
3、建立hibernate配置文件,配置数据源信息
在classpath下,建立一个默认名称为hibernate.cfg.xml配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- 搭建hibernate的开发环境: 3 前期准备: 4 导入必要的jar包。 5 1、在类的根路径下,创建一个hibernate.cfg.xml的配置文件。该配置文件是Hibernate的主配置文件。 6 2、导入dtd约束 7 约束的位置:hibernate的核心jar包中 hibernate-configuration-3.0.dtd 8 --> 9 <!DOCTYPE hibernate-configuration PUBLIC 10 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 11 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 12 <hibernate-configuration> 13 <!-- 配置session工厂创建时所必须的条件。 14 分为3部分 15 数据库连接的基本信息 16 hibernate配置的基本信息 17 映射信息 18 session-factory:session的工厂,作用就是生产session对象的。 19 session:它就相当于我们jdbc中的connection,作用就是对数据库进行增删改查操作。 20 --> 21 <session-factory> 22 <!-- 1、数据库连接的基本信息 --> 23 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 24 <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/ee0413_hibernate_day31</property> 25 <property name="hibernate.connection.username">root</property> 26 <property name="hibernate.connection.password">1234</property> 27 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><!-- 配置数据库方言 --> 28 <!-- 2、hibernate的基本配置--> 29 <property name="hibernate.show_sql">true</property><!-- 显示SQL语句 --> 30 <property name="hibernate.format_sql">true</property><!-- 格式化SQL语句 --> 31 <!-- 采用何种方式生产DDL语句 32 #hibernate.hbm2ddl.auto create-drop 创建表结构,每次执行完都删除。 33 #hibernate.hbm2ddl.auto create 创建表结构,每次执行都重新创建 34 #hibernate.hbm2ddl.auto update 创建表结构在第一此执行,之后的每次执行都检查表结构是否有变化,有变化就更新(学习阶段使用此值) 35 #hibernate.hbm2ddl.auto validate 验证表结构是否有变化,有变化就改变 36 隐藏选项:none 什么都不做。 37 DDL是数据定义语言:在hibernate中,它不能创建库。必须由我们自己先创建数据库。 38 --> 39 <property name="hibernate.hbm2ddl.auto">update</property> 40 <!-- 3、指定映射文件 --> 41 <mapping resource="cn/itcast/domain/Student.hbm.xml"/> 42 </session-factory> 43 </hibernate-configuration>
三、Hibernate中的常用接口和类
1、Configuration
作用:加载Hibernate的配置文件
1.1、另外一种配置方式:
在classpath中建立一个hibernate.properties的配置文件。(不推荐使用)
1.2、自由指定映射文件:
1.3、自由指定加载的实体类:
2、SessionFactory(重点)
由Configuration通过加载配置文件创建该对象。
SessionFactory 对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。同时,SessionFactory还负责维护Hibernate的二级缓存
预定义SQL语句:(注意如果有多个映射文件,每个映射文件都会有这4条预定义SQL语句)
select * from students where id=? //根据主键查询
insert into students (name,age,birthday) values(?,?,?); //全字段插入
update students set name=?,age=?,birthday=? where id=? //根据主键全字段更新
delete from students where id=? //根据主键删除
一个SessionFactory实例对应一个数据库,应用从该对象中获得Session实例。
SessionFactory是线程安全的,意味着它的一个实例可以被应用的多个线程共享。
SessionFactory是重量级的,意味着不能随意创建或销毁它的实例。如果只访问一个数据库,只需要创建一个SessionFactory实例,且在应用初始化的时候完成。
SessionFactory需要一个较大的缓存,用来存放预定义的SQL语句及实体的映射信息。
另外可以配置一个缓存插件,这个插件被称之为Hibernate的二级缓存(后续会详解二级缓存),被多线程所共享
结论:一般应用使用一个SessionFactory,最好是应用启动时就完成初始化。
3、Session 非常重要。使用率非常高
不是线程安全的。应避免多个线程使用同一个Session实例。
Session是轻量级的,它的创建和销毁不会消耗太多的资源。应为每次客户请求分配独立的Session实例
Session有一个缓存,被称之为Hibernate的一级缓存。每个Session实例都有自己的缓存。
4、Transaction:事务管理
Hibernate应用通过它声明事务边界,有助于在不同的环境或容器中进行移植。
开启事务:Transaction tx = session.beginTransaction();//开启事务
tx.commit()事务提交 tx.rollback()事务回滚
1 /* 2 * hibernate的步骤分析 3 * 1、加载配置文件(hibernate的主配置文件) 4 * 2、根据配置文件,构建session工厂 5 * 3、 使用Session工厂生产一个Session对象 6 * 4、开启事务 7 * 5、执行操作(现在就先保存一个学生到数据库) 8 * 6、提交事务 9 * 7、释放资源 10 */ 11 @Test 12 public void test1(){ 13 Student student = new Student(); 14 student.setName("泰斯特2"); 15 student.setGender("male"); 16 student.setBirthday(new Date()); 17 18 //1 19 Configuration cfg = new Configuration(); 20 cfg.configure(); 21 //手动指定实体 22 //cfg.addClass(Student.class); 23 //cfg.addResource("cn/itcast/domain/Student.hbm.xml"); 24 //2 25 SessionFactory factory = cfg.buildSessionFactory(); 26 //3。此Session和HttpSession没有任何关系 27 Session session = factory.openSession();//打开一个新的Session 28 //4 29 Transaction tx = session.beginTransaction(); 30 //5 31 session.save(student); 32 //6 33 tx.commit(); 34 //7 35 session.close(); 36 factory.close(); 37 } 38 39 /** 40 * Configuration: 41 * 作用:就是用于加载配置文件。它默认只会加载类的根路径下的配置文件。 42 * 常用方法: 43 * 默认构造函数:它默认只会加载类的根路径下的hibernate.properties配置文件。不会加载xml文件。 44 * configure:该方法会加载类的根路径下的hibernate.cfg.xml配置文件。 45 * addClass:手动指定实体类的字节码。目的也是指定映射文件。要求,映射文件的命名必须符合规范。实体类名称.hbm.xml 46 * addResource:手动指定映射文件的位置。 47 * 总结: 48 * 建议使用配置文件来指定映射文件的位置。 49 * 50 * SessionFactory: 51 * 作用:就是用于生产Session对象的。工厂的创建,是由Configuration对象来创建的。 52 * 常用的方法: 53 * openSession():每次打开一个新的Session对象。 54 * 说明: 55 * 1、该对象维护着应用中所有的映射文件信息。 56 * 2、它还维护类一些预定义的SQL语句。(只包含每个实体都通用的:全字段插入,全字段更新,根据ID查询,查询所有) 57 * 3、维护着连接数据库的信息,hibernate的基本配置 58 * 4、还维护着hibernate的二级缓存(关于二级缓存的内容,第四天再讲) 59 * 5、所有由该工厂生产的Session,共享工厂中的数据。结论:SessionFactory是线程安全的。 60 * SessionFactory的使用原则: 61 * SessionFactorty是一个重量级对象,里面维护了很多信息。不应该随意的创建和销毁。一个应用最好只有一个SessionFactory。 62 * 在web工程中,应该是随着应用的加载,而创建。随着应用的卸载而销毁。 63 * 64 * Session: 65 * 作用:对数据库进行增删改查的操作。开启事务等等。它是我们使用频率最高的一个对象。 66 * 常用方法: 67 * a lot of 68 * save:保存一个实体到数据库中 69 * 说明: 70 * 1、Session是一个轻量级的对象。绝大多数信息都是由SessionFactory维护的。 71 * 2、它的创建和销毁不会消耗太多资源。 72 * 3、Session对象不是线程安全的。***** 73 * 4、Session维护着hibernate的一级缓存。 74 * Session的使用原则: 75 * 保证一个线程只有一个Session。 76 * Transaction: 77 * 作用:针对事务的控制。 78 * 常用方法: 79 * commit();提交事务 80 * rollback();回滚事务 81 * 82 */ 83 84 /* 85 * 升级hibernate的基本操作 86 */ 87 @Test 88 public void test2(){ 89 Student student = new Student(); 90 student.setName("泰斯特3"); 91 student.setGender("male"); 92 student.setBirthday(new Date()); 93 94 //1、使用HibernateUtil获取一个Session 95 Session session = HibernateUtil.getSession(); 96 //2 97 Transaction tx = session.beginTransaction(); 98 //3 99 session.save(student); 100 //4 101 tx.commit(); 102 //5 103 session.close(); 104 }
5、释放资源
(隐藏问题:hibernate把所有异常都变成了运行时异常)
抽取工具类:
1 public class HibernateUtil { 2 3 private static SessionFactory factory; 4 5 /* 6 * 给factory赋值 7 * 8 * 异常是有的,只不过hibernate把异常全都转成了运行时异常 9 */ 10 static{//静态代码块:在类加载的时候就已经执行了 11 try { 12 Configuration cfg = new Configuration(); 13 cfg.configure(); 14 factory = cfg.buildSessionFactory(); 15 } catch (Exception e) { 16 e.printStackTrace(); 17 throw new ExceptionInInitializerError("创建SessionFactory失败!"); 18 } 19 } 20 21 //提供一个获取Session的方法 22 public static Session getSession(){ 23 return factory.openSession(); 24 } 25 }
6、Hibernate模板
1 public void test(){ 2 Student student = new Student(); 3 student.setName("泰斯特"); 4 student.setGender("male"); 5 student.setBirthday(new Date()); 6 7 Session session = null; 8 Transaction tx = null; 9 try{ 10 //1、使用HibernateUtil获取一个Session 11 session = HibernateUtil.getSession(); 12 //2 13 tx = session.beginTransaction(); 14 //3 15 session.save(student); 16 //4 17 tx.commit(); 18 }catch(Exception e){ 19 tx.rollback(); 20 throw new RuntimeException(e); 21 }finally{ 22 //5 23 session.close(); 24 } 25 }
四、CRUD操作
1 public class HibernateDemo { 2 3 //查询所有学生信息 4 @Test 5 public void testFindAll(){ 6 Session session = HibernateUtil.getSession(); 7 Transaction tx = session.beginTransaction(); 8 //1.需要使用Session获取到一个查询对象 9 /* 10 * createQuery中的参数是一个字符串。 11 * 它是Hibernate的查询语句。HQL。不是SQL语句。 12 * HQL : hibernate query language 13 * 写法都是和类名以及类中的属性名称(set/get方法) 14 */ 15 Query query = session.createQuery("from Student "); 16 List<Student> list = query.list(); 17 tx.commit(); 18 session.close(); 19 System.out.println(list); 20 } 21 22 //删除学生信息 23 @Test 24 public void testDelete(){ 25 Session session = HibernateUtil.getSession(); 26 Transaction tx = session.beginTransaction(); 27 Student s = session.get(Student.class, 1); 28 session.delete(s); 29 tx.commit(); 30 session.close(); 31 } 32 33 34 //更新学生信息 35 @Test 36 public void testUpdate(){ 37 Session session = HibernateUtil.getSession(); 38 Transaction tx = session.beginTransaction(); 39 Student s = session.get(Student.class, 1); 40 s.setGender("female"); 41 session.update(s); 42 tx.commit(); 43 session.close(); 44 45 } 46 47 //根据id查询一个学生信息 48 @Test 49 public void testFindOne(){ 50 Session session = HibernateUtil.getSession(); 51 Transaction tx = session.beginTransaction(); 52 /* 53 * get方法:根据id查询一个实体对象。 54 * 参数1:实体对象的字节码 55 * 参数2:查询条件的id 56 */ 57 Student s = session.get(Student.class, 1); 58 System.out.println(s); 59 tx.commit(); 60 session.close(); 61 } 62 63 //添加 64 @Test 65 public void testAdd(){ 66 Student student = new Student(); 67 student.setName("泰斯特"); 68 student.setGender("male"); 69 student.setBirthday(new Date()); 70 71 Session session = HibernateUtil.getSession(); 72 Transaction tx = session.beginTransaction(); 73 session.save(student); 74 tx.commit(); 75 session.close(); 76 } 77 78 }