day 02
Hiberante中最重要的几个接口或类:
Configuration:
SessionFactory:
Session:(最重要的一个接口) API
1.操作实体对象
save()
update()
saveOrUpdate()
2.操作缓存
clear()
evict()
flush
3.查询实体对象
get() //OID获得(对象标识)
load() //同上,懒加载,其实是产生代理对象
createQuery() //使用的是HQL,推荐使用
createCriteria() //使用的是QBC
Query:(查询中非常重要的一个接口) API
返回唯一的结果:
query.uniqueResult()
分页使用的方法:
query.setFirstResult(firstResult);
query.setMaxResult(maxResults)
Session 接口的get 和load 的区别:
Session的get 和load的方法有一点点区别,get是立马查询,load是要用的时候才查询。
load:懒加载,不会马上执行sql语句,而是在第一次使用非id或Class属性的时候才执行查询。load()返回的是代理对象,get()返回的是真正的对象。如果确定数据库中肯定有该对象的话可以使用load懒加载,如果不确定的话最好使用get方法。load方法是认为数据库中一定存在数据的不然就抛出异常,get则不是返回null.
使用session 执行删除比较浪费效率,分两步:1.先获得对象2.删除对象
对象的三种状态
临时状态:与数据库没有对应关系没有表记录,和session没有关联,一般都是new 出来的对象。可以通过Session的save或saveOrUpdate方法来改变其状态
游离状态:特点1.数据库中有对应的表记录但对象不在Session管理中,修改此状态的对象时对数据库没有影响。session关闭后,持久化状态就会变为游离状态
持久化状态:对象在Session的管理中,最终会有对象的数据库记录。
特点:1.有OID 2.对对象的修改会同步到数据库中
总之:对象的几种状态区分是根据和Session以及是否对应数据库表记录来区分的,同时利用Session可以改变它们的状态。
对象状态转换图可以去看看帮助理解。
在session接口API那里有一段操作session的标准模板。
自己编写一个HibernateUtils工具类,可以获得SessionFactory和Session实例。
持久化类的要求:(虽然不是必须的,但是良好的习惯就是如此)
POJO:(Plain Old Java Object) 四个原则
1.提供无参数构造方法
2.提供一个标识属性
3.生成setter和getter方法 ,如果是boolean值就是is
4.使用非final的类
Session的缓存机制是一级缓存,可以将Session当作缓存来理解。
SessionFactory提供了二级缓存机制,主要作用是用来创建Session实例。
Hibernate的查询方式:
1.导航图对象方式 其实就是getter方式 即根据关联关系来getter方式来获得
2.OID方式 即根据对象的卫衣标识符 即get()和load()方法
3.HQL 即hibernate query language 推荐使用,功能强大
4.SQL 即结构化查询语句 不推荐使用
5.QBC查询方式 不推荐使用,比较麻烦
HQL查询语句
HQL 和 SQL 很类似,可以借鉴SQL语法来写HQL,有一点不同的是HQL没有 * 属性。
使用HQL时,都要使用别名(强烈推荐使用,不然有时候会出现问题)
比较麻烦的就是指定查询字段查询:(前提是要使构造方法和字段对应)如下:
Session接口的查询方法比较多也比较复杂:一定要掌握这种形式:
Qyery query=session.createQuery(select new Person(name,age,info) from Person);
List<Person> lsit=new Query.lsit();
前提是必须有Person(name,age,info) 的构造方法,还要记得顺序。
映射部分:
分析关联映射很重要的一点就是分析两个表产生关联的时候有没有生成新表。
集合映射:
比如一个人有多个密码 Set<String> passwords=new HashSet<>();
映射文件如下:
<class name="User" table="user" >
<id name="id" type="int" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<set name="passwords" table="user_password_tables">//会产生一个中间表
<key column="userid" not-null="true"></key>//中间表的id
<element column="password" type="string" length="20"></element>
//中间表的字段
</set>
</class>
一对多和多对一:(是映射中最重要的一种映射关系)
分为单向和双向的:
假如一个老师对应多个学生
老师配置文件如下:
<class name="Teacher" table="teacher">
<id name="tecid" column="tecid">
<generator class="native"></generator>
</id>
<property name="name"></property>
<set name="students" table="tec_stu">
<key column="tecid"></key>
<one-to-many class="Student"/>
</set>
</class>
学生配置文件如下:
<class name="Student" table="student">
<id name="stuid" column="stuid">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<many-to-one name="teacher" column="tecid">
</many-to-one>
</class>
配置文件的备注:只要有集合属性就要有table属性。
一对一映射
1.利用主键约束(不推荐使用)
2.利用外键约束(推荐使用)
其实唯一外键约束是多对一的一种特殊< many-to-one unique=”true”>,但是此时已经不是set集合了,直接使用<many-to-one unique=”true”/>.
双向的 Person<===>IdCard
Preson映射文件如下:
<class name="Person" table="person">
<id name="id" type="int" column="person_id">
<generator class="native"></generator>
</id>
<property name="name" column="name" type="string"></property>
<!--重点在这一句,多对一 然后再加一个唯一约束 -->
<many-to-one name="idCard" unique="true"></many-to-one>
</class>
IdCard映射文件如下:
<class name="IdCard" table="idcard">
<id name="id" type="int" column="idcard_id">
<generator class="native"></generator>
</id>
<property name="cardNumber" column="cardnumber" type="string"></property>
<!-- 重点在于这一句,多对一 加上唯一性约束即可 -->
<many-to-one name="person" unique="true" column="onlyPerson"></many-to-one>
</class>
如果是单向的话,把对方的many-to-one 删除即可
关联映射总结:最重点在于一对多和多对一的映射配置,只要好好理解好这种情况就能解决实际开发中遇到配置的绝大多数问题了,到时候如果不会再来看看官方的帮助文档即可。
Hibernate对象的三种状态:(官方的)
瞬态:(transient)
持久化:(persistent)
脱管:(detached)
Hibernate开发步骤:
1.添加jar 包 核心包、required包、jpa的jar 包
2.记住添加数据库驱动包
3.到hibernate项目中 copy paster : hibernate.cfg.xml 和一个简单的 xxxx.hbm.xml
4.准备好domain对象 即持久化类
5.配置主配置文件 和 映射文件
暂时作为了解:(感觉很牛逼)
Configuration实例被设计成启动期间(startup-time)对象, 一旦SessionFactory创建完成它就被丢弃了
Hibernate自带的数据库连接池性能并不是很好:推荐自己配置数据库连接池