ORM框架, Object-relation-mapping
1 hello world实现
2. 增加配置文件hibernate.cfg.xml 推荐放在src/
3. 创建实体类User
a) @Entity加在类上(标识一个需要映射的实体类)
b) @Id(标识你这个属性是一个主键)
@GeneratedValue主键自增
在hibernate.cfg.xml中配置了一个映射的路径
测试代码
1.1 默认创建表结构的规 则
1. 表名默认是类名
2. 字段名默认是属性名
3. 字段类型默认是跟我属性类型一一对应
a) int --> int(11)
b) String --> varchar(255)
2 实体类常用注解
@GeneratedValue
@Table(name="t_user")//当表名和类名不一致的情况下, 去手动指定映射的表名
@Column(name="username")//当字段名和属性名不一致的情况下, 去手动指定映射的字段名
@Transient//把这个属性排除在数据库的映射之外
3 hibernate核心接口
session接口
增删改查基于session接口
3.1 增加
save(object)
3.2 更新
update
1.1 删除
delete
注意:
所有的增删改操作都必须手动开启和提交事务, 否则SQL不执行
1.1 查询
1.1.1 get
1.1.1 load
用法同get
1.1.2 区别
1. 如果查询的数据不存在, get方法是正常返回null, load方法抛出异常ObjectNotFountException
2. get方法是立即加载对象, load方法是懒加载的形式, 在真正用到这个对象的时候才会去查询数据库(必须是在session没有关闭之前去操作, 否则会抛出LazyInitializationException)
2 hibernate实体类的3种状态
临时, 持久, 游离
2.1 持久状态的2个特性
数据自动同步
缓存
必须是在session未关闭之前去操作, 必须是同一个session
1 HQL语句
hibernate query language
1.1 入门实例
注意:
1. HQL中没有select * 的做法
2. select子句可以省略的, 如: from User
3. 查询的不是表名, 而是类名(可以是简单类名或全限定名), 查询条件中用的是属性名而不是字段名
1.1 绑定参数的方法
通过参数位置
参数的位置从0开始
通过参数名
1.1 用HQL语句的删除和更新
更新:
删除:
1 返回唯一的记录
1 分页
从第几条开始
每页多少条
select * from t_user limit {startRow}, {pageSize}
1 HQL用法详解
1.1 用count来查询记录总数
query.setFirstResult 设置从第几条开始查询
query.setMaxResult 设置一共查询多少条
1.1 用distinct排除重复记录
1.1 用group by去进行分组查询
分组之后的条件查询
1 spring和hibernate整合
1.1 配置
引入spring的jar包, 增加spring的配置applicationContext.xml
在配置文件中需要配置3个bean:
1. 数据源C3P0
2. sessionFactory( 引用数据源)
a) hibernate相关的配置(方言, 自动生成表结构...)
b) 实体类的包扫描路径
hibernateTemplate ( 引用sessionFactory)
之后所有的增删改查都是基于这个去做的
代码
1.1 基于hibernateTemplate做HQL的操作
1.1.1 find
1.1.1 bulkUpdate
用法和find类似
1.1.1 分页
1 hibernate实体类关联关系
一对一, 一对多, 多对一, 多对多
1.1 通过注解实现关联关系
1.1.1 OneToOne
加在具体的关联对象的属性上
结论:
1. 查询的时候会自动把关联对象也查询出来, 并且组装好关系
a) 通过get方法默认是用join, 一条SQL(效率更高)
b) 通过HQL语句, 默认是2条SQL , 分别查询
如果指定了自动生成表结构, 那么就自动生成一个关联字段的外键
关联字段的默认命名方式: 属性名_关联对象的主键属性名
如: book_id
注意:
1. 如果你需要映射的实体类中, 有关联的映射实体类属性
你的关联属性必须声明一个关系, 或者可以用@Transient注解去撇清关系
否则hibernate会抛出异常
org.hibernate.MappingException: Could not determine type for...
2. 如果你的类名是SQL中的关键字, 那么就必须给他手动指定一个表名
@Table(name=”xxx”)
@JoinColumn的用法
1.1.1.1 增加记录
1 外键
强约束
优势:
数据的严格一致性
劣势:
性能比较差
1 通过注解实现关联关系
1.1 ManyToOne
与OneToOne的用法基本一致, 只是业务模型的描述上不一样
1.1 OneToMany
作用于集合类型的属性上
1.1.1 fetch属性的用法
数据加载方式:
一对一和多对一
OnetoOne, ManyToOne 默认都是直接加载数据, fetch=EAGER
OneToMany ,ManyToMany 默认加载方式是懒加载, fetch=LAZY
1.1.1 mappedBy属性的用法
mappedBy属性一般是加在不生成关联字段的那一方, 指定需要增加关联字段的那一方
一般关联字段会加在多的那一方
1.1.2 添加数据
1.1 ManyToMany
如果是双向的ManyToMany, 默认会自动生成2张关联关系表, 如果你只想要一张关联表, 可以在其中一方指定mappedBy=, 让关联表只交给对方去生成
ManyToMany也是作用在集合类型的属性上, 但是这个集合最好用的是Set
1.1 总结关联关系的用法
1. 关联关系是成对确定的, 通过梳理2个对象之间双向的关系最终而确定
@OneToOne, @ManyToOne : 作用于单个对象的属性上
@OneToMany, @ManyToMany : 作用于集合类型的属性上
注意:
关联对象的类型如果是hibernate映射的实体类, 则必须指定一种关联关系, 或者用@Transient注解撇清关系
1 spring的事务管理和hibernate结合
@transactional注解对于事务回滚的默认规则:
1. 默认是只会对于那些运行时异常进行回滚
通过手动指定抛出异常的事务回滚机制
1 hibernate做自关联的表
1 SSH整合
1. 引入jar包
2. 配置struts框架
a) 核心过滤器
b) struts.xml
3. spring配置
a) 监听器
b) applicationContext.xml配置hibernate
检查:
1. spring的包扫描是否完整: Controller, service, dao
2. 实体类的注解是否完整: @Entity, @Id...