叙:学习hibernate是必不可少的要了解其核心的API,下面电虫就核心API进行记录学习;
Hibernate核心API
Hibernate核心API有configuration、SessonFactory、Session、Transaction等,在Session中有增删改查等小地API,下面进行详细学习;
学习要有目标有方向,所以从一段代码中从上到下的进行研读不失为一种高效率的学习方法,学习模板代码如下所示:
1 package com.java.hibernate.demo1; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.Transaction; 6 import org.hibernate.cfg.Configuration; 7 import org.junit.Test; 8 /* 9 * hibernate入门案例 10 */ 11 public class HibernateDemo1 { 12 13 @Test 14 public void demo1(){ 15 //1.加载核心配置文件 16 Configuration conf = new Configuration().configure(); 17 //2.创建一个sessionFactory对象:类似于JDBC中的连接池 18 SessionFactory sessionFactory = conf.buildSessionFactory(); 19 //3.通过SessionFactory获取到Session:类似于JDBC中的Connection 20 Session session = sessionFactory.openSession(); 21 //4.手动开启事务 22 Transaction bt = session.beginTransaction(); 23 24 //5.编写代码 25 Customer c = new Customer(); 26 c.setCust_name("韦一笑"); 27 c.setCust_industry("青翼蝠王"); 28 session.save(c); 29 30 //6.提交事务 31 bt.commit(); 32 //7.释放资源 33 session.close(); 34 } 35 }
上面有一些注释,对其大概作用进行了解释,从上到下逐句解释:
1. Configuration :
介绍:
Configuration类的作用是对hibernate进行配置并启动hibernate,configuration类的实例首先定位映射文件的位置,并读取这些文件的配置,然后创建一个SessionFactory对象,虽然configuration在整个hibernate项目中并不显眼,但却是hibernate项目启动时所遇到的第一个对象;
作用:
1、读取核心配置文件;
2、加载映射文件(属性文件类型的核心配置只能通过手动设置,无法引入);
使用
读取核心配置文件分为XML类型核心配置的读取和属性类型的核心配置读取两种;
XML类型的:Configuration cfg = new Configuration().configure();
pass:主要使用XML的配置文件形式进行hibernate项目核心配置,因此,加载核心配置文件使用的也是其对一个的方法。
属性类型的:Hibernate.properties Configuration cfg = new Cofiguration();
加载映射文件:
//1.加载核心配置文件 Configuration conf = new Configuration().configure(); //添加映射文件路径 conf.addResource("com/java/hibernate/demo1/Customer.hbm.xml");
2.SessionFactory:session工厂
介绍
SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理(类似于连接池的作用),并负责创建Session对象。这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就够,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
SessionFactory内部维护了一个连接池和一个hibernate的二级缓存(企业中已经基本不用此缓存),是一个线程安全的对象,一个项目中只需要一个SessionFactory就好;
手动配置连接池
<!-- 若是不想用其自带的连接池配置,可以自己配一下,不要忘记导入连接池驱动的架包 --> <!-- 配置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>
自己配置的连接池需要导入相应的架包,导入架包后不要忘记 Build Path 一下;
在hibernate内部有封装好的连接池,如果不使用自己配置的连接池在后边释放资源是可以不用再手动编写代码进行释放;如果自己配置连接池则需要自己手动释放资源;
所用到的jar包:
使用
抽取工具类:
/* * hibernate项目的工具类 */ public class HibernateUtils { public static final Configuration conf; public static final SessionFactory sf; static{ //核心文件的配置加载; conf = new Configuration().configure(); //并根据读取的配置文件创建SessionFactory; sf = conf.buildSessionFactory(); } public static Session openSession(){ return sf.openSession(); }
调用工具类:
@Test public void demo1() { Session session = HibernateUtils.openSession(); Transaction xt = session.beginTransaction(); // --------------------- Customer c = new Customer(); c.setCust_name("张无忌"); Serializable id1 = session.save(c); // --------------------- xt.commit(); session.close(); }
3.Session:操作数据库的桥梁
介绍
Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句)。但需要注意的是Session对象是非线程安全的。同时,Hibernate的session不同于JSP应用中的HttpSession。这里当使用session这个术语时,其实指的是Hibernate中的session,而以后会将HttpSession对象称为用户session。
Session代表的是hibernate与数据库的连接对象,既是与数据库链接的桥梁,但他是线程不安全的,因此一定要把它定义成局部的,Session中有很多操作数据库的API;
session中的API
1. 添加的API
API接口名:save
@Test public void demo1() { Session session = HibernateUtils.openSession(); Transaction xt = session.beginTransaction(); // --------------------- Customer c = new Customer(); c.setCust_name("张无忌"); Serializable id1 = session.save(c); // --------------------- xt.commit(); session.close(); }
2. 查询的API
查询的API有两个,一个是get()一个是load();
public void demo2(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); //使用get方法进行查询 //在customer类所映射的表中查询id为2的数据, //l是告诉解析器2是字符串类型的,并非int类型的数据,因表设计时定义cust_id是字符串类型的; Customer customer = session.get(Customer.class, 2l); System.out.println(customer); //使用load方法进行数据查询 /*Customer load = session.load(Customer.class, 3l); System.out.println(load);*/ bt.commit(); session.close(); }
辨析:
问:get()和load()方法有什么区别?(一般面试会用到)
get方法
a) get()方法是即时查询,当运行到get()方法时就会执行查询方法;
b) get()方法查询获得的是真实的对象本身;
c) 查询不到所要查询的数据时返回的是null;
load方法
a) load()方法进行查询时是延迟查询,只有当要用到查询对象的非id数据时才会进行查询;
b) load()方法查询获得的对象是所要查询的对象的代理对象,并非是所要查询的对象本身;
c) 当查询不到所要查询的数据时会返回ObjectNotFoundEcxeption;
修改的API
API接口名:update
修改的方法有两种,第一种是直接修改,第二种是先查询再修改;
第一种:
@Test /* * 修改数据的操作 */ public void demo3(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); Customer c = new Customer(); c.setCust_id(2l); c.setCust_name("成昆"); session.save(c) bt.commit(); session.close(); }
第二种:
@Test /* * 修改数据的操作 */ public void demo3(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); //先查询再修改 Customer customer = session.get(Customer.class, 5l); customer.setCust_industry("张三丰之孙"); session.update(customer); bt.commit(); session.close(); }
辨析:
这两种修改操作的区别:
第一种是直接修改型的,修改一项的同时也要重写其他项,否者这条数据的其他项则会默认为空;
第二种是先查询再修改的,这种修改不存在问题,修改某一项时这条数据的其他项数据保持不变;
删除的API
删除数据也有两种方式,发分别是直接删除和先查询再删除;
直接删除方式:
API接口名:delete
@Test /* * 删除数据的操作 */ public void demo3(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); Customer c = new Customer(); c.setCust_id(2l); session.delete(c) bt.commit(); session.close(); }
先查询再删除:
API接口名:delete
@Test /* * 删除数据的操作 */ public void demo4(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); //先查询后删除 Customer customer = session.get(Customer.class, 3l); session.delete(customer); bt.commit(); session.close(); }
辨析:
比较:直接删除 / 先查询后删除
先查询后删除与直接删除均可以删除选中的id的数据,但是先查询后删除的优点在于可以删除级联相关的数据,即是删除客户连同删除客户id下的订单表等所有数据;
添加或更新API
API接口名:saveOrUpdate
@Test /* * 添加或更新 */ public void demo5(){ Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); /* //使用 saveOrUpdate 添加数据 Customer C = new Customer(); C.setCust_name("狗蛋"); C.setCust_industry("光明顶"); session.saveOrUpdate(C); */ //使用 saveOrUpdate 进行数据更新操作 Customer customer = session.get(Customer.class, 5l); customer.setCust_name("张无忌"); customer.setCust_level("光明教教主"); session.saveOrUpdate(customer); bt.commit(); session.close(); }
辨析:使用saveOrUpdate接口的时候,当操作过程中没有涉及数据的ID时就是添加数据的操作,当有ID时就是更新操作,一般这个接口使用的并不多;
查询所有的API
@Test /* * 查询所有操作 */ public void demo6(){ Session s = HibernateUtils.openSession(); Transaction bt = s.beginTransaction(); /* //使用HQL模式进行接收:Hibernate Query Language;面向对象的查询语言 Query query = s.createQuery("from Customer"); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer); } */ //使用SQL进行接收 SQLQuery SQLQuery = s.createSQLQuery("select * from cst_customer"); List<Object[]> list = SQLQuery.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } bt.commit(); s.close(); }
辨析:
HQL是面向对象的操作方式,接收的数据类型是Customer对象类的;
SQL是使用数据库命令的操作方式,接收的数据类型是Object类型的;
相比较而言,HQL处理数据更加方便,使用的更加普遍;
4.Transaction:事务的管理
介绍
Hibernate中用于管理操作事务的;
Transaction的API
rollback():事务回滚;
commit():事务提交;
事务管理在此章只进行初略的应用,到后边会有更详细的学习;