Hibernate快速入门
一、Hibernate的介绍
Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架。
ORM:Object Relational Mapping,对象关系映射
优点:
- Hibernate是基于jdbc的主流持久化框架。
- Hibernate是一个开源的ORM框架,。
- Hibernate对JDBC数据库的操作进行了封装,简化了数据库操作的代码,提高了开发效率。
- 程序员能够利用Hibernate框架更好的使用面向对象的编程思维来操纵数据库。
二、 Hibernate使用入门
- 创建java项目
- 导入Hibernate所需jar包与数据库驱动连接
- 创建数据库表
- 创建javaBean实体类
- 编写数据库表与javaBean实体类的映射(配置)文件
- 编写Hibernate的核心配置文件
- 使用Hibernate
1. 导入jar包
- 数据库驱动
- Hibernate所需jar包
- 日志记录jar包
2. 创建数据库表
CREATE DATABASE hibernate_day01;
USE hibernate_day01;
CREATE TABLE USER(
uid INT PRIMARY KEY AUTO_INCREMENT,
uname VARCHAR(20),
upassword VARCHAR(20)
);
3. 创建实体类(略)
4. 编写数据库表与javaBean实体类的映射(配置文件)
-
在javaBean的同级目录下创建文件名为
实体类名.hbm.xml
的配置文件.如:User.hbm.xml -
导入配置文件的DTD约束:mapping
-
class标签
定义javaBean与数据库表的映射 -
id标签
定义javaBean与数据库表中的主键的映射关系 -
property标签
定义普通字段的映射关系<?xml version="1.0" encoding="UTF-8"?> <!-- 引入DTD约束 --> <!-- 找到buildPath之后的Hibernate的Liberaries,打开hibernate的核心包:hibernate-core-5.0.7.Final.jar --> <!-- 打开和新包下的org.hibernate包,找到dtd结尾的映射配置文件mapping.dtd与hibernate的核心配置文件configuration.dtd --> <!-- 找到两个文件的dtd约束,copy到对应的xml配置文件中 --> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- 创建javaBean实体类与数据库表的映射 --> <class name="com.itdream.domain.User" table="user"> <!-- javaBean与表的主键的映射,相同时,column可省略 --> <id name="uid" column="uid"></id> <!-- 创建javaBean于表的普通字段的映射,相同时column可省略 --> <property name="uname" column="uname"></property> <property name="upassword" column="upassword"></property> </class> </hibernate-mapping>
5. 编写Hibernate的核心配置文件
- 在src目录下创建文件名为 ``hibernate.cfg.xml```的配置文件.
- 导入配置文件的DTD约束:configuration
-
<hibernate-mapping></hibernate-mapping>标签中分为三部份:以property标签标记
-
必要的配置信息 : 连接数据库的基本参数
-
Hibernate的属性
2.1 : Hibernate的方言 : 根据配置生成对应的SQL语句,实现了跨数据域,切换数据库只需更改这里的配置即可
-
Hibernate加载映射文件,
<maping resource="相对路径" />
-
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入DTD约束 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Hibernate核心配置 -->
<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_day01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 2. 与本地线程绑定 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 3. Hibernate的属性 -->
<!-- Hibernate的方言:根据配置的方言生成对应的SQL语句.实现了跨数据库 .切换数据库时只需要更改此处的配置即可-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Hibernate显示SQL语句 -->
<property name="hibernate.show_sql">true</property>
<!-- Hibernate格式化SQL语句 -->
<property name="hibernate.format_sql">true</property>
<!-- Hibernate的hbm2ddl,定义hibernate对数据库表格的创建方式,开发一般用none -->
<!-- 取值:none,create,create-drop,update,validate -->
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- 4. Hibernate加载映射 -->
<mapping resource="com/itdream/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
6. 使用Hibernate完成用户User的注册
- 创建Hibernate的配置对象Configuration
- 通过配置对象,获取SessionFactory工厂对象
- 通过工厂对象获取Session对象
- 开启事务
- 实现自己的业务逻辑
- 提交事务
- 关闭资源
代码实现:
@Test
//Hibernate入门案例,存储用户到MySQL数据库
public void test01() {
//1. 创建Hibernate配置对象
Configuration configuration = new Configuration();
//默认加载放在src下以hibernate.cfg.xml命名的Hibernate核心配置文件
//1.1 加载配置文件
configuration.configure();
//2. 通过配置对象创建SessionFactory对象
SessionFactory sessionFactory = configuration.buildSessionFactory();
//3. 通过工厂对象获取Session对象
Session session = sessionFactory.openSession();
//4. 开启事务
Transaction transaction = session.beginTransaction();
//5. 实现自己的业务逻辑
User user = new User();
user.setUname("唐嫣");
user.setUpassword("123");
//实现了insert into user values(null,'唐嫣','123')的操作
session.save(user);
//6. 提交事务
transaction.commit();
//7. 释放资源
session.close();
sessionFactory.close();
}
三、Hibernate配置文件如何导入DTD约束
- 导入Hibernate的jar包后build path会产生对应的liberary
- 在liberary中找到Hibernate的核心jar
hibernate-core-5.0.7.Final.jar
- 找到核心jar中的
org.hibernate包
,点击打开这个包 - 分别找到
hibernate-mapping-3.0.dtd
和hibernate-configuration-3.0.dtd
的dtd约束 - copy两个dtd文件中的约束
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-configuration-3.0.dtd:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
6.点开eclipse的window的prference的属性,设置约束的编写提示。
7.找到xml catalog的窗口,点击add
8.将约束中双引内的http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd 或(mapping) 填入key的输入框,key type选URI,Location选择FileSystem找到对应的DTD文件导入即可.
导入DTD编写提示二四、 Hibernate的相关API
1. Configuration对象
-
用于配置并且启动Hibernate框架。
-
Hibernate框架通过该对象来获得对象-关系映射文件中的元数据,以及动态配置Hibernate的属性。
-
可以创建SessionFactory对象。
//获取Configuration对象
Configuration conf = new Configuration();//加载配置文件: 以默认方式加载,配置文件必须放在src目录下,并以hibernate.cfg.xml命名
conf.configure();//推荐:conf.configure(String path);//不推荐
-
如果
hibernate.cfg.xml
中没有使用mapping标签
加载映射文件,可以使用该配置对象加载。configuration.addResource(String path);
不推荐该方式,推荐在核心配置文件中直接配置映射文件的加载路径。
2. SessionFactory : Session工厂对象
SessionFactory接口负责Hibernate的初始化,以及创建Session对象。它在Hibernate中起到一个缓冲区的作用,Hibernate可以将自动生成的SQL语句、映射语句以及某些可以可重复利用的数据放在这个缓冲区中。同时它还保存了对数据库配置的所有映射关系,维护了二级缓存。
SessionFactory的实例通过Configuration获取:
SessionFactory factory = configuration.buildSessionFactory();
Session具有以下特点:
1. 它是线程安全的,他的同一个实例可以被多个线程共享。
2. 它是重量级的,因此不能随意的销毁和创建。
由于这个特点,因此一个项目中只需要一个SessionFactory对象,因此对其抽取一个工具类,使其只创建一次,并且能够提供Session对象。
/**
* 1. 完成SessionFactory的初始化
* 2. 提供Session对象的获取
*/
public class HibernateUtils {
//声明SessionFactory对象,将其实例化放在static静态代码块中,保证其在一开始就完成初始化
private static SessionFactory sf = null;
static {
//1. 创建Hibernate配置对象
Configuration configuration = new Configuration();
//2. 加载配置文件:hibernate.cfg.xml,默认加载src目录下的hibernate.cfg.xml
configuration.configure();
//3. 实例化SessionFactory对象
sf = configuration.buildSessionFactory();
//4. 关闭虚拟机时,释放SessionFactory
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
System.out.println("虚拟机关闭,释放SessionFactory资源");
sf.close();
}
}));
}
//提供获取Session对象的方法
public static Session openSession() {
return sf.openSession();
}
//获得当前线程中的绑定的Session
//注意:必须配置
//return
public static Session getCurrentSession() {
return sf.getCurrentSession();
}
}
3. Session对象
Session是应用程序与数据库之间交互操作的一个单线程对象,它的主要功能是为持久化对象提供增,删,改,查的操作。
通过SessionFactory对象获得Session对象,获取Session实例有两种方式:
1. 采用openSession方式:
Session session = sessionFactory.openSession();
2. 采用getCurrentSession方式:
Session session = sessionFactory.getCurrentSession();
他们的区别:
1. openSession获取的Session对象,SessionFactory会直接创建一个Session实例,在使用完成后需要调用close方法手动关闭。
2. getCurrentSession方法获取的Session对象实例会被绑定到当前线程中,它在事务提交或回滚后会自动删除。
Session是线程不安全的,多个并发线程同时操作一个Session对象会导致Session数据存取的混乱,(方法内部定义与使用Session对象时,不会出现线程问题),因此应该避免成员位置定义Session,而在局部位置定义Session对象实例,从而避免线程问题。
Session对象的几个API方法:
- save(obj) : 增
- get/load(obj,id) : 取
- delete(obj) : 删,两种方式,直接删,先获取再删除.推荐先获取在删除。
- update(obj) : 改,两种方式,直接修改,先获取再修改.推荐先获取再修改.防止数据丢失
- createQuery("hql") : 获得Query对象
- createCriteria(Class) : 获得Criteria对象
测试:
public class HibernateTest2 {
@Test
//使用Hibernate向数据库中保存数据
public void save() {
//1.创建Hibernate配置对象
//2.创建SessionFactory对象
//3.获取Session对象
Session session = HibernateUtils.openSession();
//4.开启事务
Transaction transaction = session.beginTransaction();
//5.实现业务逻辑
User user = new User();
user.setUname("林志玲");
user.setUpassword("123");
session.save(user);
//6.提交事务
transaction.commit();
//7.关闭资源
session.close();
}
@Test
//根据主键获取user对象
public void get() {
//1. 获取Hibernate配置对象
//2. 通过配置对象获取SessionFactory工厂对象
//3. 获取Session对象
Session session = HibernateUtils.openSession();
//4. 开启事务
Transaction transaction = session.beginTransaction();
//5. 实现业务逻辑
//参数1:javaBean的实体类 ; 参数2: 序列化,根据表的主键查找对应的javaBean对象
User user = session.get(User.class, 1);
System.out.println(user);
//6. 提交事务
transaction.commit();
//7. 释放资源
session.close();
}
@Test
//根据主键获取user对象
public void load() {
//1. 创建配置对象
//2. 通过配置对象获取SessionFactory工厂对象
//3. 获取Session对象
Session session = HibernateUtils.openSession();
//4. 开启事务
Transaction transaction = session.beginTransaction();
//5. 实现业务逻辑
//与get用法一致
User user = session.load(User.class, 2);
System.out.println(user);
//6. 提交事务
transaction.commit();
//7. 关闭资源
session.close();
}
//根据主键更改user对象的值
@Test
public void update() {
//1.获取Hibernate配置对象
//2.通过配置对象获取SessionFactory工厂对象
//3.获取Session对象
Session session = HibernateUtils.openSession();
//4.开启事务
Transaction transaction = session.beginTransaction();
//5.实现业务逻辑
//首先通过主键获取到对象,然后在对对象进行修改,这样在更改对象的值的时候就不会发生丢失
User user = session.get(User.class, 1);
user.setUpassword("999");
session.update(user);
//6.提交事务
transaction.commit();
//7.释放资源
session.close();
}
@Test
//根据主键删除对应user对象
public void delete() {
//1. 获取Hibernate配置对象
//2. 通过配置对象获取SessionFactory工厂对象
//3. 获取Session对象
Session session = HibernateUtils.openSession();
//4. 开启事务
Transaction transaction = session.beginTransaction();
//5. 实现业务逻辑
//首先获取到这个要删除的对象然后删除
User user = session.get(User.class, 2);
session.delete(user);
//6. 提交事务
transaction.commit();
//7. 关闭资源
session.close();
}
}
get与load的区别:
get方法 : 立即加载策略:执行get,立即发送SQL语句
load方法 : 延迟加载(懒加载):执行load,不会发送sql语句;只要在真正使用数据的时候,才会发送sql语句。
4. Transction
负责事务管理
-
常用API :
- beginTransction() : 开启事务
- commit() : 提交事务
- roolback() : 回滚事务
-
特点
- Hibernate框架默认情况下事务不自动提交,需要手动提交事务
- 如果没有开启事务,每一个Session操作,都相当于一个独立的事务
- 每段事务隐藏着异常,需要手动添加try/catch
五、Hibernate整合C3P0实现连接池
hibernate中可以使用默认的连接池,无论功能与性能都不如C3PO。
步骤:
- 找到Hibernate中的c3p0的jar包添加到项目中
- 修改hibernate.cfg.xml的配置文件,添加属性,Hibernate会自动发现所配置的信息,选择c3p0作为连接池。
<!-- C3P0的供应商 -->
<property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
<!-- 最小连接 -->
<property name="hibernate.c3p0.min_size">5</property>
<!-- 最大连接数 -->
<property name="hibernate.c3p0.max_size">20</property>
<!-- 连接超时时长 -->
<property name="hibernate.c3p0.timeout">120</property>
<!-- 每120秒检查空闲连接 -->
<property name="hibernate.c3p0.idle_test_period">120</property>
<!-- 最大statments数量 -->
<property name="hibernate.c3p0.max_statements">120</property>
<!-- 连接用完后,每次增加的连接数 -->
<property name="hibernate.c3p0.acquire_increment">2</property>
<!-- 每次都验证连接是否可用 -->
<property name="hibernate.c3p0.validate">false</property>
3.查看连接池是否起作用
方法1:
修改log4j的log4j.properties,修改log4j.rootLogger=Info,这样降低记录与显示日志的级别.
运行程序时如果能看到控制台出现[org.hibernate.connection.C3P0ConnectionProvider]说明
Hibernate已经选择了C3P0作为连接池
方法1
方法2:
在mysql中使用命令show processlist查看连接数,如连接池中配置最小5个连接时将显示:
方法2
六、 日志集成
- JCL规范。Java Commen logger
- SLF4J规范。Simple Logger fade for Java。
- log4j:实现。
规范的出现是因为在一个程序中多个框架用到了不同的日志系统,日志杂乱。规范提供统一解决方案。
规范和实现的整合,需要中间整合桥梁。
Log4j与slf4j集成步骤:
-
导入jar包
- slf4j-api-x.x.x.jar : 规范接口jar
- slf4j-log4j12-x.x.x.jar : log4j与Slf4j整合的jar
- log4j-x.x.x.jar : log4j实现日志规范的jar
-
在src目录下编写log4j.properties配置文件
##设置日志记录到控制台的方式 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ##设置日志记录到文件的方式 log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ##日志输出的级别,以及配置记录方案 log4j.rootLogger=info, stdout, file
-
代码中调用Log4j
-
初始化(引入的包为slf4j的,使用规范接口编程)
Logger logger = LoggerFactory.getLogger(Clazz);
-
调用
logger.trace(); logger.debug(); logger.info(); logger.warn(); logger.error();
-
日志级别:
trance
debug
info
warn
error
fatal
Log4j日志配置规则介绍【参考log4j介绍】:
日志记录器:rootLogger
日志输出源:appender
日志布局器:layout
真实使用导入jar包,配好log4j.properties就可以使用c3p0连接池了.
网友评论