对象持久化
•狭义的理解,“持久化”仅仅指把对象永久保存到数据库中
•广义的理解,“持久化”包括和数据库相关的各种操作:
- –保存:把对象永久保存到数据库中。
- –更新:更新数据库中对象(记录)的状态。
- –删除:从数据库中删除一个对象。
- –查询:根据特定的查询条件,把符合查询条件的一个或多个对象从数据库加载到内存中。
- –加载:根据特定的OID,把一个对象从数据库加载到内存中。
ORM对象关系模型结构图
环境配置
刚开始接触Hibernate这个新鲜事物(于我而言),其中与其他框架有着很多相似的地方,但其专攻的是持久层的开发设计,所以自然又有着本质的区别。首先使用hibernate得配置一个运行环境,这里我使用的是4.2.4版本的hibernate。
环境搭建好了,就到了hibernate在实际中的使用配置了。其配置内容都在'hibernate.cfg.xml'之中,这个xml文件创建在src原文件夹下即可,其中具体需要配置在“hibernate-configuration”这个节点中,其中会话工厂“hibernate-configuration”这个节点下面则是具体配置内容;数据库连接池、方言、sql语句显示等。
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 会话工厂配置 -->
<session-factory>
<!-- 配置连接池 -->
<!-- driver、url、username、password -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:XE</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<!-- 方言:为不同的数据库,不同的版本,生成sql语句(DQL查询语句)提供依据 -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- 是否打印sql -->
<property name="show_sql">true</property>
<!-- sql语句格式化 -->
<property name="hibernate.format_sql">true</property>
<!-- 是否让hibernate创建表结构 -->
<property name="hbm2ddl.auto">update</property>
<!-- 配置映射文件 -->
<mapping resource="com/ozc/entity/Dict.hbm.xml" />
</session-factory>
</hibernate-configuration>
实体类映射
由以上配置也可以看到配置信息最后有这么一个映射配置<mapping>,其中需要配置的就是实际需要映射的JavaBean的配置文件,当然该映射可以设置多个。具体的配置方式简单明了,配置JavaBean所在的包路径,类名以及对应数据库中的表名,接着property配置JavaBean中的属性对应的数据库中的字段名。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- javaBean映射配置 -->
<hibernate-mapping package="com.ozc.entity">
<class name="Dict" table="T_Dict">
<id name="id" column="ID">
<!-- 配置ID生成器 -->
<!-- increment属性ID自增1 -->
<generator class="increment" />
</id>
<property name="name" not-null="true" column="NAME" />
<property name="dkey" column="DKEY" />
<property name="dval" column="DVAL" />
<property name="useFlag" column="USE_FLAG" />
<property name="orderNo" column="ORDER_NO" />
<property name="createDate" column="CREATE_DATE" />
</class>
</hibernate-mapping>
这样基本的配置信息就完成了。
核心配置详解
核心 api
Configuration
常用方法
- 构造方法:默认加载 hibernate.properties
- configure() 方法:默认加载 hibernate.cfg.xml
- configure(String) 方法:加载指定配置文件
手动添加映射
// 手动加载指定的配置文件
config.addResource("com/ittianyu/a_hello/User.hbm.xml");
// 手动加载指定类,对应的映射文件 User--> User.hbm.xml
config.addClass(User.class);
SessionFactory
- SessionFactory 相当于java web连接池,用于管理所有session
- 获得方式:config.buildSessionFactory();
- sessionFactory hibernate缓存配置信息 (数据库配置信息、映射文件,预定义HQL语句 等)
- SessionFactory线程安全,可以是成员变量,多个线程同时访问时,不会出现线程并发访问问题
- 开启一个 session:
factory.openSession();
- 获取和当前线程绑定的会话(需要配置):
factory.getCurrentSession();
<property name="hibernate.current_session_context_class">thread</property>
Session
- Session 相当于 JDBC的 Connection -- 会话
- 通过session操作PO对象 --增删改查
- session单线程,线程不安全,不能编写成成员变量。
- Api:
save 保存
update 更新
delete 删除
get 通过id查询,如果没有 null
load 通过id查询,如果没有抛异常
createQuery("hql") 获得Query对象
createCriteria(Class) 获得Criteria对象
Transaction
开启事务 beginTransaction()
获得事务 getTransaction()提交事务:commit()
回滚事务:rollback()
和 spring 整合后,无需手动管理
Query
- hibernate执行hql语句
- hql语句:hibernate提供面向对象查询语句,使用对象(类)和属性进行查询。区分大小写。
- 获得
session.createQuery("hql")
-
方法:
list() 查询所有
uniqueResult() 获得一个结果。如果没有查询到返回null,如果查询多条抛异常。setFirstResult(int) 分页,开始索引数startIndex
setMaxResults(int) 分页,每页显示个数 pageSize
Criteria
- QBC(query by criteria),hibernate提供纯面向对象查询语言,提供直接使用PO对象进行操作。
- 获得方式:Criteria criteria = session.createCriteria(User.class);
- 条件
criteria.add(Restrictions.eq("username", "tom"));
Restrictions.gt(propertyName, value) 大于
Restrictions.ge(propertyName, value) 大于等于
Restrictions.lt(propertyName, value) 小于
Restrictions.le(propertyName, value) 小于等于
Restrictions.like(propertyName, value) 模糊查询,注意:模糊查询值需要使用 % _
工具类
public class HibernateUtils {
private static SessionFactory sessionFactory;
static {
Configuration configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
sessionFactory.close();
}
});
}
public static Session openSession() {
return sessionFactory.openSession();
}
public static Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
public static void main(String[] args) {
Session session = openSession();
System.out.println(session);
session.close();
}
}
不同版本的工厂创建
-如果使用的是hibernate4.2之前的版本,那么方法就这么写:
static {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(config.getProperties()).buildServiceRegistry();
// 创建会话工厂对象
sessionFactory = config.buildSessionFactory(serviceRegistry);
// 会话对象
session = sessionFactory.openSession();
// 开启事务
transaction = session.beginTransaction();
}
-如果是hibernate4.3之后的版本,那么方法就这么写:
导入包更换:org.hibernate.boot.registry.StandardServiceRegistryBuilder;
static {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(config.getProperties()).build();
// 创建会话工厂对象
sessionFactory = config.buildSessionFactory(serviceRegistry);
// 会话对象
session = sessionFactory.openSession();
// 开启事务
transaction = session.beginTransaction();
}
-甚至到hibernate5之后连上面的包都可以省略了:
static {
//创建配置对象(读取配置文档)
Configuration config = new Configuration().configure();
//创建会话工厂对象
sessionFactory = config.buildSessionFactory();
//会话对象
session = sessionFactory.openSession();
//开启事务
transaction = session.beginTransaction();
}