Hibernate框架概述什么是Hibernate?

框架:软件的半成品,完成部分代码的功能。

Hibernate:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思想来操作数据库。Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序中使用,也可以在Servlet/JSP的web应用程序中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。

为何要学习Hibernate?

Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了dao层编码工作。

HIbernate使用Java的反射机制,而不是字节码增强程序类实现透明性。

Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系。

ORM:Object Relational Mapping 对象关系映射

传统方式开发:

持久层:

编写SQL.执行SQL. String sql = “insert into 表 values (?,?,?...)”;

开发语言Java:面向对象.

数据库:MySQL(关系型的数据库.)

将Java中的实体类与数据库的关系表建立一个映射.就可以操作Java中对象,从而操作数据库.

Hibernate就是一个持久层的ORM的框架。

常见的持久层框架:

  • Hibernate:最流行的ORM框架,通过对象—关系映射配置,可以完全脱离底层SQL。
  • JPA:Java Persistence API. JPA通过JDK5.0注解或XML描述对象关系表的映射关系。(只有接口规范)
  • MyBatis:本是Apache的一个开源项目iBatis,支持普通的SQL查询,存储过程和高级映射的优秀持久层框架。
  • Apache DBUtils 、Spring JDBCTemplate

企业开发两种架构:

SSH:Struts2+Spring+Hibernate

SSI:SpringMVC+Spring+Ibatis

Hibernate版本:

Hibernate3.x版本和Hibernate4.x

企业中常用的还是Hibernate3.x

Hibernate日志记录

日志: 程序开发中的一些信息

常用信息输出:System.out.println(" ");

这种方式不好,原因如下:

如果输出的内容比较多,项目已经开发完毕,不想使用输出,需要输出每个类,将输出的代码注释。

日志:Hibernate中使用slf4j技术

slf4j:SLF4J,即简单门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。

  • 用于整合其他日志系统(在企业中常用的日志记录:log4J)
  • 是具体的日志记录方案

Log4J技术

开发中的日志操作

  • 开发阶段的调试信息
  • 运行时的日志记录(日志代码占代码总量的4%)

if (someCondition) {

System.out.println("someinformation.");}

Hibernate中使用Log4J的步骤:

(1)导入Log4J的jar包apache-log4j-1.2.16(在Hibernate中使用时还需要导入slf4J的jar包)

在Hibernate中使用时需要单独下载SLF4J的jar包

java示例 Hibernate java hibernate框架_apache

(2)编写Property文件(log4J的配置信息)参考模板在如下位置

Hibernate_HOME/project/etc 示例中可以将log4j.properties文件拷贝出来进行修改放在项目中的classPath即src下

java示例 Hibernate java hibernate框架_java示例 Hibernate_02

(3)在程序中获得logger对象,通过下列方法输出日志信息

  • public void debug(Object message);
  • public void info(Object message);
  • public void warn(Object message);
  • public void error(Object message);

利用信息级别确保日志信息在内容上和反映问题的严重程度上,是非常重要的。

  • fatal:非常严重的错误,导致系统终止。期望这类信息能立即显示在状态控制台上。
  • error:即普通错误,其它运行期错误或不是预期条件。期望这类信息能立即显示在状态控制台上。
  • warn:警告,使用了不赞成使用的API、非常拙劣的使用API,几乎就是错误,其它运行时不合需要和不合预期的状态但还没必要称为错误。期望这类信息能立即显示在状态控制台上。
  • info:普通信息。运行时产生有意义的事件。期望这类事件能立即显示在状态控制台上。
  • debug:系统流程中的细节信息。期望这类信息仅被写入log文件中。
  • trace:堆栈信息。期望这类信息仅被写入log文件中。

(4)配置文件(log4j.properties)

Log4J有三个主要部件:记录器(Loggers)、输出源(Appenders)、布局(Layouts)

组件简介:

记录器(loggers):用来配置日志输出级别,使用哪些输出源

* 格式:记录器=级别,输出源1,输出源2...

如 log4j.rootLogger=info,stdout info是日志级别,stdout是输出源名称

* log4j提供日志级别 由高到低:fatal(致命错误)、error(普通错误)、warn(警告)、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 :自定义布局格式

示例如下:

log4j.rootLogger=DEBUG, A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n

配置时的注意事项:

注意1、log4j.properties被放置到ClassPath所指定的目录下。 注意2、log4j的日志记录的优先级分为FATAL、ERROR、WARN、INFO、DEBUG、TRACE或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。

Log4J提供的输出源:

  • org.apache.log4j.ConsoleAppender(控制台)
  • org.apache.log4j.FileAppender(文件)
  • org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
  • org.apache.log4j.RollingFileAppender(文件到达指定大小时产生一个新文件)
  • org.apache.log4j.WriterAppender(将日志信息以流方式发送到任何地方)

Log4J提供的layout:

  • org.apache.log4j.HTMLLayout(以HTML表格形式布局)
  • org.apache.log4j.PatternLayout(可以灵活的自己指定布局模式)
  • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
  • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)

自定义布局的layout中的格式符:

%c:列出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名称空间。假设当前logger的名字空间是"a.b.c"

  • %c —>a.b.c
  • %c{2} —>b.c
  • %c{1} —>c
  • %20c(若名字空间长度小于20,则左边用空格填充)
  • %-20c(若名字空间小于20,则右边用空格填充)
  • %.30c(若名字空间长度超过30,截取多余字符)
  • %20.30c(若名字空间长度小于20,则左边用空格填充;若名字空间长度超过30,截取多余字符)
  • %-20.30c(若名字空间长度小于20,则右边用空格填充;若名字空间超过30,截取多余字符)

%C:列出调用logger的类的全名(包含包路径),假设当前类是".SomeClass"

  • %C —>.SomeClass %C{2}—>xyz.SomeClass

