浅谈Hibernate框架

终于走到了框架这一步,很累也很开心,接触了Hibernate之后发现这种对象-关系映射的框架,我之前好像学过,在安卓中的LitePal这种轻量级的数据库与其类似,所以当学起Hibernate的时候,也不是很费劲。

Hibernate简介



什么是Hibernate?
1.Hibernate是Java领域一款开源的ORM框架。(ORM:(Object/Relationship Mapping):对象/关系映射)
2.对JDBC进行了轻量级的封装。

直接使用SQL语句不便的地方:
1.不同的数据库使用的SQL语法不同。比如:PL/SQL与T/SQL
2.同样的功能在不同的数据库中有不同的实现方法。如:分页SQL

其他主流ORM框架:
1.MyBatis:前身是著名的iBatis
2.Toplink:后被Oracle收购,并重新包装为Oracle As Toplink
3.EJB:本身是JavaEE的规范。



编写Hibernate过程



1.创建Hibernate的配置文件


<hibernate-configuration>
<session-factory>
<property name=”connection.username”>root</property> //连接数据库用户
<property name=”connection.password”></property> //连接数据库密码
<property name=”connection.driver_class”>com.mysql.jdbc.Driver</property> //加载JDBC驱动
<property name=”connection.url”>jdbc:mysql://localhost:3306/person?characterEncoding=UTF-8</property> //连接数据库的URL
</session-factory>
</hibernate-configuration>

注意:一定要把Hibernate的字符编码跟数据库的字符编码设置为一致,否则当你在表中存储中文数据的时候就存不进去,并且会报错。血的教训。
2.创建持久化类
要求:1.公有的类 2.提供公有的不带参数的默认的构造方法 3.属性私有4.属性使用get/set方法封装
3.创建对象-关系映射文件
创建一个.hbm.xml的对象-关系映射文件,然后在之前创建的Hibernate.xml的配置文件中加入<mapping resource=”关系-映射文件”/>
4.通过Hibernate API编写访问数据库的代码

Configuration config=new Configuration().configure(); //创建配置对象
ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); //创建服务注册对象
SessionFactory sessionFactory=config.buildSessionFactory(serviceRegistry); //创建会话工厂对象
Session session=sessionFactory.openSession(); //创建会话对象
Transaction transaction=session.beginTransaction(); //开启事务

Student s=new Student(); //创建一个学生对象
session.save(s); //保存对象进数据库

最终需要释放资源:
transaction.commit(); //提交事务
session.close(); //关闭会话
sessionFactory.close() //关闭会话工厂

导包:
1.Hibernate的jar包
2.mysql的jdbc驱动
3,Junit4的jar包,用于单元测试

使用Junit4进行单元测试
@Test:测试方法
@Before:初始化方法
@After:释放资源
执行顺序:Before->Test->After
注意:Junit4中可以由多个@Test,程序会按照编码顺序运行。


hibernate.cfg.xml常用配置



1.hibernate.show_sql:是否把Hibernate运行时的SQL语句输出到控制台,编码阶段便于测试。
2.hibernate.format.sql:输出到控制台的SQL语句是否进行排版,便于阅读,建议设置为true.
3.hbm2ddl.auto:可以帮助有java代码生成数据库脚本,进而生成具体的表结构。create|update|drop-create|validate 一般create和update比较常用,create表示生成新的表结构,会覆盖原来表中的数据
4.hibernate.default_schema:默认数据库
5.hibernate.dialect:配置Hibernate数据库方言,Hibernate可针对特殊的数据库进行优化。
注意:前缀hibernate可以省略不写。



Session简介



不建议使用JDBC的Connection对象来操作数据库,而是使用Session对象来操作
Session对象可以简单的理解为操作数据库的对象。
session与connection是多对一的关系,每个Session对象都有一个与之对应的Connection对象,而一个Connection对象不同时刻可供多个Session对象使用。
把对象保存到关系数据库中,需要调用Session对象的各种方法,如save(),update(),delete(),createQuery()

session详解:
如何获取session对象?
1.openSession()
2.getCurrentSession()
如果使用getCurrentSession需要在hibernate.cf.xml文件中进行配置:
如果是本地事务(jdbc事务)
<property name=”hibernate.current_session_context_class”>thread</property>
如果是全局事务(jta事务)
<property name=”hibernate.current_session_context_class”>jta</property>

