是处理对象和关系模型之间的转换,只是对JDBC做了一层封装
优点:
1.代码简单,操作便利
2.直接面向对象操作
3.提供世界级数据缓存(一级缓存,二级缓存)
4.数据库移植性强
缺点:
1.不能干预sql语句的生成
2.如果对sql语句的优化要求比较高,不适合用
3.如果表中数据量过大(上亿)也不适用.
2.创建第一个Hibernate项目
(1).创建java项目
(2)下载hibernate的jar包,并加载到项目中
一般只需要lib/required文件夹中的jar包即可(核心jar包),别忘了加载相关数据库的jar包
(3)创建数据库(以mysql为例)
CREATE TABLE `t_student` (
`sid` bigint(20) NOT NULL AUTO_INCREMENT,
`sname` varchar(20) DEFAULT NULL,
`sage` int(11) DEFAULT NULL,
`sgender` varchar(5) DEFAULT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
(4)对应数据库,在项目中创建相关持久化类
package org.zy._01_hibernate.domain;
/**
*创建持久化类
*/
public class Student {
private Long id;
private String name;
private Integer age;
private String gender;
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age
+ ", gender=" + gender + "]";
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
(5)创建映射配置文件(xml文件)
一般以.hbm.xml为后缀.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 映射文件 -->
<hibernate-mapping package="org.zy._01_hibernate.domain">
<!--配置持久化的对象-->
<!-- name为类的全限定名,如果package有值则为简写,table为数据库中对应的表名 -->
<class name="Student" table="t_student">
<!-- 主键信息 type为hibernate的类型名或者java的全限定名(可以省略)-->
<id name="id" column="sid" type="long">
<!-- 主键生成策略 -->
<generator class="native"/>
</id>
<!-- 其他属性 -->
<property name="name" column="sname"/>
<property name="age" column="sage"/>
<property name="gender" column="sgender"/>
</class>
</hibernate-mapping>
(5)创建数据库配置文件
默认名称hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- 根节点:代表Hibernate的配置,对应于Hibernate的类Configuration -->
<!-- 在当前配置文件里面可以不写hibernate. -->
<hibernate-configuration>
<!-- session-factory代表会话工厂,对应于Hibernate的类SessionFactory,创建Session对象 -->
<!-- hibernate4.x:需要删除name="foo"如果不删除,运行会报错 -->
<session-factory>
<!-- 连接数据库必须配置内容:4个 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///hibernatedb</property>
<property name="connection.username">root</property>
<property name="connection.password">admin</property>
<!-- 配置其他信息 -->
<!-- 必须配置的1个方言:实现数据库移植:分页语句,主键生成 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置 -->
<!-- property属性配置 -->
<!-- 是否自动创建表,不写默认为none -->
<!-- <property name="hbm2ddl.auto">update</property> -->
<!-- 是否显示sql语句 -->
<property name="show_sql">true</property>
<!-- 是否显示格式化sql语句 -->
<!-- <property name="format_sql">true</property> -->
<!-- mapping加载映射文件 -->
<!-- 加载属性resource->xml,路径必须是文件路径 -->
<mapping resource="org/zy/_01_hibernate/domain/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
可以在project\hibernate-core\src\main\resources\org\hibernate\下找到4个dtd文件,推荐用3.0版(听说目前是主流,随时联网的可以忽略)
配置文件中的属性几乎全在project\etc\hibernate.properties中可以参照!!
其中hbm2ddl.auto属性分为
create-drop:加载hibernate时创建表结构,退出是删除表结构
create::加载hibernate时先删除表结构再据映射文件创建表结构---会立即生效,用于测试阶段
update:加载hibernate时会根据映射文件去修改表的结构--用于测试,开发阶段
validate:加载hibernate时会验证映射文件是否和数据库的表一致--用于上线阶段
ps:请慎用!
(6)创建dao和dao实现类(实现CURD操作)
由于每次都要取得session会话实例所以创建了一个简单的工具类
package org.zy._01_hibernate.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
//工具类:单例模式
@SuppressWarnings("all")
public enum HibernateUtils {
INSTANCE;
private static SessionFactory sessionFactory;
//初始化Hibernate,创建SessionFactory实例
static{
try {
//解析配置文件 ,创建Configuration实例
Configuration config = new Configuration().configure();
//获得SessionFactory
sessionFactory = config.buildSessionFactory();//从hibernate4.x开始过时
} catch (Exception e) {
e.printStackTrace();
}
}
public Session getSession(){
//获取session
Session session = sessionFactory.openSession();
return session;
}
}
openSession():开启一个全新的Session(全新的连接,事务,一级缓存)
session是线程不安全的,所以一个Session对象只可以由一个线程使用.同时session是轻量级的,创建和销毁不需要消耗太多资源.
package org.zy._01_hibernate.dao;
import java.util.List;
import org.zy._01_hibernate.domain.Student;
/**
*CURD操作
*/
public interface IStudentDAO {
List<Student> getAll();
Student get(Long id);
void save(Student stu);
void update(Student stu);
void delete(Long id);
}
package org.zy._01_hibernate.impl;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.zy._01_hibernate.dao.IStudentDAO;
import org.zy._01_hibernate.domain.Student;
import org.zy._01_hibernate.util.HibernateUtils;
@SuppressWarnings("all")
public class StudentDAOImpl implements IStudentDAO {
public List<Student> getAll() {
// 获取一个会话
Session session = HibernateUtils.INSTANCE.getSession();
// 创建Query对象
Query query = session.createQuery("from Student");
// 获取查询结果
List<Student> list = query.list();
// 关闭session
session.close();
return list;
}
public Student get(Long id) {
// 获取会话
Session session = HibernateUtils.INSTANCE.getSession();
// 获取查询结果(查询单个不用使用Query实例)
Student stu = (Student) session.get(Student.class, id);
// 关闭session
session.close();
return stu;
}
public void save(Student stu) {
// 获取会话
Session session = HibernateUtils.INSTANCE.getSession();
// 声明事务
Transaction tx = null;
try {
// 创建并开启事务
tx = session.beginTransaction();// 等价于session.getTransaction().begin
// 保存学生信息
session.save(stu);
// 提交事务
tx.commit();
} catch (RuntimeException e) {
if (tx != null) {
// 事务回滚
tx.rollback();
}
} finally {
// 关闭session
session.close();
}
}
public void update(Student stu) {
// 获取会话
Session session = HibernateUtils.INSTANCE.getSession();
// 声明事务
Transaction tx = null;
try {
// 创建并开启事务
tx = session.beginTransaction();
// 修改
session.update(stu);
// 提交事务
tx.commit();
} catch (RuntimeException e) {
if (tx != null) {
// 事务回滚
tx.rollback();
}
} finally {
// 关闭session
session.close();
}
}
public void delete(Long id) {
// 获取会话
Session session = HibernateUtils.INSTANCE.getSession();
// 声明事务
Transaction tx = null;
try {
// 创建并开启事务
tx = session.beginTransaction();
//删除数据
Student stu = this.get(id);
if (stu != null) {
session.delete(stu);
}
//提交事务
tx.commit();
} catch (RuntimeException e) {
if (tx != null) {
// 事务回滚
tx.rollback();
}
} finally {
// 关闭session
session.close();
}
}
}
org.hibernate.Transaction:最常用,只能处理一个数据库的n个表同时DML操作事务管理
还有一种javax.transaction.Transaction(JTA):不常用的,可以处理n个数据库的n个表同时dml操作事务管理,tomcat不支持jta
(7)编写测试类,测试功能是否实现
package org.zy._01_hibernate.dao;
import java.util.List;
import org.junit.Test;
import org.zy._01_hibernate.domain.Student;
import org.zy._01_hibernate.impl.StudentDAOImpl;
public class StudentDAOTest {
private static IStudentDAO dao = new StudentDAOImpl();
@Test
public void testGetAll() {
List<Student> list = dao.getAll();
System.out.println(list);
}
@Test
public void testGet() {
Student stu = dao.get(1l);
System.out.println(stu);
}
@Test
public void testSave() {
Student stu = dao.get(1l);
stu.setId(null);//插入操作不能有id
dao.save(stu);
}
@Test
public void testUpdate() {
Student stu = dao.get(4l);
stu.setName("123");
dao.update(stu);
}
@Test
public void testDelete() {
dao.delete(4l);
}
}