Hibernate零散笔记

可以建立自己的user Library。(第二集)
加入mysql的驱动mysql-connector

在数据库中建立相应的内容:
create database hibernate;

use hibernate;

create table student(id int primary key, name varchar(20),age int);

建立student类:

建立hibernate配置文件,hibernate.cfg.xml:

<?xml version=‘1.0‘ encoding=‘utf-8‘?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- Database connection settings (hibernate自动帮你链接了数据库,填入相关信息) -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">abc123</property>

<!-- JDBC connection pool (use the built-in) (hibernate的连接池) -->
<!-- <property name="connection.pool_size">1</property> -->

<!-- SQL dialect (hibernate方言,hibernate统一了sql语言,将统一语言翻译成下面填写的相应的数据库语言) -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- Enable Hibernate‘s automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache (将二级缓存disable掉) -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<!-- Echo all executed SQL to stdout (将生成的sql语句打印出来) -->
<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup (是否让hibernate自动生成ddl(建表语句)) -->
<!-- <property name="hbm2ddl.auto">update</property> -->

<mapping resource="com/bjsxt/hibernate/model/Student.hbm.xml"/>

</session-factory>

</hibernate-configuration>

还要指明object与表字段的对应关系。建立映射文件,Studnet.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.bjsxt.hibernate.model">
<class name="Student"> //找到对应的类
<id name="id" column="id" /> //id表示为主键
<property name="name" /> //property表示一般字段
<property name="age" />
</class>
</hibernate-mapping>

写测试类:

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.bjsxt.hibernate.model.Student;

public class StudentTest {
public static void main(String args[]){
Student s = new Student();
s.setId(1);
s.setName("s1");
s.setAge(1);

Configuration cfg = new Configuration();
SessionFactory sf = cfg.configure().buildSessionFactory(); //SessionFactory产生connecyion的工厂
Session session = sf.openSession();
session.beginTransaction();
session.save(s); //将对象s插入数据库
session.getTransaction().commit();
session.close();
sf.close();
}
}

annotation(利用annotation注解就可以不用*.hbm.xml文件):
建立新表:
create table teacher (id int primary key,name varchar(10),title varchar(20));

建立对象Teacher并加入注解annotation:

