Hibernate是对JDBC的轻量级封装。
Get Start
导包
建立数据和表
编写1实体类,结构与表相对应
写两个配置文件
1个配置文件的名字为类名.hbm.xml用来绑定实体类对象和数据库中的表的映射关系;
程序的执行流程
配置文件
hibernate.cfg.xml文件配置连接数据库的必要信息,SQL方言,映射相关的XXX.hbm.xml文件
XXX.hbm.xml绑定表跟实体类,配置表中的字段和实体类中属性的对应关系
执行程序
先根据配置文件生成SessionFactory
通过SessionFactory打开Session
通过Session执行语句
关闭Session和SessionFactory
1个配置文件的名字为hibernate.cfg.xml
它又可以分为2部分来看
1部分用来配置连接数据库的必要信息(url,username,password,jdbc等),另1部分用来配置一些选项,例如数据库的方言、是否显示sql执行语句、是否自动更新表结构(是的话可以不用提前建表)
代码层面,注意一下逻辑关系。
插入
比如插入数据的大体流程是先通过配置文件生成工厂模型,工厂模型再生成一个会话对象,会话对象开启事务,会话对象存储实体类,会话对象提交事务,会话关闭,工厂关闭
要点:
记住每个实体类都对应着一张表,许多操作之所以要求传入实体类的类对象就是为了让框架搞明白是要对哪张表进行处理
获取跟查询是两码事,获取类似你选中了一条记录,而查询是根据条件返回的一个集合
对象的三种状态
瞬时:正常的Java对象,没有和Hibernate发生联系
持久:与Hibernate发生了联系,1.有对应的Session 2.database中有对应的数据
脱管:与Hibernate发生了联系 1.对应的Session已经关闭 2.database中有对应的数据
比如一个插入的流程,在对象被保存之前都属于“瞬时”状态,被保存后、Session关闭前属于“持久”状态,Session关闭后属于“脱管”状态
获取
通过id读取一条记录,用get或者load方法,传2个参数,一个是类对象,一个是id号
区别:
get是立刻执行查询操作,load是惰性执行,即对应的属性被访问时才会执行查询操作
当id不存在的时候,get返回null,load抛异常
删除
先通过get、load方法获取要删除的记录(保存在对应的对象里)
执行s.delete(p)即可在数据库中删除
修改
先通过get、load方法获取对应的记录
修改对象的属性值
执行s.update(p)
使用HQL(Hibernate Query Language)进行查询
这里的操作其实就类似JDBC了。
通过s.createQuery(String sql)实例化一个Query对象 q,通过q.setXXX(int index,xxx val)对sql语句中的参数赋值。
q.list()返回查询的结果集(List<>类型)
另外,使用hql用的是实体类的类名,而不是数据库中的表名,返回的是实体类本身的集合,字段也是直接根据实体类的属性去比较
使用Criteria查询
1.完全面向对象,不再用类Sql语句
2.适合条件查询
流程:
通过s.createCriteria(类.class)创建对象c
c.add(Restrictions.like("属性名",“条件”))
c.list()
使用标准语句查询
流程跟HQL基本一样,区别在于
Query q=s.createSQLQuery(String sql)
表关系的实现
一对一
多对一
多对多
多对一
逻辑梳理:不妨设A与B存在多对一关系(一个B对应多个A,则A对B相当于多对一,B对A相当于一对多)
实体类的变动
在A中增加一个B类型的属性字段(相当于外键)
在A的A.hbm.xml配置文件中,添加新增字段的配置,标签为 标签属性有name、class、column分别对应着实体类A的属性、属性类型(多对一关系中所对应的类)、对应A表中的字段名
在hibernate.cfg.xml中映射实体类A,B,通过2个标签即可绑定。属性为resoure,指向实体类的配置xml文件
一对多
(一个B对应多个A,则B对于A来说相当于多对一)
逻辑梳理:
跟多对一的区别是这回通过修改B类来实现二者的关系映射。
因为一个B对应多个A,所以用Set集合来定义字段属性
修改B的配置文件xml,使用