[toc]
1.jar包详解
hibernate-core
hibernate-core.pnghibernate-core即为hibernate核心包,其中不包括jpa的适配,一般不需要jpa即可使用此包,hibernate相对mybatis较重量级,依赖的外部包较多。其中hibernate-jpa-2.1并非hibernate的jpa适配包,仅仅是java的jpa规范包,近乎弱智般改了个名字。
hibernate-entitymanager
依赖于hibernate-core包(同样继承core的依赖),其实现了jpa规范,若需要使用jpa,则放入此包。
2.主配置文件
Hibernate的配置文件则主要用来配置数据库连接以及Hibernate运行时所需要的各个属性的值。
默认情况下,于工程路径下(classes根路径下)创建hibernate.cfg.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- 在类的根路径下创建名称为hibernate.cfg.xml的配置文件
导入约束:dtd约束
-->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--1. 数据库连接信息 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1634</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!--数据库方言-->
<!--2. hibernate可选配置 -->
<property name="hibernate.show_sql">true</property> <!--是否显示生成的sql -->
<property name="hibernate.format_sql">false</property> <!--是否格式化输出sql语句到控制台 -->
<property name="hibernate.hbm2ddl.auto">update</property> <!--是否自动建表(会自动更新表结构,但是不会更新数据类型) -->
<property name="hibernate.connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property> <!--很奇怪,明明不存在该class,应该是org.hibernate.C3P0.internal.C3P0ConnectionProvider才对 -->
<property name="current_session_context_class">thread</property> <!--session与线程绑定 -->
<!--如果使用jpa注解做映射文件,则使用class属性即可 -->
<!-- <mapping class="com.fr.elijah.entity.Customer"/>-->
<!--
事务隔离级别
hibernate.connection.isolation = 4(默认值)
1—Read uncommitted isolation
2—Read committed isolation
4—Repeatable read isolation
8—Serializable isolation
-->
<property name="hibernate.connection.isolation">4</property>
<!--3. 映射文件 -->
<mapping resource="com\fr\elijah\entity\customer.hbm.xml"/><!--只有window下可以反斜杠-->
<mapping resource="com/fr/elijah/entity/linkMan.hbm.xml"/>
<mapping resource="com/fr/elijah/entity/sysUser.hbm.xml"/>
<mapping resource="com/fr/elijah/entity/sysRole.hbm.xml"/>
</session-factory>
</hibernate-configuration>
配置文件的key都是在hibernate的开发包中project文件夹下的etc目录中的hibernate.properties
1.数据库连接信息
其中hibernate.dialect指定数据库方言,虽然数据库都支持标准sql,但是一些语法还是存在一些差异,比如标准sql不支持分页,mysql的分页可以使用limit,Oracle则需要使用行内视图的方式来进行分页,方言就是为了这种区别。默认会通过数据库信息来指定方言,见org.hibernate.engine.jdbc.dialect.internal.StandardDialectResolver#resolveDialect以及org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl
2.一些可选配置
- hibernate.hbm2ddl.auto
用于指定启动时表结构处理, 取值如下:
* none:不用Hibernate自动生成表.
* create:每次都会创建一个新的表.(测试)
* create-drop:每次都会创建一个新的表,执行程序结束后删除这个表.(测试)
* update:如果数据库中有表,使用原来的表,如果没有表,创建一个新表.可以更新表结构(不会更新数据类型,但是可以更新约束)。
* validate:只会使用原有的表.对映射关系进行校验.
- hibernate.connection.provider_class
数据库连接池设置
指定c3p0时明明不存在org.hibernate.connection.C3P0ConnectionProvider,只存在org.hibernate.C3P0.internal.C3P0ConnectionProvider,不知道做了何种兼容
检验是否配置了连接池:
public void testConnection() {
Session session = HibernateUtil.openSession();
// Hibernate中使用jdbc原始api
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
System.out.println(connection.getClass().getName());
}
});
}
-
事务隔离级别
hibernate.connection.isolation = 4(默认值) 1—Read uncommitted isolation 2—Read committed isolation 4—Repeatable read isolation 8—Serializable isolation
默认值即为可重复读
3.映射文件路径
路径必须是斜杠式(正反都行)包名+映射文件名,也可以不指定然后代码中通过Configuration.addResource添加路径。
4.主配置文件路径
如果想要自定义路径或者名称,则可以使用Configuration(String)构造方法传递路径(斜杠式(正反都行)包名+文件名)。
主配置文件其实也可以是properties文件,但是由于properties文件中没法指定映射文件(因为properties文件的key唯一),只能通过addResource()添加映射文件
3.映射文件编写
<?xml version="1.0" encoding="UTF-8"?>
<!-- 导入约束:dtd约束
位置:在Hibernate的核心jar包中名称为hibernate-mapping-3.0.dtd
明确该文件中的内容:
实体类和表的对应关系
实体类中属性和表的字段的对应关系
-->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.itheima.domain"><!-- package属性用于设定包的名称,接下来该配置文件中凡是用到此包中的对象时都可以省略包名 -->
<!-- class标签
作用:建立实体类和表的对应关系
属性:
name:指定实体类的名称
table:指定数据库表的名称
-->
<class name="Customer" table="cst_customer">
<!-- id标签
作用:用于映射主键
属性:
name:指定的是属性名称。也就是get/set方法后面的部分,并且首字母要转小写。
column:指定的是数据库表的字段名称
-->
<id name="custId" column="cust_id">
<!-- generator标签:
作用:配置主键的生成策略。
属性:
class:指定生成方式的取值。
取值之一:native。使用本地数据库的自动增长能力。
mysql数据库的自动增长能力是让某一列自动+1。但是不是所有数据库都支持这种方式。
-->
<generator class="native"></generator>
</id>
<!-- property标签:
作用:映射其他字段
属性:
name:指定属性的名称。和id标签的name属性含义一致
column:指定数据库表的字段名称
-->
<property name="custName" column="cust_name"></property>
<property name="custLevel" column="cust_level"></property>
<property name="custSource" column="cust_source"></property>
<property name="custIndustry" column="cust_industry"></property>
<property name="custAddress" column="cust_address"></property>
<property name="custPhone" column="cust_phone"></property>
</class>
</hibernate-mapping>
1.package属性用于设置包名,该配置文件中的用到的此包下的类都可以省略包名
4.代码运行
/**
* 1. 解析主配置文件
* 2. 根据配置文件生成SessionFactory
* 3. 创建session
* 4. 开启事务
* 5. 执行操作
* 6. 提交事务
* 7. 释放资源
*/
public void test1() {
Configuration cfg = new Configuration();//只是创建,不会加载配置文件
cfg.configure(); //加载配置文件
cfg.addResource("com/fr/elijah/entity/customer.hbm.xml");
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Customer customer = new Customer();
customer.setCustName("Elijah11");
customer.setCustSource("6");
session.save(customer);
tx.commit();
session.close();
sessionFactory.close();
}
1.Configuration
代表着配置文件,cfg.configurate()方法会去加载根路径下的hibernate.cfg.xml主配置文件, 如果要自定义主配置文件则使用cfg.configurate("xxx");
也可以通过cfg的addResource("xxx")方法手动加载映射文件.
2.SessionFactory
sessionFactory是根据主配置文件生成的session工厂类,SessionFactory接口负责Hibernate的初始化和建立Session对象。它在Hibernate中起到一个缓冲区作用,Hibernate可以将自动生成的SQL语句、映射数据以及某些可重复利用的的数据放在这个缓冲区中。同时它还保存了对数据库配置的所有映射关系,维护了当前的二级缓存。
同时,它是一个线程安全的对象,所有由该工厂生产的Session都共享工厂中维护的数据。
由于SessionFactory维护了很多信息同时又是线程安全的,一般情况下,一个项目中只需要一个SessionFactory,只有当应用中存在多个数据源时,才为每个数据源建立一个SessionFactory实例。因此,不应该反复的创建和销毁
网友评论