最近学习Hibernate框架,记录自己的学习笔记
第一章
Hibernate之单表映射
ORM(Object /Relationship Mapping):对象关系映射
Hibernate是Java领域的一款开源的ORM框架技术
Hibernate对JDBC进行了非常轻量级的对象封装
其他主流的ORM框架技术
- Mybatis:前身为著名的iBatis
- TopLink:后被Oracle收购,并重新包装为Oracle As TopLink
- EJB:前身是JAVAEE的规范
编写一个Hibernate的例子
1.创建一个Hibernate的配置文件(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.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate?useUnicode=true&amp;characterEncoding=UTF-8</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping resource="Students.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2.创建持久化类(Students.java)
import java.util.Date;
//学生类
public class Students {
// 1.共有的类
// 2.提供共有的不带参数的默认的构造方法
// 3.属性私有
// 4.属性setter/getter封装
private int sid;// 学号
private String sname;// 姓名
private String gender;// 性别
private Date birthday;// 出生日期
private String address;// 地址
public Students() {
}
public Students(int sid, String sname, String gender, Date birthday, String address) {
// super();
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.birthday = birthday;
this.address = address;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Students [sid=" + sid + ", sname=" + sname + ", gender=" + gender + ", birthday=" + birthday
+ ", address=" + address + "]";
}
}
3.创建对象-关系映射表(Students.hbm.xml)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2019-7-24 20:50:21 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="Students" table="STUDENTS">
<id name="sid" type="int">
<column name="SID" />
<generator class="assigned" />
</id>
<property name="sname" type="java.lang.String">
<column name="SNAME" />
</property>
<property name="gender" type="java.lang.String">
<column name="GENDER" />
</property>
<property name="birthday" type="java.util.Date">
<column name="BIRTHDAY" />
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
</class>
</hibernate-mapping>
4.通过Hibernate API编写访问数据库的代码
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
//测试类
public class StudentsTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init() {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties())
.buildServiceRegistry();
// 创建会话工厂对象
sessionFactory = config.buildSessionFactory(serviceRegistry);
// 创建会话对象
session = sessionFactory.openSession();
// 开启事务
transaction = session.beginTransaction();
}
@After
public void destroy() {
transaction.commit();// 提交事务
session.close();// 关闭会话
sessionFactory.close();// 关闭会话工厂
}
@Test
public void testSaveStudents() {
//生成一个学生对象
Students s=new Students(1,"张三丰","男",new Date(),"武当山");
session.save(s);//保存对象进数据库
}
}
}
第二章
hibernate.cfg.xml常用配置
属性名字 | 含义 |
hibernate.show_sql | 是否把Hibernate运行时的SQL语句输出到控制台,编码阶段便于测试 |
hibernate.format_sql | 输出到控制台的SQL是否进行排版,便于阅读。建议设置为true |
hbm2ddl.auto | 可以帮助Java代码生成数据库脚本,进而生成具体的表结构。create|update|create-drop|validate |
hibernate.default_schema | 默认的数据库 |
hibernate.dialect | 配置hibernate数据库方言,hibernate可针对特殊的数据库进行优化 |
注:hibernate的前缀可以省略,即:hibernate.dialect等同于dialect |
session简介
hibernate的执行流程
不建议直接使用jdbc的connection操作数据库,而是通过使用session操作数据库。
session可以理解为操作数据库的对象。
session与connection,是多对一关系,每个session都有一个与之对应的connection,一个connection不同时刻可以供多个session使用。
把对象保存在关系数据库中需要调用session的各种方法,如:sava(),update(),delete(),createQuery()等。
transaction简介
hibernate对数据库的操作都是封装在事务当中,并且默认是非自动提交的事务。所以session保存对象时,如果不开启事务,并且手动提交事务,对象并不会真正保存在数据库中。
如果想让hibernate像jdbc那样自动提交事务,必须调用session对象的doWork()方法,获得jdbc的connection后,设置为自动提交事务模式。(注意:通常并不推荐这么做)
session详解
如何获得session对象
- openSession
- getCurrentSession
如果使用getCurrentSession需要在hibernate.cfg.xml文件中进行配置:
如果是本地事务(JDBC事务)
<property name="hibernate.current_session_context_class">thread</property>
如果是全局事务(jta事务)
<property name="hibernate.current_session_context_class">jta</property>
openSession与getCurrentSession的区别
1. getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需要手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
2. openSession每次创建新的session对象,getCurrentSession使用现有的session对象。
hbm配置文件常用设置
<hibernate-mapping
schema="schemaName"
catalog="catalogName"
default-cascade="cascade_style" //级联风格
default-access="fild|property|ClassName"//访问策略
default-lazy="true|false"//加载策略
package="packagename"
/>
<class
name="ClassName"
table="tableName"
batch-size="N"//抓取策略
where="condition"//一些条件
entity-name="EntityName"//同一个类映射成多个表
/>
<id
name="propertyName"
type="typename"
column="column_name"
length="length"
<generator class="generatorClass"/>
>
</id>
主键生成策略
标识符生成器 | 描述 |
increment | 适用于代理主键。由Hibernate 自动以递增方式生成。 |
identity | 适用于代理主键。由底层数据库生成标识符。 |
sequence | 适用于代理主键。Hibernate根据底层数据库的序列生成标识符,这要求底层数据库支持序列。 |
hilo | 适用于代理主键。Hibernate分局high/low算法生成标识符。 |
seqhilo | 适用于代理主键。使用一个高/低位算法来高效的生成long,short或者int类型的标识符。 |
native | 适用于代理主键。根据底层数据库对自动生成标识符的方式,自动选择identity,sequence或hilo. |
uuid.hex | 适用于代理主键。Hibernate采用128位的UUID算法生成标识符。 |
uuid.string | 适用于代理主键。UID被编码成个16字符长的字符串。 |
assigned | 适用于自然主键。由Java应用程序负责生成标识符。 |
foreign | 适用于代理主键。使用另外一个相关联的对象的标识符。 |