hibernate基础
配置文件
-
配置文件的命名规范:类名.hbm.xml
-
配置方式为xml文件
-
引入约束文件
约束文件位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yeWCdj10-1593604408762)(F:\MarkDownOnte\学习笔记\dao层框架\assets\1591609475867.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nm8xWkat-1593604408763)(F:\MarkDownOnte\学习笔记\dao层框架\assets\1591609484987.png)]
-
根标签hibernate-mapping
-
实体类映射文件标签
-
class 标签:
-
name属性 实体类的全限定名
-
table属性 数据库的表名
-
id标签 建立类中的属性与表中的主键映射关系
- name属性 实体类中对应主键名
- colum属性 表中的主键列
- generator 标签 class=“native”
-
property标签 实体类中其他属性与数据库的字段映射关系
- name属性 实体类属性名
- colum属性 数据库列名
实体类映射配置文件示例
<?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="com.wx.dao.Customer" table="cst_customer"> <!-- 建立类中的属性与表中的主键对应 --> <id name="cust_id" column="cust_id" > <!--主键的生成策略--> <generator class="native"/> </id> <!-- 建立类中的普通的属性和表的字段的对应 --> <property name="cust_name" column="cust_name" length="32" /> <property name="cust_source" column="cust_source" length="32"/> <property name="cust_industry" column="cust_industry"/> <property name="cust_level" column="cust_level"/> <property name="cust_phone" column="cust_phone"/> <property name="cust_mobile" column="cust_mobile"/> </class> </hibernate-mapping>
-
-
-
hibernate核心配置文件
-
有两种配置方式xml方式与properties文件方式
-
核心配置文件名 hibernaet.cfg.xml
-
根标签session-factory
- 子标签property 配置连接数据库相关的配置
- 子标签property 配置数据库的方言,为了自动生成不同数据库的sql语句
- 子标签mapping 配置映射
-
hibernate的使用
- 加载hibernate的核心配置文件
- Configuration configuration= new Configuration().configure
- 创建SessionFactory的对象类似于连接池
- configuration.bulidSessionFacory()
- 通过SessionFactory获取session对象
- sessionFactory.openSessionFactory()
- 手动开启事务
- session.beginTransaction()
- 编写代码
- 创建实体类
- session.save(实体类)
- 提交事务
- session.commit
- 释放资源
- session.close()
hibernate的常见配置
-
核心配置三类:
- 1.必须配置
- 驱动类
- url路径
- 用户名
- 密码
- 2.可选配置
- 显示sql语句 hibernate.show.sql
- 格式化sql hibernate.format.sql
- 自动建表 hibernate.hbm2ddl.auto
- none 不会自动创建表
- create 如果数据库中有表就删除然后重新创建
- update 如果数据库中有表就使用没有就创建(更新表结构)
- validate 如果数据库中没有表就报错有就使用(校验用)
- 3.映射文件引入
核心配置文件示例
<?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://localhost:3306/hibernate</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> <!-- 可选配置================ --> <!-- 打印SQL --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- 自动创建表 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 配置C3P0连接池 --> <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> <!--加载实体类映射文件--> <mapping resource="com/wx/dao/Customer.hbm.xml"/> </session-factory> </hibernate-configuration>
hibernate的核心API
-
Configuration:Hibernation的配置文件
- 作用:
- 加载核心配置文件
- 加载映射文件
- 作用:
-
SessionFactory: session工厂
- 作用1:初始化hibernate,
- 作用2:维护了连接池与二级缓存
- 线程安全的对象,一般一个项目创建一个对象
-
Session:连接对象,非线程安全的,与数据库交互的桥梁
-
相关的API:
- 保存: Serializable save(Object obj); 返回保存记录的id
- 查询:
- T get(Class c,Serializable id);
- T load(Class c,Serializable id);
-
两者区别:
- load方式采用延迟加载,返回的是一个代理的对象,查询不到会抛出异常
- get采用一次性直接加载返回真是的对象,未查询到会返回一个null
- 1.必须配置
持久化类编写规则
- 在java中与数据库表对应的实体类被称为持久化类
- 持久化类=java类+映射文件
- 持久化类编写规则:
- 由于地城是通过反射的方式建立的实体类对象,所以必须要有无参构造
- 对应属性必须要有get/set方法
- 对持久化类必须要提供一个唯一标识OID与数据库主键对应
- 在属性中如果出现了基本数据类型尽量使用其对应的包装数据类型(避免出现歧义,因为基本数据类型默认为0,包装类型为null)
- 持久化类不要使用final修饰,因为要使用代理对象
主键生成策略
- 主键分类:
- 自然主键:主键本省是表中的一个字段,比如创建一个人员表,其身份证就是唯一的使用身份证号作为主键就是自然主键
- 代理主键:本省不是表中必须的一个字段,必须在表中我们另外创建一个id来标识一张表,这个主键就是代理主键
- 尽量使用代理主键
- 主键的生成策略
- 在开发中主键多数不是由用户输入的数据设置的,一般使用程序自动生成,在Hibernate中为了减少程序的编写提供了多种主键的生成策略
- increment: hibernate中的自动增长机制 适合在单线程中short int long 类型的主键,原理如下
- 首先发送一个sql语句 select max(id) from biao 然后让id+1作为下一条记录的主键
- identity: 使用short int long 类型的主键,底层使用数据库的自增 ocacle没有自增不能使用
- sequence:使用short int long 类型的主键,采用序列的方式(oracle数据库)mysql不能使用
- uuid: 使用与字符串类型的主键,生成唯一uuid作为主键
- native:本地策略 ,hibernate依据数据库的不同使用对应的主键生成策略
- assigned: 由用户自己设置主键,hibernate不会生成主键
- foreign: 一对一表映射的情况下使用
- increment: hibernate中的自动增长机制 适合在单线程中short int long 类型的主键,原理如下
- 在开发中主键多数不是由用户输入的数据设置的,一般使用程序自动生成,在Hibernate中为了减少程序的编写提供了多种主键的生成策略
持久化类的三种状态
- 瞬时态(transient):没有唯一标识oid,没有被session管理
- 持久态(persistent):有唯一标识oid,被session管理
- 持久化类的处于持久化状态的对象可以自动更新数据库
- 托管态(detached):有唯一标识oid,没有被session管理
@org.junit.Test
public void test2(){
// 对持久化类三种状态的测试
Session session = HibernateUtis.getSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer(); // 瞬时态
Serializable save = session.save(customer);// 有唯一oid被session管理持久态
customer.setCust_mobile("1107964521"); // 在这个期间对custom操作是处于持久化状态
transaction.commit();
session.close();
System.out.println(customer.getCust_id());// 现在处于托管态
}
三种状态的相互转换
- 转换方式
-- 瞬时态获得: new
- 瞬时->持久 save()方法
- 瞬时->托管 直接设置oid custom.setCust-id(1)
- 持久态获得
- 获得:get(),load(),find()
- 持久->瞬时 delete()
- 持久->托管 clear() close()
持久化类的持久态的特性
-
持久态自动更新数据库
Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); // 获得持久态对象 Customer customer = session.get(Customer.class, 2l); customer.setCust_level("17");// 设置属性 // session.update(customer); 不同调用更新方法直接就在数据库中更新了数据 transaction.commit(); session.close();
hibernate的缓存
-
一级缓存
- 一级缓存是自带的不可卸载,只是作用与同一个session对象,其底层原理是session对象包含了一些列的java集合,在集合中存储了已经查询对象的oid再吃进行查询的时候如果在集合中查到了oid直接返回结果,如果在集合中没有查询到才到数据库中去查询,然后把查询结果存储到集合中并返回结果。
-
一级缓存内部结构:
- 一级缓存中存在的特殊区域:快照区(把查询的结果备份到快照区域)
-
二级缓存一般不使用,因为会使用效率更高的redis代替
Hibernate的事务管理
-
为了保证连接对象是同一个连接对象(session)
-
向下传递
-
使用ThreadLocal 对象
- 将这个连接绑定到当前线程中
- 在dao的方法中,通过当前线程获得连接对象
-
在hibernate中已经有绑定号的ThreadLocal对象但是默认不能使用需要设置开启
-
在sessionFactory中提供了一个方法getCurrentSession()
-
开启配置
<property name="hibernate.current_session_context_class">thread</property>
-
Hibernate中的其他的API
-
Query
-
query是一个接口用于接收HQL ,查询多个对象
-
HQL:Hibernate Query Language 与sql相识的一种Hibernate的专属查询语言,面向对象的一种查询语言
-
// 普通查询所有 String hql="from Customer"; Query query = session.createQuery(hql); List list = query.list(); list.forEach(s-> System.out.println(s));
//条件查询 Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); // 条件查询 String hql="from Customer where cust_name like ? "; Query query = session.createQuery(hql); // 替换参数 query.setParameter(0,"%凌%"); // 执行查询 List list = query.list(); list.stream().forEach(s-> System.out.println(s));
// query分页查询 Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); String hql="from Customer"; Query query = session.createQuery(hql); // 设置分页条件 query.setFirstResult(0); query.setMaxResults(5); //显示数据 List list = query.list(); list.stream().forEach(s-> System.out.println(s));
-
-
Ctiteria对象
criteria标准查询
Session session = HibernateUtis.getSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
List list = criteria.list();
criteriacriteria条件查询
// criteria
Session session = HibernateUtis.getSession();
Transaction transaction = session.beginTransaction();
// 获得Criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.like("cust_name","%赵%"));
List list = criteria.list();
list.forEach(s-> System.out.println(s));
criteria分页查询
Session session = HibernateUtis.getSession();
Transaction transaction = session.beginTransaction();
// 获得Criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
// 设置查询条件
criteria.add(Restrictions.like("cust_name","%逻%"));
// 设置分页参数
criteria.setFirstResult(2);
criteria.setMaxResults(6);
List list = criteria.list();
list.forEach(s-> System.out.println(s));
ion = session.beginTransaction();
// 获得Criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
// 设置查询条件
criteria.add(Restrictions.like(“cust_name”,"%逻%"));
// 设置分页参数
criteria.setFirstResult(2);
criteria.setMaxResults(6);
List list = criteria.list();
list.forEach(s-> System.out.println(s));