框架 day31 Hibernate入门(log4j简介,核心配置,映射配置,核心api,OID映射)

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框架,JBOSSEJB服务器,JBOSS推出JBPM工作流

企业主流 Hibernate 版本: hibernate3.x

最新hibernate版本4.x测试版,hibernate4hibernate3开发有很多不同

***** hibernate 还有很多扩展技术 searchvalidator  ....

下载 hibernate-distribution-3.6.10.Final-dist.zip 




*导入jar(n个)
%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  slf4jlog4j框架整合 )

导入 log4j-1.2.16.jar  log4j的日志jar包 )


============================================================================

2.2.1log4j简介

log4j 是企业主流日志技术  ,是Apache公司提供的 

1) 什么是日志技术,开发中为什么要用日志技术  
日志 : 在系统运行过程中,记录关键信息,记录错误异常信息的技术 
   *  区分 System.out 和 日志技术 
   *  System.out 向控制台输入信息,一定输出
   *  日志技术 存在级别,通过级别控制日志是否输出,输出的详细程度, 输出的目的地(控制台、文件、发送邮件)


使用日志: 主要用于开发过程中调试 和 项目上线后的维护(记录bug)


2) 使用log4j 通过配置文件 ,配置日志框架使用 
src/log4j.xml
src/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


方案1:数据库手动创建表(建议)
方案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修饰 (将无法生成代理对象进行优化)

应用程序通过po类与hibernate进行交互。


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 配置内容)

*每一个应用程序只能有一个实例(单例),类似Jdbc时学习的连接池
*线程安全的,不同的线程都可以获得不同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 关联起来后就具有了持久化的能力

*常用api
save()/persist() 、update() 、saveOrUpdate() 增加和修改对象
delete()  删除对象
get()/load()  根据主键查询
createQuery() / createSQLQuery() 数据库操作对象
createCriteria()  条件查询

*操作事务

如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务

Transaction transaction = session.beginTransaction();

4.5事务操作

*获得当前事务:session.getTransaction() 

*开启事务:beginTransaction()
*提交事务: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语句中 。默认值:true
insert="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语法中,表示符是指用于为数据库表、视图、字段或索引等名字的字符串,常规表示符不包括空格,也不包含特殊字符,
因此无需使用引用符号。如果数据库表名或列名包含特殊字符,可以使用引用表示符(键盘~下面的字符)。


类中增加(desc在数据库中为关键字,不加重音符会报错)
private String desc;
映射文件增加
<property name="desc" column="`desc`“
                                                                     type="text"/>


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。


对象的状态总结
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值