一、什么是Hibernate?
Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架。
什么是关系型数据库?
数据采用表方式存储,表与表之间外键关联。(MySQL、Oracle、SQLServer、DB2)
什么是ORM?
Object Relational Mapping:对象关系映射
ORM就是通过将Java对象映射到数据库表,通过操作Java对象,就可以完成对数据表的操作。
Hibernate是完全ORM的,只需要对对象进行操作,就可以生成底层SQL语句。
流行的数据库框架:
1、JPA:Java Persistence API ,通过注解描述对象与数据表映射关系(只有接口规范)。
2、Hibernate:最流行的ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL,Hibernate实现JPA规范。
3、Mybatis:本是Apache的一个开源项目iBatis,支持普通SQL查询,存储过程和高级映射的优秀持久层框架。*Mybatis并不是完全ORM,需要在xml中配置SQL语句。
4、Apache DBUtils、Spring JDBCTemplate
SQL语句封装程度:Hibernate>MyBatis>Apache DBUtils 、Spring JDBCTemplate
二、为什么要使用Hibernate?
Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据库访问层繁琐的重复性代码。
Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了dao层编码工作。
Hibernate使用java的反射机制,而不是字节码增强程序类实现透明性。
Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系。
*Hibernate本身性能并不是很好,存在很多优化手段(一级缓存、二级缓存、查询缓存、抓取策略)
三、使用Hibernate框架快速入门
1、去 http://sourceforge.net/projects/hibernate/files/hibernate3/ 下载 hibernate3 开发包
hibernate 是 JBOSS 框架, JBOSS 是 EJB服务器, JBOSS 推出JBPM 工作流
***** hibernate 还有很多扩展技术 search 、 validator ....
2、目录结构
documentation:文档
lib:开发jar包
project:Hibernate源码
hibernate3.jar:hibernate框架开发核心jar包
3、导入jar包
hibernate3.jar (核心jar包)
lib/required/*.jar (6个)
lib/jpa/hibernate-jpa-2.0-api-1.0.1.Final.jar (用语JPA注解开发,web开发)
数据库驱动jar包
-----------------------------------------------------------------------------------------------------------
日志相关:
hibernate 3.x版本 默认采用日志技术 slf4j (即简单日志门面(SimpleLoggingFacadeforJava)) ,不是具体的日志解决方案,它只服务于各种各样的日志系统。
* 使用slf4j 好处,很容易整合其他日志技术
企业java开发,最主流日志技术log4j。
slf4j-api-1.6.1.jar没有日志实现,只是借口,整合log4j。
导入 slf4j-log4j12-1.7.2.jar (slf4j对log4j 框架整合 )
导入 log4j-1.2.16.jar (log4j的日志jar包 )
-------------------------------------------------------------------------
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
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4、编写数据表和实体类
create table customer(
id int primary key auto_increment,
name varchar(20),
age int ,
city varchar(20)
);
package lsq.hibernate.domain;
public class Customer {
private int id;
private String name;
private int age;
private String city;
public int getId() {
return id;
}
public void setId(int 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;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", age=" + age
+ ", city=" + city + "]";
}
}
完成实体类和数据表的映射配置
hibernate 完全ORM,只需要操作Customer类对象, 自动生成SQL 操作customer 表
1) 在类所有包,创建 类名.hbm.xml 文件 (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>
<!-- 1、类与表的映射 -->
<!--
name:类名
table:表名
catalog:数据库名
-->
<class name="lsq.hibernate.domain.Customer" table="customer" catalog="hibernate3day1">
<!-- 2、类中属性与表中数据列映射 -->
<!-- 主键 -->
<!--
name 属性名(类中)
column 列名 (表中)
type 类型
-->
<id name="id" column="id" type="int">
<!-- 主键策略identity主键自增长 -->
<generator class="native"></generator>
</id>
<!-- 普通属性 -->
<property name="name" column="name" type="java.lang.String" not-null="true"></property><!-- java类型 -->
<property name="age" column="age" type="int"></property>
<property name="city">
<column name="city" sql-type="varchar(20)"></column><!-- SQL类型 -->
</property>
</class>
</hibernate-mapping>
2)hibernate3.jar org/hibernate/hibernate-mapping-3.0.dtd
配置属性到列映射时,指定类型,类型有三种写法
第一种 java类型 java.lang.String
第二种 hibernate类型 string
第三种 SQL类型 varchar(20)
5、配置hibernate核心配置文件
在src下创建 hibernate.cfg.xml
规则参见 hibernate3.jar /org/hibernate/hibernate-configuration-3.0.dtd
配置hibernate基本属性,参考 解压目录/project/etc/hibernate.properties
1) JDBC连接属性
2)数据库方言
3)其它属性
4)加载hbm映射文件
<?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>
<!-- 配置会话工厂(hibernate核心对象,管理数据库连接池) -->
<session-factory>
<!-- 连接数据库JDBC四个基本连接参数 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate3day1</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 配置hibernate使用的数据库方言(方言解决不同数据库之间的区别) -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 其它属性 -->
<!-- 自动建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 在日志中输出SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL -->
<property name="hibernate.format_sql">true</property>
<!-- 加载hbm映射 -->
<mapping resource="lsq/hibernate/domain/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
6、 编程操作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();
7、 完成customer表增删改查操作
1) 使用 session对象 save方法 完成 insert 操作
session.save(customer);
测试代码:
@Test
//插入
public void testInsert(){
// 实例化配置对象,加载配置文件 hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
// 创建会话连接工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 创建会话
Session session = sessionFactory.openSession();
// 开启事务
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setName("Curry");
customer.setAge(28);
customer.setCity("奥克兰");
session.save(customer);
// 提交事务,释放资源
transaction.commit();
session.close();
sessionFactory.close();
}
console中自动生成的sql:
2) 使用 session对象 get或者load 完成根据 id 查询
(Customer) session.get(Customer.class, id);
测试代码:
@Test
//根据ID查询
public void testFindById(){
//实例化配置对象,加载配置文件hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
//创建会话工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
//创建会话
Session session = sessionFactory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
int id = 1;
Customer customer = (Customer) session.get(Customer.class, id);
System.out.println(customer);
//提交事务,释放资源
transaction.commit();
session.close();
sessionFactory.close();
}
结果:
3)使用session对象 update方法 完成 修改操作
(修改所有字段,如果不设置某个字段的值,则为空;为了解决这个问题,我们可以先从数据库中查询出来该对象,然后只修改其中一个字段,就达到了我们需要的效果)
session.update(customer); 根据id修改其它所有字段内容 (防止修改为null的情况)
@Test
public void testUpdate(){
//实例化配置对象,加载配置文件hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
//创建会话工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
//创建会话
Session session = sessionFactory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setId(1);
customer.setName("Curry");
customer.setAge(28);
customer.setCity("上海");
session.update(customer);
//提交事务,释放资源
transaction.commit();
session.close();
sessionFactory.close();
}
测试结果:
4) 使用session对象 delete方法 完成 删除操作
session.delete(customer); 根据id删除
@Test
public void testDelete(){
//实例化配置对象,加载配置文件hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
//创建会话工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
//创建会话
Session session = sessionFactory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setId(1);
session.delete(customer);
//提交事务,释放资源
transaction.commit();
session.close();
sessionFactory.close();
}
测试结果:
5) 查询所有数据
Session对象提供了两个方法可以获得Query对象 --- 完成查询
Query createQuery(String queryString) 接受HQL
SQLQuery createSQLQuery(String queryString) 接受SQL
* createQuery 返回Query对象,接收HQL查询语言 (Hibernate Query Language ) ---- 特点:语法类似SQL,面向类和属性的查询
* 使用HQL查询,面向类和属性,生成底层SQL 返回结果 封装类对象中
* 使用SQL查询,面向数据表,SQL无需生成,默认返回结果 每条记录 Object[] ------- 通过 addEntity(Customer.class) 指定将返回数据封装对象
HQL:
@Test
//查询所有(HQL)
public void testFindAllByHQL(){
//实例化配置对象,加载配置文件hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
//创建会话工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
//创建会话
Session session = sessionFactory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
//编写hql(面向类和属性的查询)
String hql = "from Customer";//这里Customer是类名,查询Customer类对应表所有数据
Query query = session.createQuery(hql);
List<Customer> list = query.list();
System.out.println(list);
//提交事务,释放资源
transaction.commit();
session.close();
sessionFactory.close();
}
测试结果:
SQL:
@Test
//查询所有(SQL)
public void testFindAllBySQL(){
//实例化配置对象,加载配置文件hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
//创建会话工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
//创建会话
Session session = sessionFactory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
//编写sql
String sql = "select * from customer";
SQLQuery sqlQuery = session.createSQLQuery(sql);
sqlQuery.addEntity(Customer.class);//将查询结果封装到Customer类对象中
List<Customer> list = sqlQuery.list();
System.out.println(list);
//提交事务,释放资源
transaction.commit();
session.close();
sessionFactory.close();
}
测试结果: