hibernate入门
1.1框架介绍
ssh和ssm
1.2回顾
*传统使用JDBC开发*使用工具包,DbUtils (commons-...)
1.3hibernate 介绍
*Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架
*轻量级:依赖其他内容较少,消耗资源成本少。
*持久层:与数据库进行数据交换。
*ORM ,对象关系映射(object relation mapping)
对象:java一切都是对象,一般情况使用JavaBean
关系:数据库中的表(二维表)
映射:配置文件
1.4流行框架
a、 JPA Java Persistence API 通过注解描述对象与数据表映射关系 (只有接口规范)b、 Hibernate 最流行ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL , Hibernate实现JPA规范
c、 MyBatis 本是apache的一个开源项目 iBatis,支持普通 SQL查询,存储过程和高级映射的优秀持久层框架 (企业主流)
* MyBaits 并不是完全ORM , 需要在xml中配置SQL语句
d、 Apache DBUtils 、Spring JDBCTemplate
SQL语句封装程度 Hibernate > MyBatis > Apache DBUtils 、Spring JDBCTemplate
2第一个案例
2.1编写步骤
*创建java项目*导入jar包
*核心配置文件 hibernate.cfg.xml (configuration)
*JavaBean + 映射文件 (bean名称.hbm.xml)
注意:必须将映射文件,添加核心配置文件中
*操作 api
2.2导入jar包
*版本:3.6.10
hibernate 是 JBOSS框架,JBOSS是EJB服务器,JBOSS推出JBPM工作流
企业主流 Hibernate 版本: hibernate3.x
最新hibernate版本4.x测试版,hibernate4和hibernate3开发有很多不同
***** hibernate 还有很多扩展技术 search、validator ....
下载 hibernate-distribution-3.6.10.Final-dist.zip
%h%/hibernate3.jar 核心
%h%/lib\required 必须目录下的所有
%h%/lib\jpa java 规范(java persist api)java持久api,hibernate对其支持(一般注解开发)
注意:数据驱动
hibernate 3.x版本 默认采用日志技术 slf4j (即简单日志门面(SimpleLoggingFacadeforJava)) ,不是具体的日志解决方案,它只服务于各种各样的日志系统。
* 使用slf4j好处,很容易整合其他日志技术
企业java开发 最主流日志技术log4j
slf4j-api-1.6.1.jar 没有日志实现,只是接口,整合log4j
导入 slf4j-log4j12-1.7.2.jar (slf4j对log4j框架整合 )
导入 log4j-1.2.16.jar (log4j的日志jar包 )
============================================================================
2.2.1log4j简介
log4j 是企业主流日志技术 ,是Apache公司提供的
1) 什么是日志技术,开发中为什么要用日志技术
日志 : 在系统运行过程中,记录关键信息,记录错误异常信息的技术* 区分 System.out 和 日志技术
* System.out 向控制台输入信息,一定输出
* 日志技术 存在级别,通过级别控制日志是否输出,输出的详细程度, 输出的目的地(控制台、文件、发送邮件)
使用日志: 主要用于开发过程中调试 和 项目上线后的维护(记录bug)
2) 使用log4j 通过配置文件 ,配置日志框架使用
src/log4j.xmlsrc/log4j.properties (简单)
配置log4j.properties 有三个组件
组件一: 记录器(Loggers) 用来配置日志输出级别,使用哪些输出源 格式: 记录器名 = 级别, 输出源1 , 输出源2 ...
* 一个记录器 指定 多个输出源
log4j.rootLogger=info, stdout info是日志级别 , stdout是输出源名称
* log4j提供日志级别 由高到低 :fatal(致命错误), error(普通错误), warn(警告),info(信息), debug(调试), trace(堆栈 )
* log4j记录日志时,只会记录 配置级别更高级别的信息
组件二 : 输出源(Appenders) 在log4j中可以定义多个输出源 (控制台、日志文件、邮件、数据库 )
* log4j.appender.输出源名称 = 实现类
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 向控制台输出
log4j.appender.file=org.apache.log4j.FileAppender 向文件输出
组件三 : 布局(Layouts) 在日志中都记录哪些信息
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 自定义布局
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 自定义布局格式
3)、 在程序中使用log4j 记录日志
步骤一 :定义记录器private static final Logger LOG = Logger.getLogger(Log4jTest.class);
步骤二 :使用 log4j提供每个级别方法 记录日志
LOG.fatal("致命错误");
LOG.error("普通错误");
LOG.warn("警告信息");
LOG.info("普通信息");
LOG.debug("调试信息");
LOG.trace("堆栈信息");
* 常用 : error、warn、info、debug
===========================================================================
2.3核心配置文件
*名称:hibernate.cfg.xml*位置:src (classpath)
*内容:(driver、url、username、password、 方言)
*约束: 可以在hibernate3.jar 文件中查找到 org.hibernate 包下有一个
/org/hibernate/hibernate-configuration-3.0.dtd
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
配置内容
在hibernate的目录 中有一个project/ect目录 有一个hibernate.cfg.xml文件,可以直接copy它.
书写:
在hibernate/project/etc/hibernate.properties文件,在这个文件中定义了键值与value值
<hibernate-configuration>
<!-- sessionFactory 相当于 DataSource(连接池) -->
<session-factory>
<!-- 1 基本4项 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/h_day01_db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<!-- 2方言 ,注意后缀-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
</session-factory>
</hibernate-configuration>
注意:必须手动创建数据库
2.4javabean和映射文件
2.4.1javabean 字段
public class User {private Integer uid; //注意:必须是整形
private String username;
private String password;
2.4.2映射文件
*名称:User.hbm.xml*位置:javabean同包
*内容:(配置javabean属性 和 表中字段 对应关系)
*约束: 在hibernate3.jar 文件中查找到 org.hibernate 包下有一个
/org/hibernate/hibernate-mapping-3.0.dtd
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.domain.User" table="t_user">
<!-- 给表配置主键 -->
<id name="uid">
<!-- 主键生成策略 -->
<generator class="native"></generator>
</id>
<!-- 其他属性 -->
<property name="username"></property>
<property name="password"></property>
</class>
</hibernate-mapping>
注意:映射文件必须添加到核心配置文件中
错误:Unknown entity
*解决方案:hibernate.cfg.xml 中添加映射
<mapping resource="cn/feibai/hibernate/test/User.hbm.xml"/>
</session-factory>
错误:表不存在 Table xxxxx exist
方案2:hibernate自动创建(学习调试选择)
<property name="hibernate.hbm2ddl.auto">update</property>
3CRUD操作
编码模板:
// 实例化配置对象,加载配置文件 hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
// 创建会话连接工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 创建会话
Session session = sessionFactory.openSession();
// 开启事务
Transaction transaction = session.beginTransaction();
//==>>这里可以编写hibernate操作代码逻辑 (********)
// 提交事务,释放资源
transaction.commit();
session.close();
sessionFactory.close();
----------------------------------------------------------
操作
1.添加 save(Object对象).
2.修改 update(Object c)根据id修改的
3.删除 delete(Object c)根据id删除
4.根据id查询 get(CObject.class,id);
5.查询所有 hql
Query query=session.createQuery(String hql);
List<?> list=query.list();
6.查询所有 sql
SQLQuery query=session.createSQLQuery(String sql);
List<Object[]> list=query.list();
可以通过
query.addEntity(Object.class);
在查询时得到的就是
List<Customer> list=query.list();
7.查询所有 Qbc
Criteria ct = session.createCriteria(Object.class);
List<Customer> list = ct.list();
----------------------------------------------------------public class TestCRUD {
@Test
public void demo04(){
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
//分页查询 ,提供hibernate提供的api分页
// * 回顾sql select * from t_user limit startIndex,pageSize;
// ** startIndex 开始索引
// ** pageSize 每页显示个数
Query query = session.createQuery("from User");
// 第一页
// query.setFirstResult(0);
// query.setMaxResults(2);
// 第二页
query.setFirstResult(2); //回顾算法: startIndex = (pageNum - 1 ) * pageSize;
query.setMaxResults(2);
List<User> allUser = query.list();
for (User user : allUser) {
System.out.println(user);
}
session.getTransaction().commit(); //获得之前开启的事务
session.close();
sessionFactory.close();
}
@Test
public void demo03(){
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
//查询所有--使用hibernate 查询 query 语句 hql
// * hql hibernate提供面向对象的查询语句,类似与sql
// ** sql 格式: select 表中字段 from 表名 where ... ,例如: select * from t_user
// ** hql 格式:[select 对象属性] from 对象[ where ...] ,例如:from User
Query query = session.createQuery("from User");
List<User> allUser =query.list();
for (User user : allUser) {
System.out.println(user);
}
session.getTransaction().commit(); //获得之前开启的事务
session.close();
sessionFactory.close();
}
@Test
public void demo02(){
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
//通过id查询
User user = (User)session.get(User.class, 1);
System.out.println(user);
session.getTransaction().commit(); //获得之前开启的事务
session.close();
sessionFactory.close();
}
@Test
public void demo01(){
User user = new User();
user.setUid(1);
user.setUsername("杰克");
Configuration config = new Configuration().configure();
//config.addResource("cn/itcast/domain/User.hbm.xml");
//config.addClass(User.class);
SessionFactory factory = config.buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
//更新 -- 通过id更新所有内容,如果没有设置null
session.update(user);
transaction.commit();
session.close();
factory.close();
}
}
4api详解
4.1结构图
PO persistent object 持久对象
Hibernate中持久化类
编写规则:
提供一个无参数 public访问控制符的构造器
提供一个标识属性,映射数据表主键字段
所有属性提供public访问控制符的 set get 方法
标识属性应尽量使用基本数据类型的包装类型
不要用final修饰 (将无法生成代理对象进行优化)
4.2Configuration
*hibernate 提供用于加载配置文件的。*核心配置文件种类:hibernate.properties 和 hibernate.cfg.xml
一般情况使用 hibernate.cfg.xml ,可以配置不同内容(基本信息,映射文件)
hibernate.properties 只能配置基本信息(key=value)
参考:%h%/project/etc/hibernate.properties
*构造方法,new Configuration() hibernate将加载 hibernate.properties 配置文件
*提供方法:configure() 加载hibernate.cfg.xml 配置文件
通过 configure(String ) 指定自定义的cfg.xml文件。
*加载映射文件 hbm.xml
addResource() 加载自定义的映射文件。例如:config.addResource("cn/itcast/domain/User.hbm.xml");
addClass() 加载自定义映射文件。例如:config.addClass(User.class);
建议:映射文件与Java通同名同包,且扩展名为hbm.xml
注意:如果重复添加JavaBean,提示错误
4.3SessionFactory
*Configuration对象根据当前的配置信息生成 SessionFactory对象
*SessionFactory 对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句
*SessionFactory还负责维护Hibernate的二级缓存(例如: hibernate.cfg.xml / ...hbm.xml 配置内容)
*线程安全的,不同的线程都可以获得不同session。
*获得实例 configuration.buildSessionFactory()
*获得session
openSession() 创建一个回话,每执行一次,session都是新的。
getCurrentSession() 获得当前线程中绑定的session,(需配置才能使用)。
构造SessionFactory 很消耗资源,一般情况下一个应用只初始化一个
抽取HibernateUtils 用来提供Session对象
public class HibernateUtils {
private static Configuration config;
private static SessionFactory factory;
static{
config=new Configuration().configure();
factory=config.buildSessionFactory();
}
public static Session openSession(){
return factory.openSession();
}
public static Session getCurrentSession(){
return factory.getCurrentSession();
}
}
4.4Session
*hibernate 提供 操作 PO类
Session相当于 JDBC的 Connection
Session 是应用程序与数据库之间交互操作的一个单线程对象,是 Hibernate 运作的中心
*线程不安全,及每一个用户必须独享自己的session。
所有持久化对象必须在 session 的管理下才可以进行持久化操作
Session 对象有一个一级缓存,显式执行 flush 之前,所有的持久层操作的数据都缓存在 session 对象处
持久化类与 Session 关联起来后就具有了持久化的能力
save()/persist() 、update() 、saveOrUpdate() 增加和修改对象
delete() 删除对象
get()/load() 根据主键查询
createQuery() / createSQLQuery() 数据库操作对象
createCriteria() 条件查询
*操作事务
如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务
4.5事务操作
*获得当前事务:session.getTransaction()
*提交事务:commit()
*回滚事务:rollback()
* 检查事务是否提交: wasCommitted():
4.6Query
*Query代表面向对象的一个Hibernate查询操作
*session.createQuery 接受一个HQL语句
*HQL是Hibernate Query Language缩写, 语法很像SQL语法,但是完全面向对象的
*使用Query对象步骤
获得Hibernate Session对象
编写HQL语句
调用session.createQuery 创建查询对象
如果HQL语句包含参数,则调用Query的setXXX设置参数
调用Query对象的list() 或uniqueResult() 方法执行查询
*Query还包含两个方法 用于控制返回结果
setFirstResult(int firstResult) 设置返回结果从第几条开始
setMaxResults(int maxResults) 设置本次返回结果记录条数
4.7HQL入门举例
以from开始HQL语句,调用list方法返回List<Customer>
fromCustomer 查询customer表所有数据
使用select 关键字 (查询部分对象属性)
select name from Customer 返回List<Object>
select name,age from Customer 返回 List<Object[] >
select c.name from Customer as c 为Customer实例起别名
使用where添加条件
fromCustomer as c where c.age > :age 其中:age是参数
from Customer as c where c.age > ? 其中?是参数
4.8Criteria
Criteria 是Hibernate提供的用于条件查询接口
Criteriacriteria = session.createCriteria(Customer.class);
使用Criteria对象步骤
获得Hibernate的Session对象
通过Session获得Criteria对象
使用Restrictions的静态方法创建Criterion条件对象
向Criteria对象中添加Criterion 查询条件
执行Criterita的 list() 或uniqueResult() 获得结果是参数
5主配置文件详解
*名称:hibernate.cfg.xml*位置:src (classpath) ---> WEB-INF/classes
*配置 BeanFactory异常
原因:java web 6.0项目,默认进行Bean校验,通常不使用。
解决方案:
方案1:删除此jar==>>libraryset\EE_6\bean-validator.jar
方案2:hibernate 配置取消(见5)
<?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>
<!-- 1 基本4项 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///h_day01_db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<!-- 2 方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 3 开发时,优化设置 -->
<!-- 3.1 显示生产sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 3.2 格式化方式显示sql -->
<property name="hibernate.format_sql">true</property>
<!-- 4 表的创建(了解)
* 开发中表先由DBA创建好,通过表自动生成hbm.xml 映射文件。
* 学生时,方便使用。
* 取值:validate | update | create | create-drop
create : 每一次都将创建表,如果表已经存在将删除。(测试)程序结束之后,表存在的。
create-drop:每一次都将创建表,如果表已经存在将删除。(测试)程序结束之后,将删除表。
注意:必须执行 factory.close() 否则与“create”相同
update : 如果表不存在,将创建。如果存在,将维护对应关系(映射文件 - 表)【】
注意:只负责添加,但不进行删除。
validate : 运行时,将校验 映射文件 和 表 对应关系,如果一一对应程序正常运行,如果不对应抛异常。
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 5 取消bean校验 -->
<property name="javax.persistence.validation.mode">none</property>
<!-- 6 将session绑定当本地线程中
* hibernate session 管理 : 只将使用。
* 当在cfg.xml 配置 thread,SessionFactory提供 getCurrentSession() 将可以使用。
* hibernate底层使用 ThreadLocal 线程局部变量,可以在一个线程中共享数据。
*** get() ##map.get(Thread)
*** set(value) ##map.put(Thread,value)
*** remove() ##map.remove(Thread)
-->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 映射文件 com.itheima-->
<mapping resource="cn/itcast/b_hbm/Person.hbm.xml"/>
<mapping resource="cn/itcast/c_insert_update/Book.hbm.xml"/>
<mapping resource="cn/itcast/d_generator/Category.hbm.xml"/>
</session-factory>
</hibernate-configuration>
5.1问题
*如果使用session.openSession() 可以通过执行多次 session.beginTransaction() 进行多次事务操作。*但如果使用session.getCurrentSession() 只能使用一次,如果进行提交,默认情况下,将进行session.close(),
解决此问题,spring采用 OpenSessionInViewFilter 过滤器。
@Test
public void demo01(){
Configuration config = new Configuration().configure();
SessionFactory factory = config.buildSessionFactory();
Session session = factory.getCurrentSession();
//开启事务
Transaction transaction = session.beginTransaction();
//**** 操作
User user = new User();
user.setUsername("rose2");
user.setPassword("1234");
session.save(user);
//5 提交
transaction.commit();
//再开启 Spring OpenSessionInViewFilter
Transaction transaction2 = session.beginTransaction();
//**** 操作
User user2 = new User();
user2.setUsername("tom");
user2.setPassword("1234");
session.save(user2);
//5 提交
transaction2.commit();
//6 释放
session.close();
//7 关闭工厂
factory.close();
}
5.2配置c3p0连接池
引入c3p0-0.9.1.jar* 在hibernate.cfg.xml文件中增加如下配置
<!-- C3P0连接池设定-->
<!-- 使用c3po连接池 配置连接池提供的供应商-->
<property name="connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
7映射文件详解
*文件名称: javabean名称.hbm.xml
*位置:javabean同包
*内容:
7.1约束
<?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">
<hibernate-mapping>
</hibernate-mapping>
7.2属性基本设置
*普通属性
name : 默认用于配置javabean属性名称
length : 配置长度,字符串默认255,mysql类型 varchar(255)
column : 当前属性对应表中字段(列)名称,默认name的值
方式1:column属性(attribute), <property column="">
方式2:子标签 <property> <columnname="name"></column>
type: 数据字段类型
方式1:hibernate类型,例如:string
方式2:java类型,例如:java.lang.String
方法3:mysql类型,例如:varchar(50)
<columnname="name" sql-type="varchar(50)" />
*日期时间类型
date , 日期 java.util.Date , 对应jdbc类型:java.sql.Date
time , 时间 java.util.Date , 对应jdbc类型:java.sql.Time
timestamp,时间戳 java.util.Date (注意:时间戳随着数据更改变化), 对应jdbc类型:java.sql.Timestamp
项目使用:
1.字符串、long (date.getTime())、日期时间类型
2.使用数据的datetime 表示日期时间。
7.3属性和字段选择
*其他配置
access ,用于确定当前属性如何进行数据封装
property: 默认值,hibernate采用javabean属性 与 表字段进行对应。在javabean必须提供 getter/setter方法
field: hibernate采用 javabean 字段 与 表字段进行对应。 可以没有getter/setter方法
例如:private String username;
noop: 提供给hibernatehql使用,数据库没有对应字段。一般不使用。
precision 和 scale 给 oracle配置,在mysql没有作用。
precision配置数字位数
scale配置小数位数
例如:numeric(precision,scale) , 12.34 numeric(4,2)
<property name="name" access="property" precision="" scale=""></property>
7.4优化hibernate生成sql
*添加insert 和更新update
<property> 可以设置,允许当前属性是否在sql语句中 。默认值:trueinsert="false" 表示生产insert语句,没有当前字段。
update="false" 表示生产update语句,没有当前字段。
<property name="title" insert="false" update="false"></property>
<class> 设置动态 insert和update,默认值:false
dynamic-insert="true" 如果生产insert语句,属性内容为null,生产的sql语句中将没有该字段。
dynamic-update="true" 只有内容被修改才进行更新。默认更新所有。
注意:如果使用动态更新,数据必须是查询获得的,此时修改的内容将被更新,其他内容不变。
处理sql引用表示符
在SQL语法中,表示符是指用于为数据库表、视图、字段或索引等名字的字符串,常规表示符不包括空格,也不包含特殊字符,
因此无需使用引用符号。如果数据库表名或列名包含特殊字符,可以使用引用表示符(键盘~下面的字符)。
7.5派生属性
<class table="A"><property name="title" formula="(sql语句)"></property>
*利用<property>元素的formula属性,用来设置一个sql表达式,hibernate将根据它来计算出派生属性的值。
*派生属性内容,一般情况都是从数据库另一个张表B查询获得。
聚合函数:count()/max()/min()/avg()/sum()等
*sql语句要求,如果使用字段,默认从当前表A(配置文件描述的表)获得字段,如果要从B表中获得字段,必须使用表的别名。
8OID映射
8.1什么是OID
*java区分对象:hashCode(地址值)*数据库区分记录:主键primary key
*hibernate 通过OID确定是否相同。如果OID相同,对象就相同。OID取值为数据库主键的值。
new User().setUid(1) java是一个对象A,hibernate是一个PO对象C
new User().setUid(1) java是另一个对象B,hibernate是同一个PO对象C
*PO持久对象中的数据,对应 表中一条记录。
8.2配置OID
<id name="bid">
<generator class="native"></generator>
</id>
8.3基本设置
<id> 属性(attribute)配置
name: 标识持久化类 OID 的属性名
column: 设置标识属性所映射的数据列的列名(主键字段的名字).
unsaved-value:
若设定了该属性, Hibernate 会通过比较持久化类的 OID 值和该属性值来区分当前持久化类的对象是否为临时对象,在Hibernate3中几乎不再需要.
save或update方法使用依据String ,默认null,
如果使用unsaved-value="abc" ,当执行save方法,设置“abc”
相当于之前的null
type:
指定 Hibernate 映射类型. Hibernate 映射类型是 Java 类型与 SQL 类型的桥梁.
如果没有为某个属性显式设定映射类型, Hibernate 会运用反射机制先识别出持久化类的特定属性的 Java 类型,
然后自动使用与之对应的默认的 Hibernate 映射类型
Java 的基本数据类型和包装类型对应相同的 Hibernate 映射类型.
基本数据类型无法表达 null, 所以对于持久化类的 OID 推荐使用包装类型(integer,long,string等)
8.4主键生成策略
<generator> 主键生成策略,hibernate根据设置生成OID的值方案建议:native、uuid、assigned (identity、sequence)
9持久对象状态
*hibernate之后操作通过对象状态确定如何使用api*状态分类(3种):transient 瞬时态、persistent持久态、detached脱管态
瞬时态:session没有缓存数据(无持久化标识OID),数据库没有对应的数据。例如:new 对象
持久态:session缓存数据(存在持久化标识OID),数据库中最终将会有数据。例如:save(user)
脱管态:session没有缓存(存在持久化标识OID),数据库中有数据。例如:session.close() / new User().setUid(1)
删除态:给delete专门定义一个状态。(未官方)
*状态之间的转换
*瞬时态
瞬时态 --> 持久态
当执行save()
当执行saveOrUpdate() ,hibernate底层执行save
瞬时态 --> 脱管态
手动设置OID,如果OID对应的记录再数据不存在,之后操作将抛异常(欺骗)
*持久态
持久态 --> 瞬时态
当指定delete() --(存放问题--删除态)
持久态 --> 脱管态
session.close() 关闭,session不存在,缓存不存在
session.clear() 清除所有缓存。
session.evict(PO) 将指定对象从缓存移除。
*脱管态
脱管态 --> 瞬时态
手动删除OID
脱管态 --> 持久态
执行update
执行saveOrUpdate
*所有的查询结果,对象都是 持久态,及查询结果保存session。
对象的状态总结