首页 > 代码库 > JAVAWEB开发之Hibernate详解(一)——Hibernate的框架概述、开发流程、CURD操作和核心配置与API以及Hibernate日志的使用
JAVAWEB开发之Hibernate详解(一)——Hibernate的框架概述、开发流程、CURD操作和核心配置与API以及Hibernate日志的使用
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 对象关系映射
传统方式开发:
输出到日志文件
HibernateTest2
- 持久层:
- 编写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("some information.");
}
}
Hibernate中使用Log4J的步骤:
(1)导入Log4J的jar包apache-log4j-1.2.16(在Hibernate中使用时还需要导入slf4J的jar包)
在Hibernate中使用时需要单独下载SLF4J的jar包
(2)编写Property文件(log4J的配置信息)参考模板在如下位置
Hibernate_HOME/project/etc 示例中可以将log4j.properties文件拷贝出来进行修改放在项目中的classPath即src下
(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.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
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级别的日志信息将不被打印出来。
注意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的类的全名(包含包路径),假设当前类是"org.apache.xyz.SomeClass"
- %C —>org.apache.xyz.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.
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启动非常的慢。
首先需要准备的文件为:
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
Log4JTestpackage 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.info("普通信息");
logger.debug("调试信息");
logger.trace("堆栈信息");
}
}
输出到日志文件
Hibernate快速入门
第一步:下载Hibernate3.x的开发包(3.6.10)
http://sourceforge.net/projects/hibernate/files/hibernate3/
slf4j与其他日志框架的关系
第二步:Hibernate框架目录结构
目录说明如下:
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
* 导入数据库驱动:
* log4j-1.2.16.jar
* slf4j-log4j12-1.7.2.jar
* 导入数据库驱动:
第四步:搭建环境(创建一个customer表与对应的持久化类)
第五步:在Customer.class所在的目录创建映射文件
Customer.hbm.xml(类名.hbm.xml)
配置规则参考 hibernate2.jar org/hibernate/hibernate-mappong-3.0.dtd
查找位置如下:
配置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="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类型对应关系
第六步:配置JDBC连接数据库基本属性
在src下创建hibernate.cfg.xml
规则参考hibernate3.jar /org/hibernate/hibernate-configuration-3.0.dtd
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>
<!-- 会话连接工厂,建立数据库连接需要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();
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)
Hibernate操作二(修改数据)
修改数据 通过Session的update方法 void update(Object object)
注意—修改有两种方式
方式一:手动创建对象的方式如下所示:
Customer customer = new Customer();
customer.setId(2);
customer.setName("苍老师");
session.update(customer);
customer.setId(2);
customer.setName("苍老师");
session.update(customer);
使用这种方式,如果手动创建的对象中 只对一部分属性赋值,那么剩余的属性将以默认值存入(不建议使用)
方式二:先查询再进行修改的方式(推荐使用)
Customer customer = (Customer) session.get(Customer.class, 1);
customer.setName("凤姐");
session.update(customer);
customer.setName("凤姐");
session.update(customer);
Hibernate常用操作三(删除数据)
删除数据 通过Session的delete方法 void delete(Object object)
注意—删除记录也有两种方式
删除方式一:手动创建对象的方式
// 手动创建对象的方式
Customer customer = new Customer();
customer.setId(2);
session.delete(customer);
Customer customer = new Customer();
customer.setId(2);
session.delete(customer);
方式二:先查询再删除的方式
Customer customer = (Customer)session.get(Customer.class, 1);
session.delete(customer);
session.delete(customer);
两种方式的区别:当只涉及到一个表时,没有明显的区别,但当涉及到多个有关系的表时就有区别了 手动创建对象的删除方式是不能配置级联删除的,而先查询再删除的方式是可以配置级联删除的
Hibernate常用操作四(根据主键查询数据)
根据主键查询 通过Session的get或load方法
- Object get(Class clazz, Serializable id)
- Object load(Class clazz, Serializable id )
* Customer customer = (Customer)session.get(Customer.class ,1);
* Customer customer = (Customer)session.load(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对象
SQLQuery会将查询结果每条数据封装为一个Object[]
示例如下:
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();
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运行的流程图如下:
Hibernate常见配置及核心API
Hibernate体系结构及常见配置
- 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
* 属性文件的配置:
* hibernate.properties
* 格式: key=value
* hibernate.connection.driver_class=com.mysql.jdbc.Driver
***** 注意:没有办法在核心配置文件中加载映射文件.(必须手动编码的方式进行加载.)
* XML格式文件配置:
* hibernate.cfg.xml
* 格式:
<property name="hibernate.connection.username">root</property>
* 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 事务是否自动提交
hibernate.hbm2ddl.auto 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);
注意:在核心配置文件中加载映射文件时有一个小技巧
映射文件的配置
ORM:对象关系映射。需要在映射文件(命名格式:持久化类名.hbm.xml)中配置Java对象与表的映射。
* 配置类与表的映射:
* name:类的全路径
* table:表的名称(可以省略,若不写表名则使用类的名称作为表名)
<class name="cn.itcast.hibernate3.demo1.Order" table=”orders”></class>
* 配置普通属性与字段映射:
<property 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体系结构
Hibernate API简介 — Configuration类
Configuration类负责管理Hibernate的配置信息。包括如下内容:
- 加载hibernate.properties 和hibernate.cfg.xml
- 持久化类与数据表的映射关系( *.hbm.xml)
1、加载核心配置文件
创建Configuration的两种方式
方式一:加载属性文件(hibernate.properties)
Configuration cfg = new Configuration(); // 手动加载hbm
方式二:加载xml文件(hibernate.cfg.xml)
Configuration configuration = new Configuration().configure();
2、手动加载映射文件
第一种写法:通过Configuration对象的addResource方法添加hbm文件映射
// 加载位于cn.itcast.domain包下面Customer.hbm.xml文件
configuration.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对象
使用C3P0连接池
引入c3p0-0.9.1.jar
在hibernate.cfg.xml文件中增加如下配置:
<!-- C3P0连接池设定-->
<!-- 使用c3po连接池 配置连接池提供的供应商-->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider </property>
<!-- 使用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>
<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的操作,都相当于一个独立的事务。注意:默认情况下这些独立的事务是不会提交的,都会进行回滚。
思考题:关羽和张飞的信息能否插入数据库。
如果在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 c.name from Customer as c 为Customer实例起别名
使用where添加条件
from Customer as c where c.age > :age 其中:age是参数
from Customer as c where c.age > ? 其中?是参数
Hibernate API简介—Criteria接口
Criteria是Hibernate提供的用于条件查询接口
Criteria criteria = session.createCriteria(Customer.class);
使用Criteria对象的步骤:
- 获得Hibernate的Session对象
- 通过Session获得Criteria对象
- 通过Restrictions的静态方法创建Criterion条件对象
- 向Criteria对象中添加Criterion查询条件
- 执行Criteria的list() 或 uniqueResult() 获得结果
Hibernate持久化配置和操作
Hibernate中的持久化类
Hibernate采用普通、传统的Java对象(POJO),作为持久化类,与数据表进行映射。
编写规则:
- 提供一个无参数public访问控制符的构造器(无参构造函数,因为Hibernate要使用反射进行操作)
- 提供一个标识属性,映射数据表主键字段。(Java区分两个对象是否是同一个使用地址,数据库区分两条记录是否一致使用主键,Hibernate中区分持久化对象是否是同一个则根据唯一标识)
- 所有属性提供public访问控制符的set / get方法。(框架存取值的时候使用)
- 标识属性应尽量使用基本数据类型的包装类型。
- 不要使用final修饰(将无法生成代理对象进行优化)
注意:用final修饰的类是不能被继承的,无法生成代理对象(延迟加载的时候返回代理对象,延迟加载就会失效)
持久化对象的唯一标识OID
- Java按地址区分同一个类的不同对象。
- 关系数据库用主键区分同一条记录。
- Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系。
- 对象的OID和数据库的表的主键对应。为保证OID的唯一性,应该让Hibernate来为OID进行赋值。
区分自然主键与代理主键
持久化类属性用基本类型还是包装类型?
基本数据类型和包装类型对应hibernate的映射类型相同。
<property name="price" type="double" column="PRICE" />
基本类型可直接运算、无法表达null、数字类型的默认值是0.
包装类型默认值是null。当对于默认值有业务意义的时候需要使用包装类。
例如:Student类有一个int类型的scope属性,表示学生的考试分数.int类型的scope属性无法表达这样的业务需求:
* 如果scope的属性为null,表示该学生的成绩是未知的,有可能得了100分,也有可能得了0分,只是暂时还不知道成绩
* 如果scope属性为0,表示学生考试成绩为0分.
* 在上面的情况中必须使用包装类型
* 如果scope的属性为null,表示该学生的成绩是未知的,有可能得了100分,也有可能得了0分,只是暂时还不知道成绩
* 如果scope属性为0,表示学生考试成绩为0分.
* 在上面的情况中必须使用包装类型
详解对象—关系映射 hbm文件
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以递增的方式为代理主键赋值。
Hibernate会先读取NEWS表中的主键的最大值,而接下来向NEWS表中插入记录时,就在max(id)的基础之上递增,增量为1(带走+1)
适用范围:
- 由于increment生存标识符机制不依赖于底层数据库系统,因此它是适用于所有的数据库系统。
- 适用于只有单个Hibernate应用进程访问同一个数据库的场合。因为会产生多线程问题,在集群下不要使用。
- OID必须为long,int,或short类型,如果把OID定义为byte类型,在运行时就会抛出异常。
主键生成策略 identity
identity标识符生成器由底层数据库负责生成标识符,它要求底层数据库把主键定义为自动增长字段类型(加1带走)
适用范围:
- 由于identity生成标识符的机制依赖于底层数据库系统,因此要求底层数据库系统必须支持自动增长字段类型。支持自动增长字段类型的数据库包括:DB2,MySQL,MSSQLServer,Sybase等。
- OID必须为long,int或short类型,如果把OID定义为byte类型,在运行时也会抛出异常。
主键生成策略 sequence
sequence标识符生成器利用底层数据库提供的序列来生成标识符。
Hibernate在持久化一个NEWS对象时,先从底层数据库的news_seq序列中获得一个唯一的标识号,再把它作为主键值。
适用范围:
- 由于sequence生成标识符的机制依赖于底层数据库系统的序列,因此,要求底层数据库系统必须支持序列。支持序列的数据库包括DB2、Oracle等。
- OID必须为long、int、或short类型,如果把OID定义为byte类型,在运行时也会抛出异常。
主键生成策略 native
native标识符生成器依赖底层数据库对自动生成标识符的支持能力,来选择identity,sequence或hilo标识符生成器
适用范围:
- 由于native能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此很适合用于跨数据库平台开发。
- OID必须为long、int、或short类型,如果把OID定义为byte类型,在运行时也会抛出异常。
主键生成策略 uuid
uuid 32位标识符生成器
Hibernate会产生不重复的32位字符作为主键。
主键生成策略 assigned
assigned标识符生成器— 用于映射单个自然主键。
假如CUSTOMER表没有定义ID代理主键,而是以NAME字段作为主键,那么相应的,在Customer类中不必定义id属性,Customer类的OID为name属性,它的映射代码如下:
映射复合主键
具体代码示例演示Hibernate:
项目如下:
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) {
this.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 + "]";
}
}
HibernateTest1package 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();
}
}
HibernateTest3package 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();
}
}
Log4JTestpackage 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.info("普通信息");
logger.debug("调试信息");
logger.trace("堆栈信息");
}
}
JAVAWEB开发之Hibernate详解(一)——Hibernate的框架概述、开发流程、CURD操作和核心配置与API以及Hibernate日志的使用
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。