Hibernate是一个持久层的ORM(对象关系映射)框架。
创建表
创建实体类(对应表格)
创建类与表的映射配置(实体类名.hbm.xml)
建立类与表之间的映射,主键对应和普通属性的对应
<hibernate-mapping>
<class name="com.hibernate.pojo.Customer" table="cst_customer">
<id name="cust_id" column="cust_id">
<generator class="native" />
id>
<property name="cust_source" column="cust_source">property>
<property name="cust_industry" column="cust_industry">property>
<property name="cust_level" column="cust_level">property>
<property name="cust_mobile" column="cust_mobile">property>
<property name="cust_name" column="cust_name">property>
<property name="cust_phone" column="cust_phone">property>
class>
hibernate-mapping>
映射约束从导入的jar包hibernate-core-5.0.7.Final.jar!\org\hibernate\hibernate-mapping-3.0.dtd中复制
创建Hibernate的核心配置文件hibernate.cfg.xml
配置数据库连接参数
配置打印sql语句
配置hibernate的方言
配置映射文件
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driverproperty>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_day01?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8property>
<property name="hibernate.connection.username">rootproperty>
<property name="hibernate.connection.password">cqrjxk39property>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialectproperty>
<mapping resource="com/hibernate/pojo/Customer.hbm.xml">mapping>
session-factory>
hibernate-configuration>
测试
public void test1(){
//1. 加载Hibernate核心配置文件
Configuration configure = new Configuration().configure();
//2. 创建SessionFactory对象:类似于JDBC连接池
SessionFactory sessionFactory = configure.buildSessionFactory();
//3. 通过SessionFactory获取Session对象:类似JDBC中的Connection
Session session = sessionFactory.openSession();
//4. 开启事务
Transaction transaction = session.beginTransaction();
//5. 编写代码
Customer customer = new Customer();
customer.setCust_name("张三");
session.save(customer);
//6. 事务提交
transaction.commit();
//7. 资源释放
session.close();
}
注意: Hibernate是可以根据映射关系自动创建表的,只需要在Hibernate的核心配置文件hibernate.cfg.xml中配置如下语句即可:
<property name="hibernate.hbm2ddl.auto">updateproperty>
Hibernate的核心配置文件既可以使用属性文件进行配置,也可以使用xml文件进行配置,但是属性文件配置时不能引入映射文件,需要手动加载映射文件。
Hibernate的工具类:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final Configuration cfg;
private static final SessionFactory sf;
static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
}
public static Session getSession(){
return sf.openSession();
}
}
例如:
//根据id查询
Customer customer = session.get(Customer.class, 1L);
System.out.println(customer);
Customer customer1 = session.load(Customer.class, 1L);
System.out.println(customer1);
//修改
Customer customer = session.get(Customer.class, 1L);
session.update(customer);
//删除
Customer customer = session.get(Customer.class, 1L);
session.delete(customer);
//查询所有
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");
List<Object[]> list1 = sqlQuery.list();
持久化:将内存中的一个对象持久化到数据库中的过程
持久化类:一个Java对象与数据库的表建立了映射关系,那么这个类就称为持久化类
自然主键指的是主键本身是表中的一个字段
例如:创建一个人员表,人员都会有一个身份证号(唯一不重复),使用身份证号作为主键,这种主键称为自然主键
代理主键指的是主键本身不是表中必须要有的字段
例如:创建一个人员表,给每一个人编一个号pno(唯一不重复),使用编号作为主键,这种主键称为代理主键
实际开发中,尽量使用代理主键,一旦主键参与到业务逻辑中去,后期有可能要修改源代码,好的程序应该满足ocp原则,对程序扩展是open的,对修改源代码是close的
在实际开发中一般允许用户手动设置主键,一般将主键交给数据库,手动编写程序进行设置。在Hibernate中为了减少编程,提供了多种主键生成策略。
例如
<id name="cust_id" column="cust_id">
<generator class="native" />
id>
这种对象没有唯一的标识OID,没有被session管理
这种对象有唯一标识OID,被session管理
这种对象有唯一标识OID,没有被session管理
例如:
public void test1(){
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();//瞬时态对象
customer.setCust_name("李四");
Serializable id = session.save(customer);
Customer customer1 = session.get(Customer.class, id);//持久态
transaction.commit();
session.close();
System.out.println("客户名称:"+customer.getCust_name());//脱管态对象
}
持久态可以自动更新数据库(由Hibernate的一级缓存实现)
例如:
public void test1(){
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.get(Customer.class, 6L);
customer.setCust_name("王五");
transaction.commit();
session.close();
}
上面的程序并有使用update方法,但是因为customer是持久态对象,所以也会更新数据库的内容为王五
缓存是一种优化机制,可以将数据存入内存中,使用时直接从缓存中获取,不用通过存储源
Hibernate的一级缓存,又称session级别的缓存,一级缓存的生命周期与session一致,一级缓存是Hibernate自带的,不可卸载的。
特点:
例如:
public void test1(){
Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.get(Customer.class, 6L);
Customer customer1 = session.get(Customer.class, 6L);
System.out.println(customer == customer1);
transaction.commit();
session.close();
}
运行结果:
通过控制台打印的数据我们可以发现,程序的两次查询只发送了一次sql语句,并且查询得到的对象是一个对象,证明Hibernate是有一级缓存的
query接口用于接收HQL,查询多个对象
查询所有:
String hql = "from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
for (Customer customer:list){
System.out.println(customer);
}
查询某些(带条件查询)
String hql = "from Customer where cust_name like ?";
Query query = session.createQuery(hql);
//从0开始
query.setParameter(0,"王%");
List<Customer> list = query.list();
for (Customer customer:list){
System.out.println(customer);
}
分页查询
String hql = "from Customer";
Query query = session.createQuery(hql);
//设置起始页
query.setFirstResult(0);
//设置每页的记录数
query.setMaxResults(3);
List<Customer> list = query.list();
for (Customer customer:list){
System.out.println(customer);
}
更加面向对象的查询,完全看不到查询语句
查询所有:
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
for (Customer customer:list){
System.out.println(customer);
}
查询某些
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.like("cust_name","王%"));
List<Customer> list = criteria.list();
for (Customer customer:list){
System.out.println(customer);
}
分页查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(0);
criteria.setMaxResults(3);
List<Customer> list = criteria.list();
for (Customer customer:list){
System.out.println(customer);
}
SQLQuery用于接收sql语句,特别复杂的请况下使用。