%d:显示日志记录时间,{<日期格式>} 使用ISO8601定义的日期格式

  • %d{yyyy/MM/dd HH:mm:ss,sss} —>2005/10/12 22:23:30,117
  • %d{ABSOLUTE} —>22:23:30,117
  • %d{DATE} —>12 Oct 2005 22:23:30,117
  • %d{ISO8601} —>2005-10-12 22:23:30,117

%F:显示调用logger的源文件名 %F —> MyClass.java

%l:输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数

  • %l —>MyClass.main(MyClass.java:129)

%L:显示调用logger的代码行 %L—> 129

%m:显示输出消息 %m —> This is a message for debug

%M:显示调用logger的方法名 %M —> main

%n:当前平台下的换行符 Windows平台下表示rn UNIX平台下表示n

%p:显示该条日志的优先级 %p —> INFO

%r:显示从程序启动到记录该条日志已经过去的毫秒数 %r —> 1215

%t:输出产生该日志事件的线程名 %t —> MyClass

%x:按NDC(Nested Diagnostic Context,线程堆栈) 假设某程序调用顺序是MyApp调用com.foo.Bar

%c %x - %m%n —> MyApp - Call com.foo.Bar. com.foo.Bar - Log in Bar MyApp - Return to MyApp.

%X:按MDC(Mapped Diagnostic Context,线程映射表)输出日志。通常用于多个客户端连接同一台服务器,方便服务器区分是哪个客户端访问留下的日志 %X{5} —> (记录代号为5的客户端记录)

%%:显示一个百分号 %% —> %

在Tomcat6下配置log4j的步骤 首先需要准备的文件为: 1.log4j.jar , 下载地址 : http://www.apache.org/dist/logging/log4j/1.2.15/apache-log4j-1.2.15.zip 2.log4j配置文件:log4j.properties 注意:日志级别不能太低,如果配置为debug的话,输出的日志信息太多,导致tomcat启动非常的慢。

获得logger 范例代码

package org.javaresearch.log4j;
import org.apache.log4j.*;
public class TestLog4J {   
static Logger log = Logger.getLogger(TestLog4J.class.getName());  
 public static void main(String args[]) {	    // logging的各种方法	  
  log.debug("Start of main()");  
 }
}

关于Log4J比较全面的配置

#应用于文件

log4j.appender.FILE=org.apache.log4j.FileAppender

log4j.appender.FILE.File=C:\file.log

log4j.appender.FILE.Append=false

log4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n #应用于控制台

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender

log4j.appender.CONSOLE.Target=System.out

log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

示例代码如下:

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{2}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout ,file

Log4JTest

package cn.test.log4j;

import org.apache.log4j.Logger;
import org.junit.Test;

/**
 * 日志记录的类:
 *
 */
public class Log4JTest {
	
	private Logger logger = Logger.getLogger(Log4JTest.class);
	
	@Test
	public void demo1(){
		logger.fatal("致命错误");
		logger.error("普通错误");
		logger.warn("警告信息");
		("普通信息");
		logger.debug("调试信息");
		logger.trace("堆栈信息");
	}
}

java示例 Hibernate java hibernate框架_操作系统_03

输出到日志文件

java示例 Hibernate java hibernate框架_java示例 Hibernate_04

Hibernate快速入门

第一步:下载Hibernate3.x的开发包(3.6.10)

http://sourceforge.net/projects/hibernate/files/hibernate3/

java示例 Hibernate java hibernate框架_apache_05

slf4j与其他日志框架的关系

java示例 Hibernate java hibernate框架_数据库_06

第二步:Hibernate框架目录结构

java示例 Hibernate java hibernate框架_java示例 Hibernate_07

目录说明如下:

documentation :Hibernate文档

lib :Hibernate开发的jar包

* bytecode :操作字节码的jar包

* jpa :Hibernate的实现JPA规范

* optional :Hibernate的可选jar包

* required :Hibernate必须导入的jar包

project :Hibernate提供的工程

第三步:创建一个工程:(Java工程)

导入相应的jar包:

* hibernate3.jar

