Java
Java Web框架

Hibernate(1)

简介:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

1. Hibernate入门

Hibernate是一个数据持久化层的ORM(Object Relational Mapping)框架。

  • Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架;
  • ORM就是通过将Java对象映射到数据库表,通过操作Java对象,就可以完成对数据表的操作;
  • Hibernate提供了对关系型数据库增删改成操作。

主流的ORM框架有以下几个:

  • JPA( Java Persistence API)。JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系(只有接口规范)
  • Hibernate。 最流行ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL
  • MyBatis。本是apache的一个开源项目 iBatis,支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。
  • Apache DBUtils 、Spring JDBCTemplate。

Hibernate的优点如下:

  • Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
  • Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了dao层编码工作session.save(User);
  • Hibernate使用Java的反射机制。
  • Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系。

2. 入门案例

我们按下面的流程来编写一个简单的入门案例:

  1. 创建数据库和表;
  2. 导入jar包;
  3. 编写核心配置文件(hibernate.cfg.xml),配置获得链接等参数;
  4. 编写映射文件hibernate mapping(*.hbm.xml)
  5. 使用API测试。

2.1. 数据库和表

  • create database h_day01_db;
  • use h_day01_db;
  • create table t_user(
  • id int auto_increment primary key,
  • username varchar(50),
  • password varchar(30)
  • );

2.2. 导入jar包

使用Hibernate一共要导入以下的9个Jar包:

  • antlr-2.7.6.jar:解析框架,用于Hibernate解析HQL。
  • commons-collections-3.1.jar:集合类增强。
  • dom4j-1.6.1.jar:解析XML文件。
  • hibernate-jpa-2.0-api-1.0.1.Final.jar:JPA规范支持。
  • hibernate3.jar:Hibernate核心。
  • javassist-3.12.0.GA.jar:字节码增强。
  • jta-1.1.jar:Java Transaction API事务规范支持。
  • mysql-connector-java-5.0.8-bin.jar:数据库驱动。
  • slf4j-api-1.6.1.jar:日志框架,整合log4j。

2.3. 编写JavaBean和映射文件

  • 文件位置:与Javabean同包
  • 文件名称:与Javabean同名
  • 扩展名:*.hbm.xml
  • 内容:
    添加约束

先编写JavaBean类文件User.java,代码如下:

  • package com.coderap.hello;
  • public class User {
  • private String id;
  • private String name;
  • private String password;
  • public String getId() {
  • return id;
  • }
  • public void setId(String id) {
  • this.id = id;
  • }
  • public String getName() {
  • return name;
  • }
  • public void setName(String name) {
  • this.name = name;
  • }
  • public String getPassword() {
  • return password;
  • }
  • public void setPassword(String password) {
  • this.password = password;
  • }
  • @Override
  • public String toString() {
  • return "User [id=" + id + ", name=" + name + ", password=" + password
  • + "]";
  • }
  • }

相应的映射配置文件:

  • <?xml version="1.0" encoding="UTF-8"?>
  • <!DOCTYPE hibernate-mapping PUBLIC
  • "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  • "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  • <!-- ORM元数据 表对象关系映射文件
  • package : 配置该配置文件中类所在的包. -->
  • <hibernate-mapping package="com.coderap.hello" >
  • <!-- class: 配置实体与表的关系
  • name : 填写实体的完整类名
  • table: 与实体对应表的名称
  • dynamic-insert:动态插入 默认值是false
  • true=>如果字段值为null,不参与insert语句
  • dynamic-update:动态更新 默认值"false"
  • true=> 没改动过的属性,将不会生成到update语句中
  • -->
  • <class name="User" table="t_user" >
  • <!-- id: 配置实体与表中 id对应
  • name: user对象中标识主键的属性名称
  • column: 主键在表中的列名
  • length: 列的数据长度
  • unsaved-value(不常用): 指定主键为什么值时,当做null来处理.
  • access(强烈推荐不要用):field 那么在操作属性时,会直接操作对应的字段而不是get/set方法
  • -->
  • <id name="id" column="id" length="255" >
  • <!-- generator:主键生成策略
  • 1.increment 数据库自己生成主键. 先从数据库中查询最大的ID值,将ID值加1作为新的主键
  • 2.identity 依赖于数据的主键自增功能
  • 3.sequence 序列,依赖于数据中的序列功能(Oracle).
  • 4.hilo(纯了解,永远用不到) : Hibernate自己实现序列的算法,自己生成主键. (hilo算法 )
  • 5.native 自动根据数据库判断,三选一. identity|sequence|hilo
  • 6.uuid 生成32位的不重复随机字符串当做主键
  • 7.assigned 自己指定主键值. 表的主键是自然主键时使用.
  • -->
  • <generator class="uuid"></generator>
  • </id>
  • <!-- property : 实体中属性与表中列的对应
  • name : 实体中属性名称
  • column : 表中列的名称
  • length : 数据长度
  • precision: 小数点后的精度
  • scale: 有效位数
  • insert(一般不用): 该属性是否加入insert语句.
  • update(一般不用): 该属性是否加入update语句.
  • not-null : 指定属性的约束是否使用 非空
  • unique : 指定属性的约束是否使用 唯一
  • -->
  • <!--
  • type: 表达该属性的类型
  • 可以用三种方式指定属性
  • java类型 数据库类型指定 Hibernate类型指定
  • java.lang.String varchar string
  • -->
  • <property name="name" column="name" update="true" type="string" ></property>
  • <property name="password" column="password"></property>
  • <property name="sal" column="sal" precision="2" scale="3" ></property>
  • </class>
  • </hibernate-mapping>