openSession()跟getCurrentSession()的区别:
1.getCurrentSession()在事务提交或回滚之后会自动关闭,而openSession()需要手动关闭,若没有收到关闭,多次之后会导致连接池的溢出。
2.openSession()每次创建一个新的session对象,getCurrentSession()使用现有的session对象。


transation简介



hibernate对数据的操作是封装在事务中的,并且默认是非自动提交的方式。所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库当中。
JDBC是默认自动提交事务的,如果想要hibernate也像JDBC一样自动提交事务,必须调用session对象的doWork()方法,获得jdbc的connection对象之后,设置其为自动提交事务。(注意:通常不推荐这么做)
自动提交代码:


session.doWork(new Work(){
@Override
public void execute(Connection connection) throws SQLExpection{
connection.setAutoCommit(true);
}
});

在使用session对象保存对象之后,还需要调用session对象的flush()方法,否则保存的数据无法写入表中。

hbm配置文件常用的设置:
<hibernate-mapping
schema=”schemaName”
catelog=”catelogName”
default-cascade=”cascade_style” //级联风格
default-access=”field|property|ClassName” //访问策略
default-lazy=”true|false” //加载策略
package=“packagename”
/>

<class
name=”ClassName” //映射的类名
table=”tableName” //将类映射成数据库中表的名称
batch-size:”N” //抓取策略,一次可以抓取N条记录
where=”condition” //类似于sql语句中的where过滤器
entity-name=”EntityName” //支持同一个实体类可以映射成多个表
/>

<id //表示一张表的主键
name=”propertyName” //想要映射的属性
type=”typeName” //数据类型
column=”column_name” //映射到数据库的表中的字段的名称
length=”length” //指定的长度
<generator class=”generatorClass”> //主键生成策略
/>


主键生成策略



increment:适用于代理键,递增
identity:适用于代理主键,由底层数据库生成标识符
sequence:适用于代理主键,Hibernate根据底层数据库的序列生成标识符,这要求底层数据库支持序列
hilo:适用于代理主键。Hibernate分局high/low算法生成标识符
native:适用于代理主键,根据底层数据库对自动生成标识符的方式,自动选的identity、sequence或hilo
assigned:适用于自然主键。由Java应用程序负责生成标识符。
uuid.hex:适用于代理主键,Hibernate采用128位的UUID算法生成标识符.
uuid.string:适用于代理主键,UUID被编码成16字符长的字符串.
foreign:适用于代理主键.使用另一个相关联的对象的标识符.



Hibernate单表操作



1.单一主键:
assigned 由Java应用程序生成(手工赋值).
native 由底层数据库自动生成标识符,如果是MySQL就是increment,如果是Oracle就是squence.



组件属性



实体类中的某个属性属于用户自定义的类的对象。
<component name=”adress” class=”Adress”> //Adress为类名
<property name=”postcode” column=”POSTCODE”></property>
<property name=”phone” column=”PHONE”></property>
<property name=”adress” column=”ADRESS”></property>
</component>
注意:需要写一个Address实体类,并且属性私有,含有一个空参空体的构造函数,并设置getter/setter方法,否则会抛出InvocationTargetException异常,这是一个反射的异常,在通过反射执行方法的时,如Method.invoke(),如果被反射执行的方法体抛出了Exception,这个异常会被包装成InvocationTargetException重新抛出,这也说明Hibernate框架用到了反射。



单表CRUD操作



save()
update()
delete()
get()/load() //查询单个记录


get()与load()的区别:
1.
在不考虑缓存的情况下,get()方法会在调用之后立即向数据库发出sql语句,返回持久化对象。
load()方法会在调用之后,返回一个代理对象,代理对象只含有主键id,只有在用到非主键属性的时候,才会向数据库发送sql语句。
2.
查询数据库中不存在的数据时,get()会返回null,而load()会抛出org.hibernate.ObjectNotFoundException异常。


Hibernate基本数据类型映射表

Hibernate基本数据类型映射表 Hibernate基本数据类型映射表 Hibernate基本数据类型映射表