一、需要的jar包
二、在src下加入Hibernate的配置文件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">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<!--配置连接数据库的基本信息 -->
<property name="connection.username">root</property>
<property name="connection.password">zj123456</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/hibernate
</property>
<!-- 配置Hibernate -->
<!-- hibernate 所使用的数据库方言 -->
<property name="dialect">
org.hibernate.dialect.MySQLInnoDBDialect
</property>
<!-- 执行操作时是否在控制台打印SQL -->
<property name="show_sql">true</property>
<!-- s是否对SQL 进行格式化 -->
<property name="format_sql">true</property>
<!-- 制定自动生成数据表的策略 -->
<property name="hbm2ddl.auto">update</property>
<!-- 修改事务的隔离级别 -->
<property name="connection.isolation">2</property>
<!-- 删除对象后,使其OID 置为null -->
<property name="use_identifier_rollback">true</property>
<!-- 设定 JDBC 的Statement 读取的数时候每次从数据库中取出的记录条数 -->
<property name="jdbc.fetch_size">100</property>
<!-- 设定对数据库进行批量删除,批量更新和批量插入时候的批次大小 -->
<property name="jdbc.batch_size">30</property>
<!-- 配置C3P0 -->
<property name="c3p0.max_size">10</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.acquire_increment">2</property>
<property name="c3p0.idle_test_period">2000</property>
<property name="c3p0.timeout">2000</property>
<property name="c3p0.max_statements">10</property>
<!-- 配置管理Session 的方式 -->
<property name="current_session_context_class">thread</property>
<!-- 指定关联的。hbm.xml 文件 -->
<mapping
resource="com/zhuojing/hibernate/helloworld/News.hbm.xml" />
</session-factory>
</hibernate-configuration>
三、数据库表对应实体和映射文件
1、创表语句
CREATE TABLE `news` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`title` varchar(30) DEFAULT NULL,
`author` varchar(30) DEFAULT NULL,
`date` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
2、映射文件News.hbm.xml
<?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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.zhuojing.hibernate.helloworld.News" table="news" catalog="hibernate">
<id name="id" type="java.lang.Integer">
<column name="id" />
<!-- 指定主键的生成方式,native:使用数据库本地的方式 -->
<generator class="native" />
</id>
<property name="title" type="java.lang.String">
<column name="title" length="30" />
</property>
<property name="author" type="java.lang.String">
<column name="author" length="30" />
</property>
<property name="date" type="java.sql.Timestamp">
<column name="date" length="19" />
</property>
</class>
</hibernate-mapping>
注:generator主键生成方式类型
A:increment 标识符生成器
a:increment 标识符生成器由 Hibernate 以递增的方式为代理主键赋值
b:Hibernate 会先读取 NEWS 表中的主键的最大值, 而接下来向 NEWS 表中插入记录时, 就在 max(id) 的基础上递增, 增量为 1.
c:适用范围:
由于 increment 生存标识符机制不依赖于底层数据库系统, 因此它适合所有的数据库系统
适用于只有单个 Hibernate 应用进程访问同一个数据库的场合, 在集群环境下不推荐使用它
OID 必须为 long, int 或 short 类型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常
B:identity 标识符生成器
a:identity 标识符生成器由底层数据库来负责生成标识符, 它要求底层数据库把主键定义为自动增长字段类型
b:适用范围:
由于 identity 生成标识符的机制依赖于底层数据库系统, 因此, 要求底层数据库系统必须支持自动增长字段类型. 支持自动增长字段类型的数据库包括: DB2,Mysql, MSSQLServer, Sybase 等
OID 必须为 long, int 或 short 类型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常
C:hilo 标识符生成器
a:hilo 标识符生成器由 Hibernate 按照一种 high/low 算法*生成标识符, 它从数据库的特定表的字段中获取 high 值.
b:适用范围:
由于 hilo 生存标识符机制不依赖于底层数据库系统, 因此它适合所有的数据库系统
OID 必须为 long, int 或 short 类型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常
D:native 标识符生成器(常用,根据数据库自身规则生成)
a:native 标识符生成器依据底层数据库对自动生成标识符的支持能力, 来选择使用 identity, sequence 或 hilo 标识符生成器.
b:适用范围
由于 native 能根据底层数据库系统的类型, 自动选择合适的标识符生成器, 因此很适合于跨数据库平台开发
OID 必须为 long, int 或 short 类型, 如果把 OID 定义为 byte 类型, 在运行时会抛出异常
3、对应的实体bean
public class News {
private Integer id;
private String title;
private String author;
private Date date;
//省去getter和setter方法
}
四、测试类
package com.zhuojing.hibernate.helloworld;
import static org.junit.Assert.*;
import java.sql.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.Test;
public class HibernateTest {
@Test
public void test() {
//1.创建一个SessionFactory 对象
SessionFactory sessionFactory = null;
//1).创建Configuration对象:对应的hibernate 的基本配置信息和对应关系映射信息
Configuration configuration = new Configuration().configure();
//4.0之前创建方法
//sessionFactory = configuration.buildSessionFactory()
//2).创建一个ServiceRegistry 对象:Hibernate 4.x 新添加的对象
//Hibernate 的任何配置和服务器都需要在该文件中注册后才能有效
ServiceRegistry serviceRegistry =
new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
//2.创建一个Session 对象
Session session = sessionFactory.openSession();
//3.开启事务
Transaction transaction = session.beginTransaction();
//4.执行保存操作
News news = new News("Java","zhuojing", new Date(new java.util.Date().getTime()));
session.save(news);
//5.提交事务
transaction.commit();
//6.关闭Session
session.close();
//7.关闭SessionFactory 对象
sessionFactory.close();
}
}
注:其他的核心方法
在介绍核心方法之前先说明下OID的概念,
在关系数据库中,主键用来识别记录,并保证每天记录的唯一性。在Java语言中,通过比较两个变量所引用对象的内存地址是否相同,或者比较两变量引用的对象是否相等。Hibernate为了解决两者之间的不同,使用对象标识符(OID)来标识对象的唯一性。OID是关系数据库中主键在Java对象模型中的等价物。在运行时,Hibernate根据OID来维持Java对象和数据库中的对应关系。如下所示:
Transaction tx = session.beginTransaction();
New new1= (New)session.load(New.class,new Long(1));
New new2= (New)session.load(New.class,new Long(1));
New new3 = (New)session.load(New.class,new Long(3));
应用程序在执行上述代码时,第一次OID为1的对象,从数据库中查找ID为1的记录,然后创建想要的New实例,并把它保存到session的缓存中,最后将该实例的引用赋值给变量user1,第二次加载OID为1的对象时,直接把session缓存中的OID为1的实例的引用赋值给user2,因此new1=new2的结果为
其他核心方法
A:持久化对象的状态
a:临时对象
①:在使用代理主键的情况下, OID 通常为 null
②:不处于 Session 的缓存中
③:在数据库中没有对应的记录
b:持久化对象(也叫”托管”)(Persist)
①:OID 不为 null
②:位于 Session 缓存中
③:若在数据库中已经有和其对应的记录, 持久化对象和数据库中的相关记录对应
④:Session 在 flush 缓存时, 会根据持久化对象的属性变化, 来同步更新数据库
⑤:在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象
c:删除对象(Removed)
①:在数据库中没有和其 OID 对应的记录
②:不再处于 Session 缓存中
③:一般情况下, 应用程序不该再使用被删除的对象
d:游离对象(也叫”脱管”) (Detached):
①:OID 不为 null
②:不再处于 Session 缓存中
③:一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录
B:Save() 方法:
a:使一个临时对象变为持久化对象
b:为对象分配ID
c:在flush 缓存时会发送一条 INSERT 语句
d:在save 方法之前的 id 是无效
e:持久化对象的 ID 是不能被修改的
C:persist:也会执行 INSERT 操作
a:和save() 方法的区别:早调用 persist 方法之前,若对象已经有 id 了, 则不会执行 INSERT, 而抛出异常
D:get 和 load 的区别
a:执行get 方法:会立即加载对象
执行load 方法,若不使用该对象,则不会执行查询操作,而返回一个代理对象
b:若数据表中没有对应的记录,且Session也没有关闭,同时需要使用对象
get 返回null
load 若不使用该对象的任何属性,没问题,若需要初始化了会抛出异常
c:load 方法可能会抛出 LazyInitializationException 异常:在需要初始化代理对象之前关闭了Session
E:update:
a:若更新一个持久化对象,不需要显式的调用 update 方法,因为调用Transition的 commit()方法时,会先执行session 的 flush 方法
b:更新一个游离对象,需要显式的调用 session 的update 方法,可以把一个游离对象变成持久化对象
c:注意
①:无论要更新的游离对象和数据表是否一致,都会发生UPDATE 语句, 如何能让 update 方法不盲目的发 update 语 句:在.hbm.xml 文件的class 节点设置 select-before-update="true"(默认为false),通常不需要这样设置该属性
②:若数据表中没有对应的记录,但还调用了 update 方法,会抛出异常
③:当 update() 方法关联一个游离对象时,如果在Session 的缓存中已经存在相同的OID 的持久化对象,会抛出异常, 因为在 Session 缓存中不能有两个相同的对象
F:saveOrUpdate:
a:Session 的 saveOrUpdate() 方法同时包含了 save() 与 update() 方法的功能,游离对象执行 update(), 历史对象执行 save()
b:若OID 不为null,但在数据表中还没有对应的记录,会抛出一个异常
c:了解:OID 值等于 id 的 unsaved-value 属性值的对象,也被认为是一个临时对象
H:delete:
a:执行删除操作,只要 OID 和数据表中一条记录对应,就会执行delete 操作若 OID 在数据表中没有对应的记录,则抛出 异常
b:可以通过设置use_identifier_rollback 为true,使删除对象后,把其 OID 置为null
I:evict:从session 缓存中把指定的持久化对象移除
J:doWork:获取原生的Connection 对象