##概述
在JPA和ORM介绍中说到,Hibernate框架属于JPA框架中的一种,是基于ORM思想实现的持久化框架。
Hibernate是一个开源的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将Java Model类与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
##准备工作
在使用JDBC连接数据库之前,首先要有数据库,数据库要创建表。我的数据库信息如下:
- 数据库类型:MySql。
- 数据库名字:xia。
- 用户名:root。
- 密码:root.
- 创建数据库表student。
create table student( id int primary key auto_increment, name varchar(20), age int );
##开发环境
- 操作系统:MACOS。
- 开发工具:IntelliJ IDEA。
- Java版本:jdk1.8。
- 使用maven管理jar包。
##正式开发
一,在pom.xml文件中引入需要jar的依赖
<!--mysql驱动,连接mysql的操作都需要mysql驱动包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency> <!-- hibernate-core包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.16.Final</version> </dependency>
二,创建对象与表结构映射关系文件
映射关系文件放在resource目录下。Student.java类与student表的映射关系文件命名为:student.hbm.xml。文件内容如下:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- class用来描述一个类 name 类的全名 table 该持久化类对应的表名 可以不写,默认值为类名 --> <class name="com.honor.sql.Student" table="student"> <!-- Student类字段与表结构字段对应关系 name 属性的名称 column 属性的名称对应的表的字段 可以不写 默认值就是属性的名称 length 属性的名称对应的表的字段的长度 如果不写,默认是最大的长度 --> <id name="id" column="id" length="5"> <!-- 主键的产生器 --> <generator class="increment"></generator> </id> <property name="name" column="name" length="20" ></property> <property name="age" column="age" length="50" ></property> </class> </hibernate-mapping>
注:
- 映射关系表通常以“表名.hbm.xml”的格式命名。也可以自定义,只要在hibernate的配置文件中指定即可。
- 在映射关系表中指定了Model类与表名的对应关系,及Model类字段与表结构字段的对应关系。
- 通常一个表对应一个Model类,需要写一个映射关系文件。
三,创建hibernate框架的全局配置文件
全局配置文件也放在resource目录下,命名为:hibernate.cfg.xml。文件内容如下:
<?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> <!-- 一个sessionFactory代表数据库的一个连接--> <session-factory> <!-- 链接数据库的用户名 --> <property name="connection.username">root</property> <!-- 链接数据库的密码 --> <property name="connection.password">root</property> <!-- 链接数据库的驱动 --> <property name="connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 链接数据库的url --> <property name="connection.url"> jdbc:mysql://localhost:3306/xia </property> <!--方言,告诉hibernate使用什么样的数据库,hibernate就会在底层拼接什么样的sql语句--> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- 配置根据持久化类生成表的策略 validate 通过映射文件检查持久化类与表的匹配 update 每次hibernate启动的时候,检查表是否存在,如果不存在,则创建,如果存在,则什么都不做了 create 每一次hibernate启动的时候,根据持久化类和映射文件生成表 create-drop --> <property name="hbm2ddl.auto">update</property> <property name="show_sql">true</property> <!--加载model类与表结构映射关系文件--> <mapping resource="student.hbm.xml" /> </session-factory> </hibernate-configuration>
注:该文件的主要作用有两个:
- 配置数据库参数,账号、密码、数据库驱动等信息。
- 配置model类与表结构映射关系文件
注:hibernate框架具有创建表结构的功能,在hbm2ddl.auto属性中指定update即可。但在项目中我一般都是手动创建表结构。
四,得到Session对象
/** * 根据配置文件获取Session对象 * * @return */ public static Session getSession() { //加载hibernate全局配置文件 Configuration cfg = new Configuration().configure("/hibernate.cfg.xml"); SessionFactory factory = cfg.buildSessionFactory(); //得到Session对象,所有的数据库操作都是通过Session对象来完成 Session session = factory.openSession(); return session; }
五,插入操作
public static boolean insertStudent(Student student) { //获取Session对象 Session session = getSession(); try { //开始事务 session.beginTransaction(); //插入数据,此时在student.hbm.xml文件中指定Student类对应student表,所以会将student对象数据插入到student表中 session.save(student); //提交事务 session.getTransaction().commit(); return true; } catch (Exception e) { e.printStackTrace(); //出现异常时回滚事务 session.getTransaction().rollback(); } finally { if (session != null) { if (session.isOpen()) { session.close();//关闭session } } } return false; }
六,根据id查找单个对象
public static Student selectStudent(int id) { //获取Session对象 Session session = getSession(); try { session.beginTransaction(); //根据id查询Student对象 Student student = session.load(Student.class, id); session.getTransaction().commit(); return student; } catch (Exception e) { e.printStackTrace(); //出现异常时回滚事务 session.getTransaction().rollback(); } finally { if (session != null) { if (session.isOpen()) { session.close();//关闭session } } } return null; }
七,根据其他条件得到对象集合
public static List<Student> selectStudentList(int age) { //获取Session对象 Session session = getSession(); try { session.beginTransaction(); //定义hql语句,类似于sql语句,注意:此时Student是对象,并不是表名。在student.hbm.xml文件中指定Student类对应student表 String hql = " from Student where age = " + age; Query query = session.createQuery(hql); List<Student> studentList = query.list(); session.getTransaction().commit(); return studentList; } catch (Exception e) { e.printStackTrace(); //出现异常时回滚事务 session.getTransaction().rollback(); } finally { if (session != null) { if (session.isOpen()) { session.close();//关闭session } } } return null; }
八,更新操作
public static boolean updateStudent(Student student) { //获取Session对象 Session session = getSession(); try { session.beginTransaction(); //根据ID更新数据 Student studentResult = session.load(Student.class, student.getId()); //更新Name studentResult.setName(student.getName()); //执行更新操作 session.update(studentResult); session.getTransaction().commit(); return true; } catch (Exception e) { e.printStackTrace(); //出现异常时回滚事务 session.getTransaction().rollback(); } finally { if (session != null) { if (session.isOpen()) { session.close();//关闭session } } } return false; }
九,删除操作
public static boolean deleteStudent(int id) { //获取Session对象 Session session = getSession(); try { session.beginTransaction(); //根据ID得到Student对象 Student student = session.load(Student.class, id); //删除操作 session.delete(student); session.getTransaction().commit(); return true; } catch (Exception e) { e.printStackTrace(); //出现异常时回滚事务 session.getTransaction().rollback(); } finally { if (session != null) { if (session.isOpen()) { session.close();//关闭session } } } return false; }
##在Hibernate框架中使用sql语句操作数据库
在Hibernate框架中完全不用写sql语句就可以进行数据库的增删改查,但也可以使用sql语句。下面以查询操作为例说明怎么在Hibernate框架中使用sql语句。
public static List<Student> selectStudentListBySql(int age) { //获取Session对象 Session session = getSession(); try { session.beginTransaction(); //写sql语句,由于在student.hbm.xml文件中指定Student类对应student表,所以会把结果封装到Student对象中 String sql = "select id,name,age from student where age = " + age; Query query = session.createSQLQuery(sql); List<Student> studentList = query.list(); session.getTransaction().commit(); return studentList; } catch (Exception e) { e.printStackTrace(); //出现异常时回滚事务 session.getTransaction().rollback(); } finally { if (session != null) { if (session.isOpen()) { session.close();//关闭session } } } return null; }
注:
- sql语句与hql不同,sql中使用的是表名student,hql中使用的是类名Student。
- 执行sql使用的是Session类的createSQLQuery方法,执行hql使用的是Session类的createQuery方法。
##总结
Hibernate的优点:
- 对JDBC进行了封装,使用了数据库连接池,更便于使用。
- 隐藏sql,将对数据库的操作转化为对对象的操作,实现面向对象编程。
- hibernate提供了缓存机制,一级缓存,二级缓存,查询缓存。
Hibernate的缺点:
- 封装了sql与对象的映射,通过操作对象实现操作sql,故比直接操作sql效率低。
- 框架封装了sql,直接操作对象,导致对sql操作对自由度降低,尤其对多表查询操作受限。
- 表中的数据如果在千万级别,则hibernate不适合。
- 如果表与表之间的关系特别复杂,则hibernate也不适合。
Hibernate的使用场景:
由于Hibernate不适合大量数据,所以一般用在企业内部的系统,比如公司内网。不适用于对外公共的网络,比如淘宝,京东这样的公司。