关系数据库ORM框架
配置文件
hibernate.cfg.xml
核心配置文件,基本配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?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.username">root</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb</property> <property name="hibernate.show_sql">true</property> <property name="format_sql">false</property> <property name="hbm2ddl.auto">update</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <mapping resource="com/ljc/bean/User.hbm.xml" /> </session-factory> </hibernate-configuration>
|
*.hbm.xml
bean映射文件,与javabean放在同一个包下,*为bean的名称,如User.hbm.xml,基本配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?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 package="com.ljc.bean"> <class name="User" table="user"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="name" column="username"></property> <property name="password" column="password"></property> </class> </hibernate-mapping>
|
常用Api
Configuration
构造: //无参的configure()默认加载src根目录下的hibernate.cfg.xml,有参的为加载指定目录
1
| Configuration config = new Configuration().configure();
|
SessionFactory
类似于JDBC连接池,用于管理所有session
1
| SessionFactory sessionFactory = config.buildSessionFactory();
|
sessionFactory缓存配置信息:数据库配置信息、映射文件、预定义HQL语句 等
其线程安全,可以是成员变量,多个线程同时访问时,不会出现线程并发访问问题。
1 2 3 4
| sessionFactory.openSession(); sessionFactory.getCurrentSession();
|
getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需手动关闭
如果使用openSession而没有手动关闭,多次之后会导致连接池溢出
openSession每次创建新的session对象,getCurrentSession使用现有的session对象(单例)
hibernate支持将创建的session绑定到本地线程中,底层使用ThreadLocal,在程序之间共享session
但必须在hibernate.cfg.xml 配置以下属性才可使用getCurrentSession()
1
| <property name="hibernate.current_session_context_class">thread</property>
|
Session
类似于JDBC的Connection,实现数据库的增删改查,单线程,线程不安全,不能编写成员变量
插入操作
1 2 3 4 5 6 7
| User user = new User(); user.setId(123); user.setName("LJC"); user.setPassword("123456"); session.save(user);
|
删除操作
1 2 3 4
| User user = (User) session.get(User.class,1); session.delete(user);
|
更新操作
1 2 3 4 5 6
| User user = (User) session.get(User.class, 1); user.setName("ljc"); session.update(user);
|
查询操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| User user1 = (User) session.get(User.class,1); User user2 = (User) session.load(User.class,1); Query query = session.createQuery("from com.ljc.bean.User"); List<User> list = query.list(); Criteria criteria = session.createCriteria(User.class); List<User> list1 = criteria.list(); SQLQuery query1 = session.createSQLQuery("select * from user"); query1.addEntity(User.class); List<User> list2 = query.list();
|
Transaction
1 2 3 4 5 6 7 8
| Transaction ts = session.beginTransaction(); ts.commit(); ts.rollback(); session.getTransaction();
|
如果提交或回滚事务,底层将自动关闭session
Query
封装HQL语句
1 2 3 4 5 6 7 8 9 10 11
| Query query = session.createQuery("from com.ljc.bean.User"); query.list(); query.uniqueResult(); query.setFirstResult(0); query.setMaxResults(2);
|
多表映射
一对多/多对一
- 一对多
数据库:通过添加主外键的关联,表现一对多的关系(在多的一方加入外键,引用一的一方的主键)
代码中:通过在一方持有多方的集合实现,即在”一”的一端中使用元素表示持有”多”的一端的对象
- 多对一
多对一的关系和关系数据库中的外键参照关系最匹配,即在己方(多方)表中的一个外键参照另一个表的主键
通过在多方持有一方的引用实现,需要在”多”的一端使用配置
1 2 3 4 5 6 7
| 一方: <set name="集合属性名" > <key column="外键名" /> <one-to-many class="多的一方的类型" /> </set> 多方: <many-to-one name="属性名" column="外键名" class="一的一方类型" />
|
- inverse
表示反转,是节点的一个属性(用来指定关联关系的维护),可以指定关联关系的方向,默认值为false(不反转)
//即表示一的一方要不要放弃维护外键关系
1、一方的hbm.xml文件的节点的inverse属性指定了关联关系的控制方向,默认由one方来维护
2、关联关系中,inverse=”false”则为主动方,由主动方负责维护关联关系
3、在一对多关联中,设置one方的inverse为true,这将有助于性能的改善
4、只存在于集合标记的元素中,Hibernate提供的集合元素包括
- cascade
级联操作
1、当设置了cascade属性不为none时,Hibernate会自动持久化所关联的对象
2、cascade属性的设置会带来性能上的变动,需要谨慎设置
1 2 3 4 5
| 属性值 含义和作用 all 对所有操作进行级联操作 save-update 执行保存和更新操作时进行级联操作 delete 执行删除时进行级联操作 none 对所有操作不进行级联操作
|
多对多
数据库:使用中间表,分别引用两方的ID
对象: 两方都使用set集合表达
1 2 3 4
| <set name="courses" table="t_student_course" > <key column="sid" ></key> <many-to-many class="Course" column="cid" ></many-to-many> </set>
|
加载策略/优化查询
策略种类:延迟加载、立即加载
策略的应用:类级别的加载策略、关联级别的加载策略
类级别加载策略
即get与load方法查询数据的方式
其中load属性是否懒加载由hbm文件中class元素的lazy属性决定
- lazy=”true”:先返回一个代理对象,使用代理对象的属性时,才去查询数据库(默认值)
- lazy=”false”:与get一致,会立即加载数据
关联级别加载策略
在查询有关联关系的数据时,加载一方的数据是否需要将另一方立即查询出
默认: 与我关联的数据,在使用时才会加载.
关系中主要由的两个属性:fetch、lazy来设置
缓存
Hibernate 提供缓存机制
- 一级缓存:session级别缓存,在一次请求中共享数据
- 二级缓存:sessionFactory级别缓存,整个应用程序共享一个会话工厂,共享一个二级缓存
一级缓存
当获得一次会话session,hibernate在session中创建多个集合map,用于存放操作数据
如果之后需要相应的数据,优先从session缓存中获取,如果有就使用,有再查询数据库
当session关闭时,一级缓存销毁
一级缓存中的快照
与一级缓存一样的存放位置,对一级缓存数据备份,保证数据库的数据与一级缓存的数据一致
如果一级缓存修改了,在执行commit提交时,将自动刷新一级缓存,执行update语句,将一级缓存的数据更新到数据库
1 2 3 4
| session.evict(user); 用于将某个对象从Session的一级缓存中清除 session.clear(); 用于将一级缓存中的所有对象全部清除 session.refresh(user); 保证一级缓存的数据与数据库的数据保持一致 session.flush(); 手动刷新缓存,默认情况提交commit()刷新
|
二级缓存
SessionFactory的缓存两部分
- 内置缓存:使用一个Map,用于存放配置信息,预定义HQL语句等,提供给框架自己使用,对外只读,不能操作
- 外置缓存:使用另一个Map,用于存放用户自定义数据,默认不开启,需要第三方实现类。外置缓存即二级缓存
由4部分构成:类级别缓存/集合级别缓存/时间戳缓存/查询缓存(二级缓存的第2大部分,三级缓存)
通常使用EHCache:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernatede查询缓存提供了支持
二级缓存的适用场景:很少被修改的数据/不是很重要的数据,允许出现偶尔并发的数据/不会被并发访问的数据
1 2 3 4 5 6 7
| 一级缓存 二级缓存 缓存范围范围 事务范围 应用范围,当前应用内所有事务共享 并发访问策略 不会出现并发问题 序提供并发访问策略 数据过期策略 无 缓存对象的最大数目/最长时间等 缓存的软件实现 框架包含 第三提供,可插拔集成 物理介质 内存 内存和硬盘 启用方式 默认启用,不可关闭 默认不启用,选择性开启
|