1. Hibernate技术简介
Hibernate能够使关系数据变得十分容易,是数据库表的访问同普通Java对象访问一样简单和快捷。更加方便的是程序员不必考虑如何将这些Java对象和数据库表中的数据保持同步,这些工作由Hibernate来完成。这样解放了程序员,使其可以专注于应用程序的对象和功能,而不必担心如何保存它们或者如何存取数据库。
1.1 什么是ORM
ORM(Object / Relational Mapping)是一种为了解决面向对象与关系数据库存在的互不匹配的问题的技术。简单来说ORM本质上就是将数据从一种形式转换到另外一种形式。虽然增加了一些额外的执行程序,但是ORM作为一种中间件实现,则提供很多机会做优化处理。
1.2 ORM组成
- 一个对持久类对象进行CRUD操作的API
- 一个语言或API用来规定与类和类属性相关的查询
- 一个规定mapping metadata 的工具
- 一种技术可以让ORM的实现同事务对象一起进行dirty checking、lazy association fetching 以及其他优化操作。
2. Hibernate 概述
Hibernate是一种Java语言下的对象关系映射解决方案。它是一种自由、开源的软件。
2.1 Hibernate用途
Hibernate设计目标是将软件开发人员从大量相同数据持久层相关变成工作中解放出来。无论是从设计草案还是从一个遗留数据库开始,开发人员都可以采用Hibernate。
在这个图中有一些概念需要进行说明:
SessionFactory:它针对单个数据库映射关系进行编译后的内存镜像,是线程安全(不可变)。它是生成Session的工厂,本身要用到ConnectionPrivider。该对象可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存。
Session:表示应用程序域持久存储层之间交互操作的一个单线程对象,此对象生存期很短。其隐藏了JDBC连接,也是Transaction的工厂。它有持久一个针对持久化对象的必选(第一级)缓存,在遍历对象图或者根据持久化标识查找对象是会用到。
2.2 Hibernate优点
- Hibernate 是JDBC的轻量级的对象封装。它是一个独立的对象持久层框架,和App Sever、EJB 没有什么必然的关系。Hibernate可以用在任何JDBC可以使用的场合,例如:Java应用程序的数据库访问代码,DAO接口的实现类,甚至可以是BMP里面的访问数据库的代码,从这个意义上来说,Hibernate和EJB不是一个范畴的东西,也不存在非此即彼的关系。
- Hibernate 是一个和JDBC密切关联的框架,所以Hibernate的兼容性和JDBC驱动,和数据库都有一定的关系,但是和使用它的Java程序,和App Sever 没有任何关系,也不存在兼容性问题。
- Hibernate不能用来直接和Entity Bean做对比。只有放在整个J2EE项目的框架中才能比较。并且即使是放在软件整体框架中来看。Hibernate也是作为JDBC的替代者出现的,而不是Entity Bean的替代者出现的。
- Hibernate 发展前景很好,新版的Hibernate 不但支持Java架构,同时还提供了对微软.net的支持。
3. 我的第一个Hibernate程序(CRUD)
在本程序中我们使用了Hibernate里面的一些XML配置文件进行配置从而达到程序的功能。PS:好了,上干货了。
3.1 工具
eclipse 、mysql、mysql的界面软件navicat、Hibernate包、mysql驱动包
3.2 步骤
3.2.1 建数据库
首先,我们需要在mysql中建立一个数据库,这里我所建立的是thetestcrud,这个数据库名
PS:这里可能有的小伙伴看到了,我并没有在数据库中建立我们需要的表,这个就牵引到自动建表的技术了。
3.2.2 建立hibernate.cfg.xml文件
这个文件是hibernate的配置文件,这里呢主要就是一些数据库连接配置和一些.hbm映射文件。
<?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>
<!-- JDBC的配置代码,与数据库进行链接 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/thetestcrud?characterEncoding=UTF-8</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.username">root</property>
<!-- 指定使用mysql数据库中的SQL语句格式-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 指定在控制台打印生成的Sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 指定Hibernate启动的时候自动创建表结构 -->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 要加这一句,否则可能会出现异常 -->
<property name="current_session_context_class">thread</property>
<!-- 表示为每个线程生成一个session -->
<!-- 指定Cat类为Hibernate实体类 -->
<!-- 在这些后面的参数中,dialect和current_session_context_class是必须的 -->
<mapping resource="hibernate/Medicine.hbm.xml" />
<!-- 告诉Hibernate,Cat类是一个实体类,Hibernate将管理Cat与对应的数据库表 -->
</session-factory>
</hibernate-configuration>
这里呢,就是我的.cfg.xml文件的代码了。
这一个地方呢?有两个地方不得不谈。
一个是hibernate.hbm2ddl.auto的属性值。有下面这些:
- create:加载SesssionFactory时创建表结构。如果原表结构存在,则先删除原表结构。如果classpath根目录有import.sql文件,创建表结构后会执行里面的sql语句。
- create-drop:加载SessionFactory时创建表结构,卸载SessionFactory时( 一般为程序退出时 )删除表结构。如果classpath根目录有import.sql文件,创建表结构后会执行里面的sql语句。
- update:加载SessionFactory 时检查表结构,如果与Entity不一致,则更新表结构。
- validate:加载SessionFactory 时检查表结构。
另外,就是mapping这个标签: - 这个标签就是.hbm.xml文件的相对路径。就不再重复说明了。
3.2.3 建立持久化文件
持久化文件:也就是将文件从暂时的文件类型中转换成持久也就是硬盘中的文件
package hibernate;
public class Medicine {
private int id;
private String name;
private double price;
private String factoryAdd;
private String Description;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getFactoryAdd() {
return factoryAdd;
}
public void setFactoryAdd(String factoryAdd) {
this.factoryAdd = factoryAdd;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
}
这个就没什么说的了。
3.2.4 建立.hbm.xml 文件
当我们建立很好持久化文件之后,就会发现在我们建立.hbm.xml的时候,会有自动生成。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-2-20 22:15:36 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="hibernate.Medicine" table="MEDICINE">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="price" type="double">
<column name="PRICE" />
</property>
<property name="factoryAdd" type="java.lang.String">
<column name="FACTORYADD" />
</property>
<property name="Description" type="java.lang.String">
<column name="DESCRIPTION" />
</property>
</class>
</hibernate-mapping>
这个也有一个重点,就是要和持久化文件在一个包中。
然后,就是在.cfg.xml中就可以设置mapping属性值了,就是文件的相对路径。
3.2.5 编写工具类
这个可以一直使用,只需要编写一次就行
package hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory factory = null;
static {
try{
Configuration cfg = new Configuration().configure();
factory = cfg.buildSessionFactory();
}catch(HibernateException e){
e.printStackTrace();
}
}
public static Session getSession(){
Session session = (factory != null)?factory.openSession():null;
return session;
}
public static SessionFactory getSessionFactory(){
return factory;
}
public static void closeSession(Session session){
if(session != null){
if(session.isOpen()){
session.close();
}
}
}
}
3.2.6测试代码
3.2.6.1 插入
package Test;
import org.hibernate.Session;
import hibernate.HibernateUtil;
import hibernate.Medicine;
public class Save {
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
Medicine medicine = new Medicine();
medicine.setId(12);
medicine.setName("感冒");
medicine.setPrice(1.00);
medicine.setFactoryAdd("XX制厂");
medicine.setDescription("最新感药");
session.save(medicine);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
HibernateUtil.closeSession(session);
}
}
}
3.2.6.2 删除
package Test;
import org.hibernate.Session;
import hibernate.HibernateUtil;
import hibernate.Medicine;
public class Delete {
public static void main(String[] args) {
Session session = null;
try {
session = HibernateUtil.getSession();
session.beginTransaction();
Medicine medicine = session.load(Medicine.class, new Integer(2));
session.delete(medicine);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
HibernateUtil.closeSession(session);
}
}
}
3.3.6.3更改
1.手动更改
package Test;
import org.hibernate.Session;
import hibernate.HibernateUtil;
import hibernate.Medicine;
public class HandUpdate {
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session = null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
Medicine medicine = new Medicine();
medicine.setId(2);
medicine.setName("fdfdfd");
session.update(medicine);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtil.closeSession(session);
}
}
}
- 自动更改
package Test;
import org.hibernate.Session;
import hibernate.HibernateUtil;
import hibernate.Medicine;
public class AutoUpdate {
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session = null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
Medicine medicine = session.load(Medicine.class, new Integer(2));
medicine.setName("hhhh");
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtil.closeSession(session);
}
}
}
3.3.6.4 查找
package Test;
import org.hibernate.Session;
import hibernate.HibernateUtil;
import hibernate.Medicine;
public class SelectData {
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session =null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
//Medicine medicine = session.get(Medicine.class, new Integer(12));//使用get方法
Medicine medicine1 = session.load(Medicine.class, new Integer(12));//使用load方法
System.out.println(medicine1.getId());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtil.closeSession(session);
}
}
}
还有程序的目录结构:
4. 总结
在这个程序中,我们能学习到一些基础的Hibernate CRUD操作,不算复杂,但是我觉得非常的实用。