Hibernate核心API
一、Configuration:Hibernate配置对象
Configuration 类的作用是对Hibernate 进行配置,以及对它进行启动。在Hibernate
的启动过程中,
Configuration
类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。虽然Configuration
类在整个Hibernate 项目中只扮演着一个很小的角色,但它是启动hibernate 时所遇到的第一个对象
1、作用:加载核心配置文件
如果加载的是:hibernate.properties
Configuration cfg = new Configuration ();
//手动加载映射
cfg.addResource("com/itzheng/hibernate/demo01/Customer.hbm.xml");
如果加载的是:hibernate.cfg.xml
Configuration cfg = new Configuration ().configuer();
在hibernate.cfg.xml当中
没有设置mapping的时候
//手动加载映射
configuration.addResource("com/itzheng/hibernate/demo01/Customer.hbm.xml");
二、SessionFactory:session工厂
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
SessionFactory内部维护了hibernate的链接池和hibernate的二级缓存(二级缓存用的不多已被替代)线程安全的对象,一个项目只需要创建一个
1、配置链接池(了解 后面交给Spring)
默认已经配好了也可以手动配置
手动配置如下
在核心配置文件当中hibernate.cfg.xml
<!-- 配置C3P0连接池 -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
然后引入
c3po的jar,hibernate自带
测试相关代码可以在控制台看到c3po相关的配置
2、抽取工具类
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/*
* Hibernate的工具类
*/
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session openSession() {
return sf.openSession();
}
}
测试工具类
Transaction(数据库事务)
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具类的一个测试
*/
public class HibernateDemo02 {
@Test
// 保存客户
public void demo01() {
//获取到数据库的链接
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();//创建数据库事务对象开启事务
Customer customer = new Customer();//自定义与数据库匹配的类
customer.setCust_name("王小东");
session.save(customer);
tx.commit();//提交事务
session.close();
}
@Test
// 查询:
public void demo02() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();// 创建数据库事务对象开启事务
// 使用get方法来进行查询
/*
* Customer customer = session.get(Customer.class, 1l);
* System.out.println(customer);
* System.out.println("===========================");
*/
// 使用load方法查询
Customer customer = session.load(Customer.class, 1l);//发送SQL语句
System.out.println(customer);
tx.commit();// 提交事务
session.close();
}
}
三、Session:类似Connection对象是链接对象(实现Hibbernate和数据库建立连接)
Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。
但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session。
Session代表的是Hibernate与数据库的链接对象。不是线程安全 (Session对象不可以定义为全局变量)使用该对象的时候必须为局部变量
Session是与数据库交互的一个桥梁
1、Session的API
可以到Hibernate的API文档当中找到关于Session的介绍
A、保存方法:
Serializable save(Object obj);
Serializable id = session.save(customer);
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具类的一个测试
*/
public class HibernateDemo02 {
@Test
// 保存客户
public void demo01() {
//获取到数据库的链接
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();//创建数据库事务对象开启事务
Customer customer = new Customer();//自定义与数据库匹配的类
customer.setCust_name("王小东");
session.save(customer);
tx.commit();//提交事务
session.close();
}
}
B、查询的方法:
T get(Class c,Serializable id);
T load(Class c,Serializable id);
测试代码:
使用get方法来查询
使用load方法来查询
—》get方法和load方法的区别?使用Debug分别测试get方法和load方法
get方法
采用的是立即加载,执行到这行代码的时候,就会马上发送SQL语句去查询
查询后返回的是真实对象本身
查询一个找不到的对象的时候会返回null
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具类的一个测试
*/
public class HibernateDemo02 {
@Test
// 查询:
public void demo02() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();// 创建数据库事务对象开启事务
// 使用get方法来进行查询
Customer customer = session.get(Customer.class, 1l);
System.out.println(customer);
System.out.println("===========================");
tx.commit();// 提交事务
session.close();
}
}
load方法
采用的是延迟加载(lazy懒加载),执行到这行代码的时候不会发送SQL语句,当真正使用该对象的时候才会发送SQL语句
获取其id的时候也不会发送SQL语句,但是获取其他属性的时候就会发生SQL语句
load方法查询后返回的是 代理对象。
使用的是这个包产生的代理,利用javassist技术产生的代理。
查询一个找不到的对象的时候会返回对象找不到的异常(ObjectNotFoundException)
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itzheng.hibernate.demo01.Customer;
import com.itzheng.hibernate.utils.HibernateUtils;
/*
* Hibernate工具类的一个测试
*/
public class HibernateDemo02 {
@Test
// 查询:
public void demo02() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();// 创建数据库事务对象开启事务
// 使用load方法查询
Customer customer = session.load(Customer.class, 1l);//发送SQL语句
System.out.println(customer);
tx.commit();// 提交事务
session.close();
}
}
C、修改方法
void update(Object obj);
第一种修改方式(覆盖所有的值,包括没有修改的值,如果没有设置,则会被赋予null)
public void demo03() {
Session session = HibernateUtils.openSession();// 获取数据库的链接
Transaction transaction = session.beginTransaction();// 开启事务
// 1、创建对象进行修改 只是修改一个的话其他没有设置对应的值会别默认覆盖为null
Customer customer = new Customer();
customer.setCust_id(1l);
customer.setCust_name("王村");
session.update(customer);
transaction.commit();// 提交事务
session.close();// 关闭链接
}
第二种修改方式(先查询然后再修改)
// 修改操作
public void demo03() {
//session可以理解为是将数据放入到session对象当中
Session session = HibernateUtils.openSession();// 获取数据库的链接
Transaction transaction = session.beginTransaction();// 开启事务
// 1、创建对象进行修改 只是修改一个的话其他没有设置对应的值会别默认覆盖为null
/*
* Customer customer = new Customer(); customer.setCust_id(1l);
* customer.setCust_name("王村"); session.update(customer);
*/
// 先查询,在修改(一般推荐使用先查询再修改的方式)
Customer customer = session.get(Customer.class, 1l);//先将数据库当中对应id的数据查询出来方到customer对象当中
customer.setCust_name("王小键");//将对应的数据存放到查询到的对象当中
session.save(customer);//再次将该对象放入到数据库当中
transaction.commit();// 提交事务
session.close();// 关闭链接
}
D、删除方法
void delete(Object obj);
第一种删除方式
// 删除操作
public void demo4() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//直接创建对象,删除
Customer customer = new Customer();
customer.setCust_id(1l);
session.delete(customer);//删除对应id的数据
//直接创建再删除
tx.commit();
session.close();
}
第二种删除方式
// 删除操作
public void demo4() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//直接创建对象,删除
/*
* Customer customer = new Customer(); customer.setCust_id(1l);
* session.delete(customer);//删除对应id的数据
*/
//先查询再删除
Customer customer = session.get(Customer.class, 2l);//将数据当中的数据与Customer字节码文件进行匹配
session.delete(customer);//删除查询到的customer对象
tx.commit();
session.close();
}
E、保存或更新
void saveOrUpdate(Object obj);
第一种没有设置id(保存)
会单纯的实现保存功能在已有的数据后面
@Test
// 保存
public void demo05() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer(); customer.setCust_name("王菲");
session.saveOrUpdate(customer);
transaction.commit();
session.close();
}
设置id并且是数据表当中已有的id(会实现更新该数据)
会覆盖对应的数据如果没有设置会覆盖为null
@Test
// 更新
public void demo05() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_id(3l);
customer.setCust_name("李芬");
session.saveOrUpdate(customer);
transaction.commit();
session.close();
}
F、查询所有
void createQuery(“from Customer”);
// 查询所有
public void demo06() {
// 加载核心配置文件hibernate.cfg.cml
Configuration configuration = new Configuration().configure();
// 创建sessionFactory对象,类似于JDBC当中的连接池
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 通过sessionFactory获取session对象,类似于我们JDBC中的Connection
Session session = sessionFactory.openSession();
// 手动开启事务
Transaction transaction = session.beginTransaction();
// 接收一个HQL:Hibernate Query Language 面向对象的查询语言
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
System.out.println("====================================");
// 同时也可以使用SQL语句
SQLQuery createSQLQuery = session.createSQLQuery("select * from cst_customer");
List<Object[]> list2 = createSQLQuery.list();
for (Object[] objects : list2) {
System.out.println(Arrays.toString(objects));
}
transaction.commit();// 提交事务
session.close();// 关闭链接池
}
四、Transaction:事务对象
Transaction 接口是一个可选的API,可以选择不使用这个接口,取而代之的是Hibernate 的设计者自己写的底层事务处理代码。
Transaction 接口是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA
中的UserTransaction、甚至可以是CORBA
事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面,使得自己的项目可以在不同的环境和容器之间方便地移植。
Hibernate当中去管理事务的对象。
对应文档当中的方法
常用方法:
1、commit():提交事务
2、rollback ():回滚事务
Hibernate其他API(解决事务当中的问题)
以下API在运行的时候需要配置好核心文件当中
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<!-- 链接数据库的基本参数 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day02</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<!-- 配置hibernate的方言的 目的是生成对应不同数据的语句 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 可选配置 -->
<!-- 打印SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- 自动创建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 配置C3P0连接池 -->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!--在连接池中可用的数据库连接的最少数目 -->
<property name="c3p0.min_size">5</property>
<!--在连接池中所有数据库连接的最大数目 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库连接的过期时间,以秒为单位,
如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
<!-- 设置事务隔离级别 -->
<property name="hibernate.connection.isolaction">4</property>
<!-- 配置当前线程来绑定的session -->
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="com/itzheng/hibernate/demo01/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
以及准备好对应的工具类
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session openSession() {
return sf.openSession();
}
public static Session getCurrentSession() {
return sf.getCurrentSession();
}
}
一、Query
Query接口用于接收HQL,查询多个对象。
HQL:Hibernate Query Language :Hibernate查询语言。这种语言与SQL的语法及其类似,是一个面向对象的查询语言。
1、查询所有表当中信息
public class HibernateDemo5 {
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
String hql = "from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
}
2、查询指定字符的数据(条件查询)
/*
* Hibernate的其他的API
*/
public class HibernateDemo5 {
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
// String hql = "from Customer";
String hql = "from Customer where cust_name like ?";
Query query = session.createQuery(hql);
query.setParameter(0, "王%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
}
分页查询
/*
* Hibernate的其他的API
*/
public class HibernateDemo5 {
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
//分页查询
String hql = "from Customer";
Query query = session.createQuery(hql);
//设置分页
query.setFirstResult(0);//相当于MySQL当中limit的第一个参数
query.setMaxResults(3);
//query.setParameter(0, "王%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
}
改变初始值
@Test
// Query
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session活动Query接口
//分页查询
String hql = "from Customer";
Query query = session.createQuery(hql);
//设置分页---》会根据不同的数据库切换SQL语句
query.setFirstResult(3);//相当于MySQL当中limit的第一个参数
query.setMaxResults(3);
//query.setParameter(0, "王%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
二、Criteria
Criteria:QBC(Query By Criteria);
更加面向对象的一种查询方式。
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
Criteria criteria = session.createCriteria(Customer.class);// 返回
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
条件查询
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
Criteria criteria = session.createCriteria(Customer.class);//先获取到criteria的Customer对象
//criteria.add(Restrictions.like("cust_name", "王%"));//设置对应的查询的条件
criteria.add(Restrictions.like("cust_name", "王",MatchMode.START));//在这里上下这两种设置条件的方式实现的功能一致
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
分页查询
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
/*
* Criteria criteria = session.createCriteria(Customer.class);// 返回
* List<Customer> list = criteria.list();
*/
Criteria criteria = session.createCriteria(Customer.class);//先获取到criteria的Customer对象
//criteria.add(Restrictions.like("cust_name", "王%"));//设置对应的查询的条件
criteria.add(Restrictions.like("cust_name", "王",MatchMode.START));//在这里上下这两种设置条件的方式实现的功能一致
criteria.setFirstResult(0);
criteria.setMaxResults(3);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
修改初始值
@Test
// Criteria
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 通过Session获得Criteria接口
/*
* Criteria criteria = session.createCriteria(Customer.class);// 返回
* List<Customer> list = criteria.list();
*/
Criteria criteria = session.createCriteria(Customer.class);//先获取到criteria的Customer对象
//criteria.add(Restrictions.like("cust_name", "王%"));//设置对应的查询的条件
criteria.add(Restrictions.like("cust_name", "王",MatchMode.START));//在这里上下这两种设置条件的方式实现的功能一致
criteria.setFirstResult(3);
criteria.setMaxResults(3);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
三、SQLQuery
SQLQuery用于接收一个SQL语句。如果是特别复杂的使用SQL
@Test
// createSQLQuery
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
SQLQuery query = session.createSQLQuery("select * from cst_customer");
query.addEntity(Customer.class);//设置查询返回时返回对象的元素
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}