package com.bjsxt.hibernate.model;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity //表示实体类,对应于数据库表中的一个表
public class Teacher { //利用annotation注解就可以不用*.hbm.xml文件
private int id;
private String name;
private String title;

@Id //表示主键
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

JDBC操作数据库很繁琐
sql语句是面向关系而不是面向对象
可以再对象和关系表之间建立关系来简化变成
o/r mapping跨越数据库平台

表名与类名不同的时候,对表名进行配置
Annotation:@Table
xml:...

字段名与属性相同的时候:默认为@Basic;xml中不写column

字段名与属性名不同的时候:
Annotation:@Column
xml:...

不需要psersitence(持久化,存入数据库)的字段:
Annotation:@Transient
xml:直接不写

映射日期与时间类型,指定时间精度:
Annotation:@Temporal
xml:制定property标签的type属性

枚举类型的映射:
Annotation:@Enumerated
xml:...

注解的位置:
可以放在field(成员变量)上面,
也可以放在getxxx方法上面。

Junit4有BUG:第19个视频

ID生成策略:对应项目hibernate_0400_ID
注意:
我们观察hibernate生成表的结构并不是为了将来就用他生成(也可能还有自己的扩展,比如index),而是为了明白我们应该尽力什么样的表和实体类映射。

xml生成id:
使用generator
常用的有四个:native identity sequence uuid
annotation生成id:
@GeneratedValue
有四种取值方式:auto identity sequence(@SequenseGenrator) table(@TableGenerator)

联合主键:
xml:composite-id(要实现serializable和重写equals和hashcode)
annotation:
将类注解为@IdClass,并将该类实体中的所有属于主键的属性都注解为@Id
将组件类注解为@Embeddable.并将组件的属性注解为@Id
将组建的属性注解为@Embeddable

Hibernate的核心开发接口:
sessionFactory有两个方法得到Session:
1.openSession:每次都打开一个新的Session,用完要关闭
2.getCurrentSession:拿到当前上下文(可以在配置文件中设置current-context-class,主要有jta和thread)已有的Session或者打开一个新的Session(前一个Session被commit之后),用完不用关闭,commit()之后自动关闭。
Session是个接口,这两种方法得到的具体类可能不一样,所以不能混用
两种方法的区别很重要
区别在第26集。
JPA界定事物边界,例如数据存入和日志记录需要在同一个事物之内完成。
还有一种事物JTA,分布式数据库。

对象的三种状态:
怎么区分:
1.对象有没有ID
2.ID在数据库中有没有
3.在内存(session缓存)中有没有ID
1.transient:内存中一个对象,没ID,缓存中也没有ID
2.persistent:内存中有ID,缓存中有ID,数据库有ID
3.detached:内存有ID,缓存没有ID,数据库有ID

delete方法:
只要有ID就可以调用delete方法

get和load的区别:
get会马上执行sql语句得到对象
load会生成并返回一个代理对象,直到你取该对象的属性,这个代理才会执行sql语句得到对象
不存在对应记录的时候有区别。

update:
用来跟新detached对象,更新完成后可以转化为persistent状态
更新transient会报错
跟新自己设定ID的transient对象可以(前提是数据库有对应记录)
当一个persistent对象的字段被改变的时候,commit会检查修改,且更改全部字段。
下面的方法只让他修改相应的修改了的字段:第32个视频。

clear:
无论是load还是get,都会先查找缓存,如果没有,才会去数据库查找,调用用clear方法可以强制清除Session缓冲。

flush:
可以强制进行从内存到数据库的同步,commit时就执行一次flush。

关系映射:
对象之间的关系:

一对一:
单向:
每个Husband对应一个Wife,Wife中没有对应的Husbus,则此为单向关联
在数据库有中用外键关联
@OneToOne @JoinColumn(name="wifeId")
双向:
每个Husband对应一个Wife,Wife中也对应一个Husbus,则此为双向关联
@OneToOne(mappedBy)
联合主键:
@JoinColums
一对多(多对一):
设局库表设计:在多的一方加外键。

多对多:
单向关联:
老师和学生的关系,老师需要知道自己教了哪些学生。
双向关联:
老师知道自己教了哪些学生,学生也知道教自己的有哪些老师。

此外还可以根据单向还是双向可以非为7种。

Ctrl+Alt+下 复制这一行到下一行
Alt+下 移动这一行到下一行
powerdesigner可以用于分析代码,生成表的关系图。

关联关系中的CRUD:
设定cascade可以设定在持久化时对于对象的操作。
C--create
R--retrieve(取出load get)
U--update
D--delete
Cascade属性致命做什么操作的时候关联对象是绑在一起的
Merge=save+update
refresh=A里面需要读B改过之后的数据

铁律:双向关系在程序中要设定双向关系,双向关系设定mappedBy(在一的那一方设置)

fetch:
双向不要两边设置Eager(会有多余的查询语句发出)
对多的乙方设置fetch的时候要谨慎,结合具体情况,一帮使用Lazy不使用eager(特别情况:多方的数量不是很多的时候可以考虑,提高效率的时候可以考虑)。

O/RMapping编程模型:
1.映射模型
jap annotation
hibernate annotation extension
hibernate xml
jap xml
2.编程接口
jap
hibernate
3.数据查询:
hql
ejbql(jpql)

要删除或者更新的时候,先load,除了精确知道ID号之外。

如果要消除关联关系,先设定为NULL,在删除记录,如果不删除记录,该记录就会变成垃圾数据。第51集。

如果指定@OneToOne的属性fetch为FetchType.LAZY,会延迟对于关联对象的加载,不论使用的是load还是get。

关系映射总结:什么样的关系,设计什么样的表,进行什么样的映射。

继承映射:
1.一张表single_table
2.每个类分别一张表table_pre_class
3.每个子类一张表joined

树状结构的设计(至关重要):
在用一个类中使用one2many和many2one。

Hibernate查询(query language)
HQL&EJBQL
1.NativeSQL
2.HQL(Hibernate ql)
3.EJBql(JPql 1.0)--可认为是hql的子集
4.qbc
5.qbe

性能优化:
注意session.clear()的使用,尤其在不断分页循环的时候,否则会造成内存泄漏。
JAVA有内存泄露吗?
在语法级别上没有,但是在实际上可能会间接造成,如果他调用用了C,在调用OS,而C需要手动控制内存。

1+N问题(很重要):
第64集
解决方案:
1.设置LAZY
2.BatchSize
3.join fetch
用得最多的是1 3。

list和Iterate的区别:
1.list取所有
2.iterate先去ID,等用到的时候再根据ID来去对象
3.session中list第二次发出,仍会到数据库查询
4.iterate第二次发出,则会先找session缓存

hiberbate中有三种缓存:
1.一级缓存(Session级)

2.二级缓存(SessionFactory级)
可以跨Session存在
以下情况使用二级缓存:
1.经常被访问
2.不会经常改动
3.数量有限
如:用户权限、组织机构
hibernate.cfg.xml设定:
<property name="cache.use_second_level_cache">true</property> //打开二级缓存
<property name="cache.provider_class">org.hibernate.cache.EnCacheProvider</property> //指明使用哪种二级缓存
添加注解:
@Cache
load默认使用二级缓存,iterate默认使用二级缓存
list默认往二级缓存加数据,但是查询的时候默认不使用
3.查询缓存
只有在查询语句完全一样才有效。查询缓存依赖于二级缓存,所以必须同时打开二级缓存。
调用Query的setCachable(true)方法指明使用二级缓存。

缓存算法:(当缓存满了之后怎么办)
1.LRU:Least Recently Used(最近最少被使用的被清除)
2.LFU:Least Frequently Used(使用频率最少的被清除)
3.FIFO:First In First Out(先来的先被清除)
可以在ehcache中设置使用哪一种:
memoryStoreEvictionPolicy="LRU"

事物并发处理:
事物的特性:ACID
Atomic(原子性) Consistency(独立性) Itegrity(一致性) Durability(持久性)
事物经常出现的问题:
脏读 不可重复读 幻读
数据库的事物的隔离机制:
1:read-uncommitted
2:read-committed
4:repeatable read
8:serilizable
只要数据库支持事物,就不可能出现第一类丢失跟新。
read-uncommitted会出现dirty read,phanton-read,non repeatable read问题。
read-committed不会出现dirty read,因为只有另一个事物提交才会读出来结果,但仍然会出现phanton-read,non repeatable read.
repeatable read。
serial解决一切问题。
设定hibernate的事物隔离级别:
一般设定hibernate.connection.isolation=2 //考虑效率
用悲观素解决repeatable read的问题(依赖于数据库的锁)

Hibernate零散笔记

时间: 2024-10-14 03:44:00

Hibernate零散笔记的相关文章

Spring零散笔记

IOC(控制反转),也称DI(Denpendency Inject依赖注入).1.把自己new的东西改为由容器提供. 初始化具体bean 动态装配2.好处:灵活配置. 控制反转:将控制权交给容器依赖注入:setdao根据实际的dao注入(setdao依赖于实际的dao) spring是一个IOC容器,可以实例化具体的bean,还可以动态装配.还支持AOP:安全检查,管理transaction. FAQ:不给提示a.window-preferences-myeclipse-xml catalogb

《Hibernate学习笔记十一》:树状结构设计

<Hibernate学习笔记十一>:树状结构设计 这是马士兵老师讲解Hibernate的一个作业题,树状结构设计,这是一个比较典型的例子,因此有必要写篇博文记录下. 树状结构的设计,它是在同一个类中使用了多对一(ManyToOne)和一对多(OneToMany). 在完成这个题目我们应该按照如下的步骤进行: 1.先思考数据库的模型应该是什么样的?? 数据库中的模型应该如下:即存在id p_id 2.思考面向对象的模型,及如何来进行映射??? 根据数据库中表的特点,对象应该有id name;由于

【Thinking In Java零散笔记】对于持有对象一章中的显示系统环境变量代码分析

今天仍旧进行着学习java的计划.在学习到持有对象一章中,看到了如下代码: 1 import java.util.*; 2 3 public class EnvironmentVariables { 4 public static void main(String[] args) { 5 for(Map.Entry entry: System.getenv().entrySet()) { 6 System.out.println(entry.getKey() + ": " + 7 en

hibernate实战笔记1---初探

由于在学习Spring的时候学到有关数据库的章节的时候,提及到了hibernate的集成,但是我对hibernate技术几乎是一点不了解,只是知道它是一个orm对象映射框架,所以在初探的章节做一下hibernate的简单了解,以及应用.顺便提一句,我用的是maven添加的hibernate开发包 简单使用hibernate的一般步骤 *创建并且编辑hibernate配置文件 该配置文件主要是用于链接数据库所用,定义了数据库的驱动程序和映射文件的位置,如下是一个简单的配置 <?xml versio

《Hibernate学习笔记八》:组件映射

<Hibernate学习笔记八>:组件映射 前面介绍了一对一的单向.双向外键关联,例如,学生证和学生是一个一对一的关系.这篇博文主要是介绍下组件映射,即一个是另一个的一部分,例如,学生证的信息也可以作为学生信息的一部分,即在数据库中只存在学生一个表,而不是有学生和学生证两个表,并且这两个表中有一个一对一的关联关系. 如下: 有人或许会说,那我们就将学生和学生证的信息写在一个类中,则就不需要组件映射了,确实可以这样,但是,根据类的设计原则,我们一般都会将其设计为两个类,然后将学生证的信息作为一个

Hibernate学习笔记:第一个程序的搭建

Hibernate学习笔记:第一个程序的搭建 前一段时间对Struts2这个框架有了一点点地了解,很高兴,自己开始学习Hibernate这个框架了.本篇博文将记录下第一个Hibernate程序的搭建过程.其实有时候个人觉得无论我们学习什么语言也好,还是学习什么框架也好,第一个HelloWorld程序真的相当重要,假如 我们在学习第一个HelloWorld程序都跑不出来,这完全影响着我们对新接触的东西的兴趣和动力,但是,往往第一个程序都会涉及到很多的配置,因此使得对于初学者要摸索一定的时间,对于我

hibernate自学笔记

一.hibernate环境搭建 1.下载需要的jar包 hibernate的官方网站是http://www.hibernate.org,hibernate的jar包都可以从官方网站下载得到.推荐下载hibernate-distribution-3.3.2.GA-dist.zip,解压后目录结构 hibernate使用的核心类和接口存放在根目录下hibernate3.jar中 hibernate会使用到一些第三方类库,这些类库放在lib\required下, 名称 说明 antlr-2.7.6.j

hibernate学习笔记之三(一级缓存的使用和管理)

(hibernate学习笔记系列来自于 "疯狂Java" Hibernate视频学习) 一级缓存 一级缓存生命周期很短,与session生命周期一致,所以一级缓存也叫session级缓存或事务级缓存.位于缓存中的对象处于持久化状态,它与表中的相关记录对应,session能够在某些时间点,按照缓存中持久化对象的属性来同步数据库中表的记录,这一过程称为清理缓存. 一级缓存实现原理. session缓存是由它的实现类sessionImpl中定义的一些集合属性构成的,原理是保证有一个引用在关联

hibernate学习笔记之四(Hibernate中的类型)

(hibernate学习笔记系列来自于 "疯狂Java" Hibernate视频学习) Hibernate中的类型 在*.hbm.xml文件中,<property name="password" column="t_pass">,hibernate根据type转换将java转换成hibernate类型,然后再转换成SQL类型,<property name="password" type="...&q