一、Configuration:加载配置文件
1、加载数据库连接配置文件
1.1、属性配置文件(hibernate.properties)
// 1.1.属性文件加载 Configuration configuration=new Configuration(); // 1.2.加载映射文件 configuration.addResource("com/marw/util/Customer.hbm.xml");
1.2、hibernate.cfg.xml
Configuration configuration=new Configuration().configure();
2、加载映射配置文件
2.1、对属性配置文件(hibernate.properties)加载映射文件
configuration.addResource("com/marw/util/Customer.hbm.xml");
二、SessionFactory:内部维护了Hibernate的连接池和Hibernate的二级缓存。是线程安全的对象。一个项目创建一个对象即可。
配置连接池
1、导入jar包
2、配置c3p0到核心配置文件
<?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-core-5.x.Final.jar包中 org.hibernate => hibernate-configuration-3.0.dtd --> <hibernate-configuration> <session-factory> <!-- 连接数据库基本参数 --> <property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property> <property name="hibernate.connection.url">jdbc:sqlserver://localhost:1433;databaseName=HibernateDB;</property> <property name="hibernate.connection.username">sa</property> <property name="hibernate.connection.password">AAA@111</property> <!-- 配置Hibernate的方言 --> <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property> <!-- 可选配置start --> <!-- 控制台打印sql语句 --> <property name="hibernate.show_sql">true</property> <!-- 控制台打印sql语句 格式化--> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 可选配置end --> <!-- 配置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> <!-- 配置映射 --> <mapping resource="com/marw/util/Customer.hbm.xml"/> </session-factory> </hibernate-configuration>
一个项目只创建一个SessionFactory
package com.marw.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * @Title: HibernateUtils * @Description: * @author: marw * @date 2020/11/03 17:00:26 */ public class HibernateUtils { private static Configuration confg; private static SessionFactory factory; static { confg=new Configuration().configure(); factory=confg.buildSessionFactory(); } public static Session openSession() { return factory.openSession(); } }
@Test public void demo2() { Session session=HibernateUtils.openSession(); // 4.开启事务(Hibernate版本5不用手动开启事务,要兼容版本3需要手动开启事务) Transaction transaction=session.beginTransaction(); // 5.编写代码 Customer customer=new Customer(); customer.setCust_name("zhang"); session.save(customer); // 6.提交事务 transaction.commit(); // 7.资源释放 session.close(); }
三、Session:Hibernate与数据库的链接对象。不是线程安全的(必须定义在方法内部,不能作为全局变量)。与数据库交互桥梁。
Session中的API
保存方法:
Serializable save(Object obj);
查询方法:
T get(Class c,Serializable id);
T load(Class c,Serializable id);
get方法和load方法的区别?
get:立即加载,返回值为对象,查询一个找不到的对象,返回null
load:延迟加载,返回值为代理对象,查询一个找不到的对象,返回ObjectNotFoundException
更新方法:
void update(Object obj);
@Test public void demo3() { Session session=HibernateUtils.openSession(); Transaction transaction=session.beginTransaction(); // 1.直接修改,不该修改的字段也被修改了 /* * Customer customer=new Customer(); * customer.setCust_name("zhang"); * session.update(customer); */ // 2.先查询,再修改,只会修改我们要修改的字段 Customer customer=session.get(Customer.class, 1L); customer.setCust_name("zhang"); session.update(customer); // 6.提交事务 transaction.commit(); // 7.资源释放 session.close(); }
删除方法:
void delete(Object obj);
@Test public void demo4() { Session session=HibernateUtils.openSession(); Transaction transaction=session.beginTransaction(); // 1.直接删除 /* * Customer customer=new Customer(); * customer.setCust_id("1L"); * session.delete(customer); */ // 2.先查询,再删除,如果有级联关系使用查询后删除 Customer customer=session.get(Customer.class, 2L); session.delete(customer); // 6.提交事务 transaction.commit(); // 7.资源释放 session.close(); }
保存或更新:
void saveOrUpdate(Object obj)
@Test public void demo5() { Session session=HibernateUtils.openSession(); Transaction transaction=session.beginTransaction(); /* * Customer customer=new Customer(); * customer.setCust_name("lisi"); * session.saveOrUpdate(customer); */ Customer customer=new Customer(); customer.setCust_id(3L); customer.setCust_name("wangwu"); session.saveOrUpdate(customer); // 6.提交事务 transaction.commit(); // 7.资源释放 session.close(); }
查询所有
@Test public void demo6() { Session session=HibernateUtils.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); * } */ //接收SQL SQLQuery query=session.createSQLQuery("select * from cst_customer"); List<Object[]> list= query.list(); for (Object[] objects : list) { System.out.println(Arrays.toString(objects)); } // 6.提交事务 transaction.commit(); // 7.资源释放 session.close(); }
①、HQL
@Test public void demoQuery() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); // 简单查询 String hql = "from Customer"; // 条件查询 -- 在hibernate4.1之后已经对HQL查询参数中的占位符做了改进 String hql = "from Customer where cust_name like ?"; // 第一种: String hql = "from Customer where cust_name like ?0"; Query query = session.createQuery(hql); // 设置条件 query.setParameter(0, "z%"); // 第二种 String hql = "from Customer where cust_name like :cust_names"; Query query = session.createQuery(hql); // 设置条件 query.setParameter(cust_names, "z%"); // 分页查询 String hql = "from Customer where cust_name like :cust_name"; Query<Customer> query = session.createQuery(hql); query.setParameter("cust_name", "z%"); // 设置分页 query.setFirstResult(0); query.setMaxResults(3); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); }
②、Criteria:QBC Query By Criteria
@Test public void demoCriteria() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); //查询所有 /* * Criteria criteria = session.createCriteria(Customer.class); * List<Customer> list = criteria.list(); */ //设置条件 Criteria criteria = session.createCriteria(Customer.class); //criteria.add(Restrictions.like("cust_name", "zh",MatchMode.START));//相当于criteria.add(Restrictions.like("cust_name", "zh%")); //分页 criteria.setFirstResult(0); criteria.setMaxResults(3); List<Customer> list = criteria.list(); for (Customer customer : list) { System.out.println(customer); } transaction.commit(); session.close(); }
注意:HQL、QBC两个Demo在实现分页调用setFirstResult和setMaxResults方法一直报java.lang.UnsupportedOperationException: query result offset is not supported的异常
解决方法:修改hibernate方言
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
改为
<property name="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</property>
Control输出内容
Hibernate: WITH query AS (SELECT inner_query.*, ROW_NUMBER() OVER ( ORDER BY CURRENT_TIMESTAMP) as __hibernate_row_nr__ FROM ( select this_.cust_id as cust_id1_0_0_, this_.cust_name as cust_nam2_0_0_, this_.cust_source as cust_sou3_0_0_, this_.cust_industry as cust_ind4_0_0_, this_.cust_level as cust_lev5_0_0_, this_.cust_phone as cust_pho6_0_0_, this_.cust_mobile as cust_mob7_0_0_ from cst_customer this_ ) inner_query ) SELECT cust_id1_0_0_, cust_nam2_0_0_, cust_sou3_0_0_, cust_ind4_0_0_, cust_lev5_0_0_, cust_pho6_0_0_, cust_mob7_0_0_ FROM query WHERE __hibernate_row_nr__ >= ? AND __hibernate_row_nr__ < ?