一. hibernate和JDBC的优缺点
1、 ormapping框架:数据库的操作框架
优点
1、代码结构比较简单
2、数据缓存:一级缓存 二级缓存 查询缓存
3、移植性比较好
缺点
1、因为sql语句是hibernate内部生成的,所以程序员干预不了,不可控
2、如果数据库特别大,不适合用hibernate
2、 jdbc的优点和缺点
缺点
1、查询代码特别繁琐
2、重复性代码特别多,频繁的try,catch
3、未做到数据的缓存
4、sql的移植性不好
优点
1、速度比较快
2、把控性比较好
二、 hibernate的jar包和配置文件
1、 拷贝所需jar包:
antlr-2.7.6.jar
backport-util-concurrent.jar
c3p0-0.9.1.jar 数据库连接池
commons-collections-3.1.jar apache的集合帮助包
commons-logging-1.1.1.jar 日志
dom4j-1.6.1.jar 解析xml文件的包
ehcache-1.5.0.jar 缓存框架
hibernate3.jar 核心包
javassist-3.9.0.GA.jar 解决代理模式的jar包,代理模式是解决懒加载的包
jta-1.1.jar
log4j.jar 日志
mysql-connector-java-5.1.10-bin.jar 数据库连接
slf4j-api-1.5.8.jar 帮助工具包
slf4j-log4j12.jar 帮助工具包
Junit
2、 *.hbm.xml(映射文件) : ormapping:对象关系映射,让关系型数据库和对象发生关联
拷贝*.hbm.xml 文件必须建立在domain中, *与当前类名称对应
打开方式: 右键 openwith---other--MyEclipse Hibernate Mapping Editor的方式打开,方便开发。
注: 第一次弄好了,要关掉, 再用同样的方式打开,然后使用提示的方式快捷开发
*对应POJO的名称
类与表的对应关系
类上的属性的名称和表中的字段的名称对应关系
类上的属性的类型和表中的字段的类型对应关系
把一对多和多对多的关系转化成面向对象的关系
注: 该类称为持久化类(POJO),须实现serializable接口,为标识接口,java虚拟机会在检测到该标识的时候会自动转化
对象的序列化作用: 让对象在网络上以二进制的形式进行传输
------------------------------------------------------------------------------------------------
配置文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
</hibernate-mapping>
------------------------------------------------------------------------------------------------
配置内容详解
class元素: 用来描述一个持久化类
属性: name:类的全名;
table:数据库中表的名称,可以不写 默认值和类名一样
catalog:数据库的名称 一般不写
子元素:
id: 描述主键标示属性 和数据库中的主键对应
属性: name 属性的名称
column 列的名称
length 长度
type 类型
子元素:
generator: 主键的产生器,就是告诉hibernate容器用什么样的方式产生主键
属性: class: 几种主键的生成方式
property:描述一般属性
属性:
name 属性的名称
column 列的名称
length 长度
type 类型
注:
1、hibernate的映射文件支持俩种类型,
java类型
hibernate内部定义了一些类型: 如string对应着java.long.String,
在解析配置文件的时候,会自动转换为java类型,直接写java类型效率高
2.主键生成器:主键生成的几种机制
注: hibernate内部是根据配置文件中的主键生成器的机制来生成主键的
在客户端设置主键的时候不一定起作用,在assigned的时候起作用
increment方式:
Hibernate: select max(pid) from Person
Hibernate: insert into Person (pname, psex, pid) values (?, ?, ?)
注: 1、主键的类型必须是数字
2、主键的生成是由hibernate内部完成的,程序猿不需要干预
3、该生成机制效率比较低
iIdentity方式:
Hibernate: insert into Person (pname, psex) values (?, ?)
注:
1、新的主键产生是由数据库完成的,并不是由hibernate或程序猿生成的
2、该表必须支持自动增长机制,需要在数据库中取消主键自动增长机制
3、效率较高
assigned方式:
Hibernate: insert into Person (pname, psex, pid) values (?, ?, ?)
注:
主键必须由程序猿手动设置其值
UUID方式:
Hibernate: insert into Person (pname, psex, pid) values (?, ?, ?)
注:
1、UUID是由hibernate内部生成的
2、主键的类型必须是String类型 持久化类和配置文件都要改
------------------------------------------------------------------------------------------------
3、 hibernate的配置文件 hibernate.cfg.xml:
作用是用来连接数据库的
要建立在src下,使用MyEclispse Hibernate Config Editor的方式打开
注: 第一次弄好了,要关掉, 再用同样的方式打开,然后使用提示的方式快捷开发
------------------------------------------------------------------------------------------------
配置文件内容如下:
<?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只能连接一个数据库 -->
<session-factory>
<!-- 数据库的用户名 -->
<property name="connection.username">root</property>
<!-- 密码 -->
<property name="connection.password">数据库密码</property>
<!-- url -->
<property name="connection.url">
jdbc:mysql://localhost:3306/数据库名称
</property>
<!-- 方言 告诉hibernate链接的mysql数据库 ,如果加此配置,则不会自动生成表 -->
<!-- <property name="hibernate.dialect">-->
<!-- org.hibernate.dialect.MySQLInnoDBDialect-->
<!-- </property>-->
<!-- 数据库连接的驱动 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 作用:根据持久化类和映射文件生成表 -->
<property name="hbm2ddl.auto">update</property>
<!-- 显示hibernate内部生成的sql语句 -->
<property name="show_sql">true</property>
<!-- hibernate中使用currentSession需要配置该内容 -->
<property name="current_session_context_class">thread</property>
<!-- 加载的映射文件 在图形编辑页面添加 -->
</session-factory>
</hibernate-configuration>
------------------------------------------------------------------------------------------------
4、 hibernate加载配置文件的俩种方式: 测试配置是否成功,生成表
------------------------------------------------------------------------------------------------
public class CreateTables {
// 创建表 配置文件在src下,且配置文件名称必须为hibernate.cfg.xml
@Test
public void testCreateTable(){
Configuration configuration = new Configuration(); // 创建configuration对象
configuration.configure(); // 加载配置文件
configuration.buildSessionFactory();
}
// 创建表 配置文件在自定义的路径下,且名称可以自定义
@Test
public void testCreateTableByUrl(){
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml的路径");
configuration.buildSessionFactory();
}
}
------------------------------------------------------------------------------------------------
5. 获取sessionFactory的工具类:注: 由子类继承即可使用sessionFactory
------------------------------------------------------------------------------------------------
public class HibernateUtil {
public static SessionFactory sessionFactory;
static{
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml的路径");
sessionFactory = configuration.buildSessionFactory();
}
}
------------------------------------------------------------------------------------------------
三、 hibernate加载流程
注意事项:
1、一个类是否是持久化类
1、加载配置文件
2、在配置文件中加载映射文件
3、解析映射文件中class元素的name属性,找到对应的类
2、在客户端的参数的类必须是持久化类
3. Configuraction 加载了配置文件
SessionFactory 配置文件的信息、映射文件的信息、持久化类的信息
Session
1、crud的操作都是由session完成的
2、事务是由session开启的
3、两个不同的session只能用各自的事务
4、session决定了对象的状态
5、创建完一个session,相当于打开了一个数据库的链接
Transaction
1、事务默认不是自动提交的
2、必须由session开启
3、必须和当前的session绑定(两个session不可能共用一个事务)
4、hibernate的原理:
根据客户端的代码,参照映射文件,生成sql语句,利用jdbc技术进行数据库的操作
四、 hibernate的CRUD操作
------------------------------------------------------------------------------------------------
@Test
public void testCRD(){
// 获取sessionFactory对象并创建session对象
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
// 开启事务
Transaction transaction = session.beginTransaction();
// 增
Person person = new Person();
person.setPname("傻逼东");
person.setPsex("男");
session.save(person);
// 删 hibernate内部会检查标识符,看标识符中的值在数据库相应的表中有没有对应的记录,如果有,则删除
Person person = (Person) session.get(Person.class, 1L);
session.delete(person);
// 改
Person person = (Person) session.get(Person.class, 2L);
person.setPsex("女");
session.update(person);
// 提交事务,并关闭session
transaction.commit();
session.close();
}
@Test
public void testQueryPersonById(){
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
// 按照主键的方式查询数据库表中的记录,第二个参数的类型必须和持久化类中标识的类型保持一致
Person person = (Person) session.get(Person.class, 1L);
System.out.println(person.getPname());
session.close();
}
@Test
public void testQueryPerson(){
SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
Session session = sessionFactory.openSession();
// 查询: 注 参数为hql语句 from 持久化类名(表对应的类 注意开头大写)
List<Person> persons = session.createQuery("from Person").list();
for(Person person : persons)
System.out.println(person.getPname());
session.close();
}
------------------------------------------------------------------------------------------------
五、 由表生成持久化类和映射文件
步骤:
1、 选中工程,点击工具栏的MyEclipse, 选中Project Capablities,再选中Add Hibernate Capablities;
2、 选中hibernate3.3, 将添加jar包的一项去了,选中add checked libraries to project build-path,next
3. 选中Existing,并导入自己的hibernate.cfg.xml文件,下面的open configuration file 选中,next
4. java package,选中自己定义的工具类包,finish;
5. 选择DB Browser视图,右键选中Hibernate Reverse Engineering反向生成,选中路径,next,
6. 选中id生成器,finish即可生成
六、 对象的状态
分为临时、持久化、脱管状态
当在代码中新创建一个对象时是临时状态,
当在执行session.save/update/get方法的时候,转换为持久化状态
当在执行session.clear方法: 把session中所有的对象清空,使其从持久化状态变成脱管状态
当在执行session.evict方法: 把session中的单个对象清空,使其从持久化状态变成脱管状态
当执行transaction.commit语句的时候,hibernate内部会检查session
如果该对象的id没有值的话,就会发出save语句,
如果该对象的id有值,并且和数据库中的值对应的话,就会发出update语句,此时hibernate内部会生成一个快照,
在进行提交时,hibernate内部会让该对象和快照进行对比,如果一样,则不发出update语句,反之,则发出update语句
注: 此时,如果未关闭session或者清空session,该对象仍未持久化状态
当session.get方法得到一个对象的时侯,是不需要再执行update语句的,因为此时已经是持久化状态
一个对象是否持久化是针对某一个session而言的,一个session对应一个事务
一个对象和session发生交互了,并不一定在数据库中有数据,要事务提交之后