* HIBERNATE_HOME / lib / required/*.jar

* HIBERNATE_HOME/lib/jpa/hibernate-jpa-2.0-api-1.0.1.Final.jar

* 导入日志记录的包:* log4j-1.2.16.jar* slf4j-log4j12-1.7.2.jar * 导入数据库驱动:

第四步:搭建环境(创建一个customer表与对应的持久化类)

java示例 Hibernate java hibernate框架_数据库_08

java示例 Hibernate java hibernate框架_运维_09

第五步:在Customer.class所在的目录创建映射文件

Customer.hbm.xml(类名.hbm.xml)

配置规则参考 hibernate2.jar org/hibernate/hibernate-mappong-3.0.dtd

查找位置如下:

java示例 Hibernate java hibernate框架_数据库_10

配置Customer.hbm.xml内容如下:

java示例 Hibernate java hibernate框架_apache_11

<?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>
	<!-- 配置类 和数据表 对应关系 -->
	<class name="cn.itcast.domain.Customer" table="customer" select-before-update="true">
		 <!-- 配置哪个属性 关联数据表主键 -->
		 <id name="id" column="id" type="integer">
		 	<!-- 主键生成策略 -->
		 	<generator class="identity"></generator>
		 </id>
		 <!-- 普通属性 -->
		 <property name="name" column="name" type="string"></property>
		 <!-- 如果属性名和列名相同 可以省略 column -->
		 <property name="age" type="integer" ></property>
		 <!-- 类型也可以使用默认生成规则,省略type -->
		 <property name="city"></property>
		 <property name="info"></property>
	</class>
</hibernate-mapping>

java、hibernate、sql类型对应关系

java示例 Hibernate java hibernate框架_操作系统_12

第六步:配置JDBC连接数据库基本属性

在src下创建hibernate.cfg.xml

规则参考hibernate3.jar /org/hibernate/hibernate-configuration-3.0.dtd

hibernate.cfg.xml内容配置如下:

java示例 Hibernate java hibernate框架_数据库_13

<?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>
	<!-- 会话连接工厂,建立数据库连接需要SessionFactory -->
	<session-factory>
		<!-- JDBC连接基本参数 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql:///hibernatetest</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">123</property>
		<!-- 配置数据库方言,便于生成一些与数据库相关SQL方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
		<!-- 可以根据需要自动创建数据表 -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		<!-- 将SQL语句 输出到控制台 -->
		<property name="hibernate.show_sql">true</property>
		<property name="hibernate.format_sql">true</property>
		
		<!-- JavaEE6 使用BeanValidator校验,需要设置校验模式-->
<!-- 		<property name="javax.persistence.validation.mode">none</property> -->
		
		<mapping resource="cn/itcast/domain/Customer.hbm.xml"></mapping>
	</session-factory>
</hibernate-configuration>

第七步:编程操作hibernate框架

// 实例化配置对象,加载配置文件 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();

Hibernate的CRUD操作

Hibernate操作一(插入数据)

插入数据 通过Session对象的save方法 Serializable save(Object object)

java示例 Hibernate java hibernate框架_apache_14

Hibernate操作二(修改数据)

修改数据 通过Session的update方法 void update(Object object)

java示例 Hibernate java hibernate框架_数据库_15

注意—修改有两种方式

方式一:手动创建对象的方式如下所示:

Customer customer = new Customer(); customer.setId(2); customer.setName("苍老师"); session.update(customer);

使用这种方式,如果手动创建的对象中 只对一部分属性赋值,那么剩余的属性将以默认值存入(不建议使用)

方式二:先查询再进行修改的方式(推荐使用)

Customer customer = (Customer) session.get(Customer.class, 1); customer.setName("凤姐"); session.update(customer);

Hibernate常用操作三(删除数据)

删除数据 通过Session的delete方法 void delete(Object object)

java示例 Hibernate java hibernate框架_操作系统_16

注意—删除记录也有两种方式

删除方式一:手动创建对象的方式

// 手动创建对象的方式 Customer customer = new Customer(); customer.setId(2); session.delete(customer);

方式二:先查询再删除的方式

Customer customer = (Customer)session.get(Customer.class, 1); session.delete(customer);

两种方式的区别:当只涉及到一个表时,没有明显的区别,但当涉及到多个有关系的表时就有区别了 手动创建对象的删除方式是不能配置级联删除的,而先查询再删除的方式是可以配置级联删除的

Hibernate常用操作四(根据主键查询数据)

根据主键查询 通过Session的get或load方法

  • Object get(Class clazz, Serializable id)
  • Object load(Class clazz, Serializable id)

java示例 Hibernate java hibernate框架_运维_17

* Customer customer = (Customer)session.get(Customer.class ,1); * Customer customer = (Customer)session.load(Customer.class,1);

get和load的区别(重点+面试题)

1、发送SQL的时机不同

* load这个方法采用了一个技术叫lazy延迟加载(懒加载)只有真正使用这个对象的数据的时候才发送SQL(对象的数据不包括主键 也就是说只查询主键时是不会发送SQL的)

* get方法是立即检索,当执行session.get()方法的时候,马上发送SQL语句进行查询。

2、返回的对象不同

* load方法返回的是代理对象。

* get方法返回的是真实的对象。

3、查询一个不存在的数据时抛出的异常不同

* load方法抛出异常:ObjectNotFoundException

* get方法抛出异常:NullPointException

Hibernate常用操作五(查询所有数据)

Hibernate框架查询数据 可以通过Query对象完成

Session对象提供了两个方法可以获得Query对象

  • Query createQuery(String queryString) 接受HQL
  • SQLQuery createSQLQuery(String queryString) 接受SQL

HQL—Hibernate Query Language 描写对象操作的一种查询语言

  • Query query=session.createQuery("from Customer");
  • 这里的Customer是类名

SQL—Structured Query Language 面向数据库查询语言

  • Query query = session.createSQLQuery("select * from customer");
  • 这里参数就是普通SQL语句

HQL查询结果会自动封装为Java对象

java示例 Hibernate java hibernate框架_apache_18

SQLQuery会将查询结果每条数据封装为一个Object[]

java示例 Hibernate java hibernate框架_操作系统_19

示例如下:

HQL:HQL:Hibernate Query Language.面向对象的写法:Query query = session.createQuery("from Customer where name = ?");query.setParameter(0, "苍老师");query.list(); QBC:Query By Criteria.(条件查询)Criteria criteria = session.createCriteria(Customer.class);criteria.add(Restrictions.eq("name", "凤姐"));List<Customer> list = criteria.list(); SQL:SQLQuery query = session.createSQLQuery("select * from customer");List<Object[]> list = query.list();SQLQuery query = session.createSQLQuery("select * from customer");query.addEntity(Customer.class);List<Customer> list = query.list();

Hibernate运行的流程图如下:

java示例 Hibernate java hibernate框架_操作系统_20

Hibernate常见配置及核心API

Hibernate体系结构及常见配置

java示例 Hibernate java hibernate框架_apache_21

  • Hibernate的持久化方案,将用户从原始的JDBC底层SQL访问中解放出来。
  • 用户无须关注底层数据库的操作,只要通过操作映射到数据表的Java对象,就可以对数据库进行增删改查。
  • Hibernate框架支持哦两种Hibernate属性配置方式:hibernate.properties和hibernate.cfg.xml。
  • 采用properties方式必须手动编程加载hbm文件或者持久化类
  • 采用xml配置方式,可以配置添加hbm文件

核心配置的两种方式进行配置: * 属性文件的配置: * hibernate.properties * 格式:key=value * hibernate.connection.driver_class=com.mysql.jdbc.Driver

***** 注意:没有办法在核心配置文件中加载映射文件.(必须手动编码的方式进行加载.) * XML格式文件配置: * hibernate.cfg.xml * 格式: <property name="hibernate.connection.username">root</property>

Hibernate核心配置常用属性

在project/etc/hibernate.properties中配置了hibernate常用的一些属性信息

核心配置中:

1、必须的配置

*连接数据库的4个基本参数:

hibernate.connection.driver_class 连接数据库驱动程序

hibernate.connection.url 连接数据库的URL

hibernate.connection.username 数据库用户名

hibernate.connection.password 数据库密码

*hibernate的方言

hibernate.dialect 操作数据的方言

2、可选的配置

hibernate.show_sql true 在控制台上输出SQL语句

hibernate.format_sql true 格式化控制台输出的SQL语句

hibernate.connection.autocommit true 事务是否自动提交

create/create-drop/update/validate

* create :每次执行的时候,创建一个新的表(如果以前有该表,将该表删除重新创建)一般测试的时候使用.

* create-drop:每次执行的时候,创建一个新的表,程序执行结束后将这个表删除掉了。一般测试的时候使用。

* update:如果数据库中没有表,创建一个新的表,如果有了,直接使用这个表。可以更新表的结构.

* validate:会使用原有的表,完成校验,校验映射文件与表中配置的字段是否一致,不一致报错

3、映射的配置

在核心配置文件中加载映射文件

* <mapping resource="cn/itcast/hibernate3/demo1/Customer.hbm.xml" />

* 使用手动编码的方式进行加载hbm.xml映射文件

configuration.addResource("cn/itcast/hibernate3/demo1/Customer.hbm.xml");

或configuration.addClass(Customer.class);

注意:在核心配置文件中加载映射文件时有一个小技巧

java示例 Hibernate java hibernate框架_运维_22

映射文件的配置

ORM:对象关系映射。需要在映射文件(命名格式:持久化类名.hbm.xml)中配置Java对象与表的映射。

* 配置类与表的映射:

* name:类的全路径

* table:表的名称(可以省略,若不写表名则使用类的名称作为表名)

<class name="cn.itcast.hibernate3.demo1.Order" table=”orders”></class>

* 配置普通属性与字段映射:

name="name" column="name" type="string" length="20" />

type:三种写法

* Java类型:java.lang.String

* Hibernate类型:string

* SQL类型:不能直接使用type属性,需要子标签<column>

* <column name="name" sql-type="varchar(20)" />

* 配置唯一标识与主键映射:

* 一个表中只有一个主键的形式

<id name="id" column="id">

<generator class="assigned"/> <!-- 生成策略-->

</id>

* 一个表对应多个主键形式:(复合主键)

<composite-id>

<key-property name="firstname" column="firstname" type="string" />

<key-property name="lastname" column="lastname" type="string" />

</composite-id>

* 关联关系

* 命名SQL

<query name="findAll"> from Customer </query>

<sql-query name="sqlFindAll" > select * from customer </sql-query>

Hibernate的核心API

Hibernate体系结构

java示例 Hibernate java hibernate框架_操作系统_23

Hibernate API简介 — Configuration类

Configuration类负责管理Hibernate的配置信息。包括如下内容:

  • 加载hibernate.properties 和hibernate.cfg.xml
  • 持久化类与数据表的映射关系( *.hbm.xml)

1、加载核心配置文件

创建Configuration的两种方式

hibernate.properties)

Configuration cfg = new Configuration(); // 手动加载hbm

hibernate.cfg.xml)

Configuration configuration = new Configuration().configure();

2、手动加载映射文件

第一种写法:通过Configuration对象的addResource方法添加hbm文件映射

// 加载位于cn.itcast.domain包下面Customer.hbm.xml文件

addResource("cn/itcast/domain/Customer.hbm.xml");

第二种写法:通过addClass添加持久化类,Hibernate会在类所在包自动搜索hbm映射文件

要求:映射文件名称要规范,类与映射文件在同一个包下

configuration.addClass(Customer.class);

Hibernate API简介—SessionFactory接口

Configuration对象根据当前的配置信息生成SessionFactory对象。

SessionFactory对象中保存了当前的数据库配置信息和所有映射关系以及预定义的SQL语句。

SessionFactory 对象是线程安全的。

SessionFactory还负责维护Hibernate的二级缓存。

  • Configuration configuration=new Configuration().configure();
  • SessionFactory sessionFactory = configuration.buildSessionFactory();

SessionFactory对象根据数据库信息,维护连接池,创建Session(相当于Connection)对象

  • Session session = sessionFactory.openSession();

构造SessionFactory很消耗资源,一般情况下一个应用只初始化一个

抽取HibernateUtils类用来提供Session对象

java示例 Hibernate java hibernate框架_apache_24

使用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>

Hibernate API简介—Session接口

相当于JDBC的Connection

Session是应用程序与数据库之间交互操作的一个单线程对象,是Hibernate运作的中心。

Session是线程不安全的。

所有持久化对象必须在session的管理下才可以进行持久化操作。

Session对象有一个一级缓存,显式执行flush之前,所有持久化操作的数据都缓存在session对象处。

持久化类与Session关联起来后就具有了持久化的能力。

Session维护了Hibernate的一级缓存。

常用方法如下:

save() / persist() :添加。

update :修改。

saveOrUpdate :增加和修改对象。

delete :删除对象。

get() / load() :根据主键查询。

createQuery() :创建一个Query接口,编写HQL语句。

createSQLQuery():创建一个SQLQuery接口,编写SQL语句 数据库操作对象。

createCriteria() :返回一个Criteria接口,条件查询。

Hibernate API简介—Transaction接口

代表数据库操作的事务对象

Transaction transaction = session.beginTransaction();

提供事务管理的方法:

  • commit():提交相关联的session实例。
  • rollback():撤销事务操作。
  • wasCommitted():检查事务是否提交。

如果没有开启事务,那么每个session的操作,都相当于一个独立的事务。注意:默认情况下这些独立的事务是不会提交的,都会进行回滚。

思考题:关羽和张飞的信息能否插入数据库。

java示例 Hibernate java hibernate框架_java示例 Hibernate_25

如果在Hibernate的核心配置文件中配置了事务自动提交,则会将关羽的信息插入数据库,张飞的信息不会被插入数据库。如果在核心配置文件中没有配置事务自动提交,则张飞和关羽的信息都不会被插入数据库。

Hibernate API简介— Query接口

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):设置本次返回结果的记录条数

HQL入门举例:

以from开始HQL语句,调用list方法返回 List<Customer>

  • from Customer 查询customer表所有数据

使用select 关键字 (查询部分对象属性)

  • select name from Customer 返回List<String>
  • select name,age from Customer 返回 List<Object[] >
  • select from Customer as c 为Customer实例起别名

使用where添加条件

from Customer as c where c.age > :age 其中:age是参数

java示例 Hibernate java hibernate框架_java示例 Hibernate_26

from Customer as c where c.age > ? 其中?是参数

java示例 Hibernate java hibernate框架_操作系统_27

Hibernate API简介—Criteria接口

Criteria是Hibernate提供的用于条件查询接口

Criteria criteria = session.createCriteria(Customer.class);

使用Criteria对象的步骤:

  • 获得Hibernate的Session对象
  • 通过Session获得Criteria对象
  • 通过Restrictions的静态方法创建Criterion条件对象
  • 向Criteria对象中添加Criterion查询条件
  • 执行Criteria的list() 或 uniqueResult() 获得结果

java示例 Hibernate java hibernate框架_java示例 Hibernate_28

Hibernate持久化配置和操作

Hibernate中的持久化类

Hibernate采用普通、传统的Java对象(POJO),作为持久化类,与数据表进行映射。

编写规则:

  • 提供一个无参数public访问控制符的构造器(无参构造函数,因为Hibernate要使用反射进行操作)
  • 提供一个标识属性,映射数据表主键字段。(Java区分两个对象是否是同一个使用地址,数据库区分两条记录是否一致使用主键,Hibernate中区分持久化对象是否是同一个则根据唯一标识)
  • 所有属性提供public访问控制符的set / get方法。(框架存取值的时候使用)
  • 标识属性应尽量使用基本数据类型的包装类型。
  • 不要使用final修饰(将无法生成代理对象进行优化)

注意:用final修饰的类是不能被继承的,无法生成代理对象(延迟加载的时候返回代理对象,延迟加载就会失效)

持久化对象的唯一标识OID

  • Java按地址区分同一个类的不同对象。
  • 关系数据库用主键区分同一条记录。
  • Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系。
  • 对象的OID和数据库的表的主键对应。为保证OID的唯一性,应该让Hibernate来为OID进行赋值。

区分自然主键与代理主键

java示例 Hibernate java hibernate框架_java示例 Hibernate_29

java示例 Hibernate java hibernate框架_操作系统_30

java示例 Hibernate java hibernate框架_数据库_31

持久化类属性用基本类型还是包装类型?

基本数据类型和包装类型对应hibernate的映射类型相同。

<property name="price" type="double" column="PRICE" />

基本类型可直接运算、无法表达null、数字类型的默认值是0.

包装类型默认值是null。当对于默认值有业务意义的时候需要使用包装类。

例如:Student类有一个int类型的scope属性,表示学生的考试分数.int类型的scope属性无法表达这样的业务需求: * 如果scope的属性为null,表示该学生的成绩是未知的,有可能得了100分,也有可能得了0分,只是暂时还不知道成绩 * 如果scope属性为0,表示学生考试成绩为0分. * 在上面的情况中必须使用包装类型

详解对象—关系映射 hbm文件

java示例 Hibernate java hibernate框架_apache_32

ID和generator属性说明

id:设定持久化类的OID和表的主键的映射。id标签有以下属性:

  • name:表示持久化类OID的属性名。
  • column:设置标识属性所映射的数据列的列名(主键字段的名称)。
  • unsaved-value:若设定了该属性,Hibernate会通过比较持久化类的OID和该属性值来区分当前持久化类的对象是否是临时对象,Hibernate3中几乎不再需要。
  • type:指定 Hibernate 映射类型. Hibernate 映射类型是 Java 类型与 SQL 类型的桥梁. 如果没有为某个属性显式设定映射类型, Hibernate 会运用反射机制先识别出持久化类的特定属性的 Java 类型, 然后自动使用与之对应的默认的 Hibernate 映射类型
  • Java 的基本数据类型和包装类型对应相同的 Hibernate 映射类型. 基本数据类型无法表达 null, 所以对于持久化类的 OID 推荐使用包装类型(integer,long,string等)

generator:设置持久化类指定标识符生成器。

  • class:指定使用标识符生成器全限定 类名或其缩写名。

主键生成策略

常用的几种标识符生成器以及相关描述如下:

increment :适用于代理主键。由Hibernate自动以递增的方式生成标识符,每次增量为1.

identity :适合代理主键。由底层数据库生成标识符。条件是数据库支持自动增长数据类型。

sequence :适用于代理主键。Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。

native :适用于代理主键。根据底层数据库对自动生成标识符的能力来选择identity、sequence、hilo。

uuid :适用于代理主键。Hibernate采用128位的UUID算法来生成标识符。该算法能够在网络环境中生成唯一的字符串标识符,这种策略并不流行,因为字符串类型的主键比整数类型的主键占用更多的数据库空间。

assigned :适用于自然主键。由Java程序员负责生成标识符。不能把setId()声明为private类型。尽量避免使用自然主键。

主键生成策略increment

increment标识符生成器

increment 标识符生成器由Hibernate以递增的方式为代理主键赋值。

java示例 Hibernate java hibernate框架_apache_33

Hibernate会先读取NEWS表中的主键的最大值,而接下来向NEWS表中插入记录时,就在max(id)的基础之上递增,增量为1(带走+1)

适用范围:

  • 由于increment生存标识符机制不依赖于底层数据库系统,因此它是适用于所有的数据库系统。
  • 适用于只有单个Hibernate应用进程访问同一个数据库的场合。因为会产生多线程问题,在集群下不要使用。
  • OID必须为long,int,或short类型,如果把OID定义为byte类型,在运行时就会抛出异常。

主键生成策略 identity

identity标识符生成器由底层数据库负责生成标识符,它要求底层数据库把主键定义为自动增长字段类型(加1带走)

java示例 Hibernate java hibernate框架_数据库_34

适用范围:

  • 由于identity生成标识符的机制依赖于底层数据库系统,因此要求底层数据库系统必须支持自动增长字段类型。支持自动增长字段类型的数据库包括:DB2,MySQL,MSSQLServer,Sybase等。
  • OID必须为long,int或short类型,如果把OID定义为byte类型,在运行时也会抛出异常。

主键生成策略 sequence

sequence标识符生成器利用底层数据库提供的序列来生成标识符。

java示例 Hibernate java hibernate框架_java示例 Hibernate_35

Hibernate在持久化一个NEWS对象时,先从底层数据库的news_seq序列中获得一个唯一的标识号,再把它作为主键值。

适用范围:

  • 由于sequence生成标识符的机制依赖于底层数据库系统的序列,因此,要求底层数据库系统必须支持序列。支持序列的数据库包括DB2、Oracle等。
  • OID必须为long、int、或short类型,如果把OID定义为byte类型,在运行时也会抛出异常。

主键生成策略 native

native标识符生成器依赖底层数据库对自动生成标识符的支持能力,来选择identity,sequence或hilo标识符生成器

java示例 Hibernate java hibernate框架_java示例 Hibernate_36

适用范围:

  • 由于native能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此很适合用于跨数据库平台开发。
  • OID必须为long、int、或short类型,如果把OID定义为byte类型,在运行时也会抛出异常。

主键生成策略 uuid

uuid 32位标识符生成器

java示例 Hibernate java hibernate框架_java示例 Hibernate_37

Hibernate会产生不重复的32位字符作为主键。

主键生成策略 assigned

assigned标识符生成器— 用于映射单个自然主键。

假如CUSTOMER表没有定义ID代理主键,而是以NAME字段作为主键,那么相应的,在Customer类中不必定义id属性,Customer类的OID为name属性,它的映射代码如下:

java示例 Hibernate java hibernate框架_操作系统_38

映射复合主键

java示例 Hibernate java hibernate框架_操作系统_39

具体代码示例演示Hibernate:

项目如下:

java示例 Hibernate java hibernate框架_apache_40

java示例 Hibernate java hibernate框架_数据库_41

Customer

package cn.itcast.hibernate3.demo1;
/**
 * 实体类对象
 *
 */
