一、什么是ORM?
1、O/R Mapping:
对象关系映射(Object Relational Mapping,简称ORM)技术,是通过使用描述对象和数据库之间映射的元数据,将Java程序中的对象自动持久化到关系数据库中。
2、关于ORM的说明:
(1)对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。
(2)内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。
(3)因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
二、什么是Hibernate?
1、Hibernate:
(1)Hibernate是一个开放源码的、非常优秀、成熟的O/R Mapping框架。它提供了强大、高性能的Java对象和关系数据的持久化和查询功能。
(2)Hibernate只是一个将持久化类与数据库表相映射的工 具,每个持久化类实例均对应于数据库表中的一条数据行。
(3)可以使用面向对象的方法操作此持久化类实例,完成对数据库表的插入、删除、修改等操作。
(4)利用Hibernate操作数据库,我们通过应用程序经过Hibernate持久层来访问数据库,其实Hibernate完成了以前JDBC的功能,不过Hibernate使用面向对象的方法操作数据库。
三、Hibernate体系结构
关于Hibernate体系结构的说明:
(1)首先通过Application访问Hibernate,
(2)然后Hibernate持久化对象,
(3)接着在Hibernate通过配置XML Mapping对象关系映射文件,
(4)最后将此对象作为一行数据插入到Database中。
四、Hibernate入门示例
第一步:
(1)先建一个Java工程导入使用Hibernate最小必要包。可以到网站下载Hibernate最新的包,如果访问数据库,则需要导入数据库驱动包。
(2)在项目中写一个POJO类(需要用到的值对象,注意一下关于写值对象时候的一些说明)。
创建POJO类,Student.java:
package cn.hncu.demo.domain;
/**
* 项目名:HibernateDemo
* 时间 :2017-8-13 下午11:53:41
*
* 1.关于值对象的说明:
* 【无参数构造函数是一个持久类的要求;Hibernate已为您创建对象,使用java反射。
* 构造函数可以是私有的,但是运行时代理生成和有效的数据检索所需的包或公共可见性是不需要字节码的。】
*
* 2.进一步说明:
* 【这个类使用标准的JavaBean命名约定,用于属性获取器和设置方法,以及字段的私有可见性。虽然这是推荐的设计,但不是必需的。
* Hibernate也可以直接访问字段,访问器方法的好处是鲁棒性的重构。id属性为特定事件保留唯一标识符值。
* 如果我们想使用Hibernate的全部特性集,所有持久的实体类(还有不太重要的依赖类)都需要这样的标识符属性。
* 事实上,大多数应用程序,尤其是Web应用程序都需要通过标识符来区分对象,因此您应该考虑这一特性而不是局限性。
* 但是,我们通常不处理对象的标识,因此set方法应该是私有的。只有Hibernate在保存对象时才会分配标识符。】
*
* 3.【注意】接下来,我们创建一个类来表示要存储在数据库中的事件;它是一个具有一些属性的简单JavaBean类。
*
*
*/
public class Student {
private String studId;
private String studName;
private Integer age;
private String deptId;
public Student() {
super();
}
public String getStudId() {
return studId;
}
public void setStudId(String studId) {
this.studId = studId;
}
public String getStudName() {
return studName;
}
public void setStudName(String studName) {
this.studName = studName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getDeptId() {
return deptId;
}
public void setDeptId(String deptId) {
this.deptId = deptId;
}
}
创建数据库语句:
create database hib character set utf8;
use hib;
create table students(
id varchar(8) primary key,
name varchar(40),
age int,
deptId varchar(8)
);
insert into students values('S001','Jack',20,'D001');
insert into students values('S002','Tom', 21,'D001');
insert into students values('S003','张三',23,'D002');
insert into students values('S004','李四',24,'D002');
insert into students values('S005','王五',22,'D002');
第二步:
(1)写一个XML Mappping File 配置文件,并且跟POJO类(值对象)的位置并列,而且取名为:POJO类名.hbm.xml 。
(2)关于XML Mappping File的说明:
<1>、Hibernate需要知道如何加载和存储持久类的对象。这就是Hibernate映射文件发挥作用的地方。
<2>、映射文件告诉Hibernate它必须访问数据库中的表,以及它应该使用的表中的哪些列。
(3)XML Mappping File文件的第一部分:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
(4)XML Mappping File文件的结构:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.hncu.demo.domain">
[...中间内容..]
</hibernate-mapping>
(5)XML Mappping File中的元素的说明:
<hibernate-mapping ></hibernate-mapping>
该配置文件站的立场是Object, 去配置自己和 数据库表之间的映射关系 。hibernate-mapping元素常用的属性是package,其属性值为POJO类所在的包路径,如<hibernate-mapping package="cn.hncu.demo.domain"></hibernate-mapping>
。
<class></class>
在两个Hibernate映射标记之间,包含一个类class元素。所有持久性实体类(再次,可能以后依赖类,而不是一级实体)需要对SQL数据库中的表进行映射。class元素常用的属性是name,table,catlog,其中name的属性值为当前POJO类的类名;table的属性值为当前类所映射到数据库表中的表名;catlog为数据库名,可以夸库;如<class name="Student" table="students" catalog="hib" >
。
<id></id>
id元素是标识符属性的声明,id元素常用的属性是name,type,其中name属性值是将映射名称的JavaBean属性,告诉Hibernate使用getid()和setid()方法来访问属性;type属性是指定POJO类成员变量的类型,如<id name="studId" type="java.lang.String" >
。
<column></column>
column列元素的属性有name,length,name的属性值是数据表中的主键名,告诉Hibernate事件表的哪个列保存主键值;length的属性值是数据表主键的长度,如<column name="id" length="8"></column>
。
<property> <column></column> </property>
只有主键字段对应的属性变量才能用id,其它字段对应的属性变量都用property 。property的属性值和用法与id元素类似,如<property name="studName" type="java.lang.String">
。
(6)依据上面的元素说明,可以翻译出一个完整的XML Mappping File:Student.hbm.xml :
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--【注意】 该配置文件站的立场是Object, 去配置自己和 数据库表之间的映射关系 -->
<hibernate-mapping package="cn.hncu.demo.domain" >
<class name="Student" table="students" catalog="hib">
<!--【注意】id标记是指Student类中的属性变量,该属性是表主键字段对应 -->
<id name="studId" type="java.lang.String" >
<!--【注意】 column标记是指数据库表中的哪一列(字段) -->
<column name="id" length="8"></column>
</id>
<!--【注意】只有主键字段对应的属性变量才能用id,其它字段对应的属性变量都用property -->
<property name="studName" type="java.lang.String">
<column name="name" length="40"></column>
</property>
<property name="age" type="java.lang.Integer">
<column name="age" ></column>
</property>
<property name="deptId" type="java.lang.String">
<column name="deptId" length="8"></column>
</property>
</class>
</hibernate-mapping>
第三步:
(1)在src创建配置文件hibernate.cfg.xml,放置在src目录中。
Hibernate configuration配置文件
<?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 name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/hib</property>
<property name="connection.username">root</property>
<property name="connection.password">1234</property>
<!-- SQL的方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 一定要将对象映射文件配置进来 -->
<mapping resource="cn/hncu/demo/domain/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
第四步:
(1)编写一个会话工厂类。通过会话工厂类产生一个会话Session对象。Session对象是Hibernate的核心。任何对数据库操作都在会话中进行的。
package cn.hncu.demo.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactory {
private static SessionFactory sessionFactory = null;
/**利用本地线程池管理对象*/
private static ThreadLocal<Session> t = new ThreadLocal<Session>();
/**
* 用单例的形式初始化工厂类
*/
static{
try {
// Create the SessionFactory from hibernate.cfg.xml
Configuration config = new Configuration().configure();
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings( config.getProperties() ).build();
sessionFactory = config.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
}
}
/**
* 获得SessionFactory 工厂类
* @return
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* 获得Session类
* @return
*/
public static Session getSession() {
Session session = t.get();/*先到本地线程池中去拿Session对象,如果有就拿到*/
if(session==null || sessionFactory==null){/*如果session为空或者sessionFactory为空,一定要开启一个session*/
session = (sessionFactory!=null)?sessionFactory.openSession():null;/*如果sessionFactory不为空,一定开启一个session*/
t.set(session);/*将拿到的session放入到线程池中*/
}
return session;
}
}
第五步:
(1)编写测试文件
package cn.hncu.demo;
import org.hibernate.Session;
import cn.hncu.demo.domain.Student;
import cn.hncu.demo.util.HibernateSessionFactory;
public class StudentManager {
public static void main(String[] args) {
Session session = HibernateSessionFactory.getSession();
/*开启事务*/
session.beginTransaction();
Student student = new Student();
student.setStudId("s008");
student.setStudName("Jack");
student.setAge(20);
student.setDeptId("D004");
session.save(student);
/*提交事务*/
session.getTransaction().commit();
}
}
(2)执行结果:
项目整体框架:
程序执行结果:
八月 14, 2017 1:20:47 下午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
八月 14, 2017 1:20:47 下午 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.7.Final}
八月 14, 2017 1:20:47 下午 org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
八月 14, 2017 1:20:47 下午 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
八月 14, 2017 1:20:47 下午 org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: /hibernate.cfg.xml
八月 14, 2017 1:20:47 下午 org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: /hibernate.cfg.xml
八月 14, 2017 1:20:48 下午 org.hibernate.cfg.Configuration addResource
INFO: HHH000221: Reading mappings from resource: cn/hncu/demo/domain/Student.hbm.xml
八月 14, 2017 1:20:48 下午 org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
八月 14, 2017 1:20:49 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
八月 14, 2017 1:20:49 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://127.0.0.1:3306/hib]
八月 14, 2017 1:20:49 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=root, password=****}
八月 14, 2017 1:20:49 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
八月 14, 2017 1:20:49 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
八月 14, 2017 1:20:50 下午 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
八月 14, 2017 1:20:50 下午 org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
八月 14, 2017 1:20:50 下午 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
至此,一个Hibernate完整的简单流程示例做完了, 这样就可以使用Hibernate这个框架进行我们的Web项目的进一步的开发了,在后面还会用到Hibernate的操作数据库知识,后面去学了!