先来一个hibernate的案例。
实体类Student
public class Student{
private int studentId;
private String studentName;
private int studentSex;
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentSex() {
return studentSex;
}
public void setStudentSex(int studentSex) {
this.studentSex = studentSex;
}
}
实体类映射文件:Student.hbm.xm
<?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 class="Student实体类所在的包路径">
<!--类名和表名映射,以下配置的name值严格和实体类的属性名一致-->
<class name="Student" table="t_student">
<!--类中的属性和表的主键映射-->
<id name="studentId" column="student_id">
<!--
主键生成策略:
oracle:sequence
sql:identity
mysql:increment
native:自动根据连接的数据库选择主键生成策略,有的
数据库并不支持。
-->
<generator class="sequence">
<param name="sequence">创建到数据库中序列的名称</param>
</generator>
</id>
<!--将类的普通属性映射成表相对应的字段-->
<param name="studentName" type="string" column="student_name"/>
<param name="studentSex" type="int" column="student_sex"/>
</class>
</hibernate-mapping>
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>
<property name="hibernate.conntion.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!--连接数据库密码-->
<property name="hibernate.connection.password">123</property>
<!--数据库地址-->
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
<!--连接数据库用户名-->
<property name="hibernate.connection.username">scott</property>
<!--生成sql语句数据库方言-->
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!--
根据实体类自动生成对应的表,如果表存在则不创建,若不存在则创建
-->
<property name="hbm2ddl">update</propery>
<mapping resource="实体类.hbm.xml文件路径"/>
</session-factory>
</hibernate-configuration>
TestMain.java
public class TestMain{
public static void main(String[] args){
//创建hibernate配置对象
Configuration cfg=new Configuration();
//读取hibernate中的主配置文件,如果在主配置文件配置了实体类映射文件,也会去读取实体类映射文件
cfg.configure();
//构建会话工厂
SessionFactory sf=cfg.buildSesstionFactory(cfg);
//获取与数据库的会话连接
Session session=sf.openSession();
/*
通过session对象就可以对数据库进行增删改查操作了。
进行增删改需要获取事务,并且开启事务,提交事务。因为hibernate操作数据库,默认是不提交事务
*/
//获取事务对象,并启动对象
Transaction ts=session=sf.beginTransaction();
//增删查改操作
..........
//提交事务
ts.commit();
//关闭会话
session.close();
//关闭工厂,已经在使用过程中使用的缓存
sf.close();
}
}
hibernate运行原理:
1、hibernate首先会通过Configuration对象去读取hibernate.cfg.xml主配置文件以及实体类对应的映射文件,解析这些xml文件,并将xml的信息,按照key/value的方式保存起来。
2、通过Configuratino对象中的buildSessionFactory建立会话工厂,用于创建与数据库的的会话连接。
因为在第一步中有通过Configuration对象解析配置文件,并将数据保存起来了;而这些保存的数据就含有连接数据库的信息,因此这里可以通过会话工厂对象来开启数据库会话对象。
3、设置事务,默认在获取会话连接的时候,设置默认的事务提交方式是不提交的;因此需要人为的获取到事务,并在进行完增删改操作后,显示的提交,否则数据不会被持久化到数据库中。
4、通过session对象进行数据库的增删改查。
为什么这里可以适用与所有的对象呢?其奥秘就在于实体类映射文件,也就是上述的Student.hbm.xml。session对象的增删改查,在其内部其实都是通过解析实体类映射文件,然后通过反射就可以获取所有的实体类信息,以及实体类所对应的表信息从而拼接出对应增删改查的sql语句。
5、提交事务,关闭所有的连接。