public final class Customer {
	private Integer id;
	//private String id;
	private String name;
	private int age;

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		 = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Customer [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
}

HibernateTest1

package cn.itcast.hibernate3.demo1;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

/**
 * Hibernate入门案例的测试:
 *
 *
 */
public class HibernateTest1 {
	
	@Test
	// 查询所有记录:SQL
	public void demo7(){
		// 1.加载核心配置文件
		Configuration configuration = new Configuration().configure();
		// 2.构建Session工厂
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通过工厂创建Session
		Session session = sessionFactory.openSession();
		// 4.开启事务
		Transaction tx = session.beginTransaction();
		
		// 5.操作
		// 查询所有:SQL
		/*SQLQuery query = session.createSQLQuery("select * from customer");
		List<Object[]> list = query.list();
		
		for (Object[] objs : list) {
			System.out.println(Arrays.toString(objs));
		}*/
		SQLQuery query = session.createSQLQuery("select * from customer");
		query.addEntity(Customer.class);
		List<Customer> list = query.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		// 6.事务提交
		tx.commit();
		// 7.释放资源
		session.close();
		sessionFactory.close();
		
	}
	
	@Test
	// 查询所有:QBC
	public void demo6(){
		// 1.加载核心配置文件
		Configuration configuration = new Configuration().configure();
		// 2.构建Session工厂
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通过工厂创建Session
		Session session = sessionFactory.openSession();
		// 4.开启事务
		Transaction tx = session.beginTransaction();
		
		// 5.操作:
		// 查询所有 :QBC.
		/*Criteria criteria = session.createCriteria(Customer.class);
		List<Customer> list = criteria.list();*/
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.add(Restrictions.eq("name", "凤姐"));
		List<Customer> list = criteria.list();
		
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		// 6.事务提交
		tx.commit();
		// 7.释放资源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 查询所有:HQL.
	// HQL:Hibernate Query Language.Hibernate查询语言.面向对象的查询.
	public void demo5(){
		// 1.加载核心配置文件
		Configuration configuration = new Configuration().configure();
		// 手动编码加载映射文件:
		// configuration.addResource("cn/itcast/hibernate3/demo1/Customer.hbm.xml");
		// configuration.addClass(Customer.class);
		// 2.构建Session工厂
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通过工厂创建Session
		Session session = sessionFactory.openSession();
		// 4.开启事务
		Transaction tx = session.beginTransaction();	
		
		// 5.操作
		// 1.查询所有的客户
		/*Query query = session.createQuery("from Customer");
		List<Customer> list = query.list();*/
		// 2.按名称查询
		/*Query query = session.createQuery("from Customer where name = ?");
		query.setParameter(0, "苍老师");*/
		Query query = session.createQuery("from Customer where name = :aaa");
		query.setParameter("aaa", "苍老师");
		List<Customer> list = query.list();
		
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		// 6.事务提交
		tx.commit();
		// 7.释放资源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 删除记录
	public void demo4(){
		// 1.加载核心配置文件
		Configuration configuration = new Configuration().configure();
		// 2.构建Session工厂
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通过工厂创建Session
		Session session = sessionFactory.openSession();
		// 4.开启事务
		Transaction tx = session.beginTransaction();	
		
		// 5.操作
		// 删除记录有两种方式:
		// 5.1手动创建对象的方式
		/*Customer customer = new Customer();
		customer.setId(2);
		
		session.delete(customer);*/
		
		// 5.2先查询在删除的方式
		Customer customer = (Customer)session.get(Customer.class, 1);
		session.delete(customer);
		
		// 6.事务提交
		tx.commit();
		// 7.释放资源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 修改记录
	public void demo3(){
		// 1.加载核心配置文件
		Configuration configuration = new Configuration().configure();
		// 2.构建Session工厂
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通过工厂创建Session
		Session session = sessionFactory.openSession();
		// 4.开启事务
		Transaction tx = session.beginTransaction();	
		
		// 5.操作:
		// 修改记录:两种方式可以进行修改.
		// 5.1手动创建对象的方式
		/*Customer customer = new Customer();
		customer.setId(2);
		customer.setName("苍老师");
		
		session.update(customer);*/
		
		// 5.2先查询在修改的方式
		Customer customer = (Customer) session.get(Customer.class, 1);
		customer.setName("凤姐");
		
		session.update(customer);
		
		// 6.事务提交
		tx.commit();
		// 7.释放资源
		session.close();
		sessionFactory.close();
	}
	
	@Test
	// 按id进行查询
	// (*****面试题)get和load方法区别
	public void demo2(){
		// 1.加载核心配置文件
		Configuration configuration = new Configuration().configure();
		// 2.构建Session工厂
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.通过工厂创建Session
		Session session = sessionFactory.openSession();
		// 4.开启事务
		Transaction tx = session.beginTransaction();
		// 5.操作
		// 根据id进行查询:
		// get方法进行查询
		Customer customer = (Customer) session.get(Customer.class, 100); // 马上发生一条SQL进行查询
		
		System.out.println(customer);
		
		// load方法进行查询
		//Customer customer = (Customer) session.load(Customer.class, 100); // 没有发送SQL
		
		//System.out.println(customer);// 发送SQL.
		
		// 6.事务提交
		tx.commit();
		// 7.释放资源
		session.close();
		sessionFactory.close();
		
	}
	
	@Test
	// 保存记录
	public void demo1(){
		// 1.Hiberante框架加载核心配置文件(有数据库连接信息)
		Configuration configuration = new Configuration().configure();
		// 2.创建一个SessionFactory.(获得Session--相当连接对象)
		SessionFactory sessionFactory = configuration.buildSessionFactory();
		// 3.获得Session对象.
		Session session = sessionFactory.openSession();
		// 4.默认的情况下,事务是不自动提交.
		Transaction tx = session.beginTransaction();
		// 5.业务逻辑操作
		
		// 向数据库中插入一条记录:
		Customer customer = new Customer();
		customer.setName("苍老师");
		customer.setAge(38);
		
		session.save(customer);
		
		// 6.事务提交
		tx.commit();
		// 7.释放资源
		session.close();
		sessionFactory.close();
	}
}

Customer.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">
    
<hibernate-mapping>
	<!-- 建立类与表的映射 -->
	<!-- class标签:用于映射类与表的关系 name :类的全路径  table:表名称 -->
	<class name="cn.itcast.hibernate3.demo1.Customer" table="customer">
		<!-- 建立类中属性与表中的字段映射 -->
		<!-- 唯一标识 -->
		<!-- 使用id的标签 配置唯一属性 -->
		<!-- 在<id>标签中配置一个主键的生成策略. -->
		<id name="id" column="id">
			<generator class="assigned"/>
		</id>
		
		<!-- 普通属性 -->
		<!-- property标签:映射类中的普通属性 name:类中的属性名称, column:表中字段名称 -->
		<!-- 
			type:三种写法
				* Java类型		:java.lang.String
				* Hibernate类型	:string
				* SQL类型		:不能直接使用type属性,需要子标签<column>
					* <column name="name" sql-type="varchar(20)"/>
		 -->
		<property name="name" column="name" type="string" length="20"/>
		<property name="age" column="age"/>
		
		
	</class>
	

</hibernate-mapping>

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">

<hibernate-configuration>
<session-factory>
	<!-- 必须去配置的属性 -->
	<!-- 配置数据库连接的基本信息: -->
	<property name="hibernate.connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<property name="hibernate.connection.url">
		jdbc:mysql:///hibernate3_day01
	</property>
	<property name="hibernate.connection.username">root</property>
	<property name="hibernate.connection.password">123</property>
	<!-- Hibernate的方言 -->
	<!-- 生成底层SQL不同的 -->
	<property name="hibernate.dialect">
		org.hibernate.dialect.MySQLDialect
	</property>

	<!-- 可选的属性 -->
	<!-- 显示SQL -->
	<property name="hibernate.show_sql">true</property>
	<!-- 格式化SQL -->
	<property name="hibernate.format_sql">true</property>
	
	<property name="hibernate.connection.autocommit">false</property>
	<!-- hbm:映射 to DDL: create drop alter -->
	<property name="hibernate.hbm2ddl.auto">update</property>

	<!-- 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>

	<!-- 通知Hibernate加载那些映射文件 -->
	<mapping resource="cn/itcast/hibernate3/demo1/Customer.hbm.xml" />

</session-factory>
</hibernate-configuration>

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{2}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout ,file

HibernateUtils

package cn.itcast.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hibernate抽取工具类
 * 
 *
 */
public class HibernateUtils {
	private static Configuration configuration;
	private static SessionFactory sessionFactory;
	
	static{
		configuration = new Configuration().configure();
		sessionFactory = configuration.buildSessionFactory();
	}
	
	public static Session openSession(){
		return sessionFactory.openSession();
	}
	
	public static void main(String[] args) {
		openSession();
	}
}

package cn.itcast.hibernate3.demo1;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

import cn.itcast.utils.HibernateUtils;

/**
 * 抽取了Hibernate的工具类的使用
 *
 */
public class HibernateTest2 {
	@Test
	// 保存数据
	public void demo1(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = new Customer();
		customer.setName("芙蓉");
		customer.setAge(26);
		
		session.save(customer);
		
		tx.commit();
		session.close();
	}
	
	@Test
	// 保存或更新()
	public void demo2(){
		// 获得SEssion
		Session session = HibernateUtils.openSession();
		// 开启事务
		Transaction tx = session.beginTransaction();
		
		/*Customer customer = new Customer();
		customer.setName("冠希");
		customer.setAge(34);
		
		session.saveOrUpdate(customer);*/
		
		Customer customer = new Customer();
		customer.setName("冠希");
		customer.setAge(34);
		
		session.saveOrUpdate(customer);
		
		System.out.println(tx.wasCommitted());
		
		// 事务提交
		tx.commit();
		
		System.out.println(tx.wasCommitted());
		// session关闭
		session.close();
	}
	
	@Test
	// 保存数据
	public void demo3(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = new Customer();
		customer.setName("芙蓉");
		customer.setAge(26);
		
		Serializable id = session.save(customer);
		
		// session.get(Customer.class, id);
		
		session.update(customer);
		
		tx.commit();
		session.close();
	}
	
	@Test
	// 测试程序
	public void demo4(){
		Session session = HibernateUtils.openSession();
		
		Customer customer = new Customer();
		customer.setName("关羽");
		customer.setAge(26);
		
		session.save(customer);
		
		int d = 10 / 0;
		
		Customer customer2 = new Customer();
		customer2.setName("张飞");
		customer2.setAge(26);
		
		session.save(customer2);
		
		session.close();
	}
	
	@Test
	// HQL:
	public void demo5(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// 1.简单查询
		// List<Customer> list = session.createQuery("from Customer").list();
		
		// 2.条件查询:
		// List<Customer> list = session.createQuery("from Customer where name = ?").setParameter(0, "芙蓉").list();
		
		// 3.分页查询:select * from customer limit a,b; a:从哪开始  b:每页显示记录数.
		Query query = session.createQuery("from Customer");
		query.setFirstResult(3);
		query.setMaxResults(3);
		
		List<Customer> list = query.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		tx.commit();
		session.close();
	}
	
	@Test
	// QBC:
	public void demo6(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		// 1.简单查询
		//List<Customer> list = session.createCriteria(Customer.class).list();
		
		// 2.条件查询:
		/*Criteria criteria = session.createCriteria(Customer.class);
		criteria.add(Restrictions.eq("name","芙蓉"));
		List<Customer> list = criteria.list();*/
		
		// 3.分页查询:
		Criteria criteria = session.createCriteria(Customer.class);
		criteria.setFirstResult(3);
		criteria.setMaxResults(3);
		List<Customer> list = criteria.list();
		for (Customer customer : list) {
			System.out.println(customer);
		}
		
		tx.commit();
		session.close();
	}
	
	@Test
	// 演示错误:(注意:)
	public void demo7(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = (Customer) session.get(Customer.class, 10);
		
		Customer customer2 = new Customer();
		customer.setId(10);
		customer.setName("张飞");
		session.update(customer2);
		
		tx.commit();
		session.close();
	}
	
	@SuppressWarnings("unused")
	@Test
	// 演示持久化类为final情况
	public void demo8(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = (Customer) session.load(Customer.class, 10);
		
		tx.commit();
		session.close();
	}
}

HibernateTest3

package cn.itcast.hibernate3.demo1;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.itcast.utils.HibernateUtils;

/**
 * 主键生成策略
 *
 */
public class HibernateTest3 {
	
	@Test
	// 演示increment的问题:
	public void demo1(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = new Customer();
		customer.setName("芙蓉");
		customer.setAge(26);
		
		session.save(customer);
		
		tx.commit();
		session.close();
	}
	
	@Test
	// 演示increment的问题:
	public void demo2(){
		Session session = HibernateUtils.openSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = new Customer();
		// customer.setId(100);
		customer.setName("凤姐");
		customer.setAge(26);
		
		session.save(customer);
		
		tx.commit();
		session.close();
	}
}

Log4JTest

package cn.itcast.log4j;

import org.apache.log4j.Logger;
import org.junit.Test;

/**
 * 日志记录的类:
 */
public class Log4JTest {
	
	private Logger logger = Logger.getLogger(Log4JTest.class);
	
	@Test
	public void demo1(){
		logger.fatal("致命错误");
		logger.error("普通错误");
		logger.warn("警告信息");
		("普通信息");
		logger.debug("调试信息");
		logger.trace("堆栈信息");
	}
}