2.4. 编写核心配置文件

  • 位置:类路径(classpathsrc),即WEB-INF/classes
  • 名称:hibernate.cfg.xml

核心配置文件hibernate.cfg.xml用于配置数据库连接等信息,代码如下:

  • <?xml version="1.0" encoding="UTF-8"?>
  • <!DOCTYPE hibernate-configuration PUBLIC
  • "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  • "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
  • <hibernate-configuration>
  • <session-factory>
  • <!-- property 元素用于配置Hibernate中的属性
  • 键:值
  • -->
  • <!-- hibernate.connection.driver_class : 连接数据库的驱动 -->
  • <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  • <!-- hibernate.connection.username : 连接数据库的用户名 -->
  • <property name="hibernate.connection.username">root</property>
  • <!-- hibernate.connection.password : 连接数据库的密码 -->
  • <property name="hibernate.connection.password">1234</property>
  • <!-- hibernate.connection.url : 连接数据库的地址,路径 -->
  • <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/EE19Day01</property>
  • <!-- show_sql: 操作数据库时,会 向控制台打印sql语句 -->
  • <property name="show_sql">true</property>
  • <!-- format_sql: 打印sql语句前,会将sql语句先格式化 -->
  • <property name="format_sql">true</property>
  • <!-- hbm2ddl.auto: 生成表结构的策略配置
  • update(最常用的取值): 如果当前数据库中不存在表结构,那么自动创建表结构.
  • 如果存在表结构,并且表结构与实体一致,那么不做修改
  • 如果存在表结构,并且表结构与实体不一致,那么会修改表结构.会保留原有列.
  • create(很少):无论是否存在表结构.每次启动Hibernate都会重新创建表结构.(数据会丢失)
  • create-drop(极少): 无论是否存在表结构.每次启动Hibernate都会重新创建表结构.每次Hibernate运行结束时,删除表结构.
  • validate(很少):不会自动创建表结构.也不会自动维护表结构.Hibernate只校验表结构. 如果表结构不一致将会抛出异常.
  • -->
  • <property name="hbm2ddl.auto">update</property>
  • <!-- 数据库方言配置
  • org.hibernate.dialect.MySQLDialect (选择最短的)
  • -->
  • <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  • <!-- hibernate.connection.autocommit: 事务自动提交 -->
  • <property name="hibernate.connection.autocommit">true</property>
  • <!-- 将Session与线程绑定=> 只有配置了该配置,才能使用getCurrentSession -->
  • <property name="hibernate.current_session_context_class">thread</property>
  • <!-- 引入ORM 映射文件
  • 填写src之后的路径
  • -->
  • <mapping resource="com/itheima/a_hello/User.hbm.xml"/>
  • </session-factory>
  • </hibernate-configuration>

2.5. 测试代码

  • package com.coderap.hello;
  • import org.hibernate.SessionFactory;
  • import org.hibernate.cfg.Configuration;
  • import org.hibernate.classic.Session;
  • import org.junit.Test;
  • public class Test01 {
  • @Test
  • public void fun1() {
  • // 1 读取配置文件
  • Configuration conf = new Configuration().configure();
  • // 2 根据配置 创建Factory
  • SessionFactory sessionFactory = conf.buildSessionFactory();
  • // 3 通过获得操作数据库的session对象
  • Session session = sessionFactory.openSession();
  • // 4 操作数据库
  • User u = new User();
  • u.setName("tom");
  • u.setPassword("1234");
  • session.save(u);
  • // 5 关闭资源
  • session.close();
  • sessionFactory.close();
  • }
  • }

注:如果出现Unknown entity异常,将映射文件*.hbm.xml添加到核心配置文件hibernate.cfg.xml中即可。