Hibernate自学入门

Hibernate自学入门

java连接数据库

只要java代码想连接上数据库,就一定需要实验JDBC

什么是Hibernate框架

持久层的ORM的框架,对JDBC做了封装。

持久层
ORM框架,对象关系映射
  1. ORM框架都会遵循的一种思想:想将对象和数据库表建立映射关系

    好处:操作对象就相当于操作数据库的表数据

  2. Hibernate只是ORM框架中的一种

hibernate框架的作用?
  1. 简化了Dao层的编码工作

    大大简化了数据访问层繁琐的重复性代码,加快了运行效率

  2. 程序更加面向对象

    可以不需要编写SQL语句,只需要操作相应的对象就可以完成数据库数据的crud操作

使用方式
  1. 将hibernate的开发环境包:hibernate-release-5.0.7.Final.zip解压

    documentation:Hibernate的开发规范和文档
    lib:Hibernate的开发使用的jar包(重点关注 required optional)
    project:Hibernate的提供测试的工程。

  2. 导入工程所需要的包

    hibernate-release-5.0.7.Final\lib\required* 所有包

    hibernate-release-5.0.7.Final\lib\optional\c3p0* 所有包

    hibernate在运行的过程中会加载一个日志包 ,企业开发用的日志包: apacha-log4j.jar

    要连接的数据库驱动包(mysql)

  3. 使用

    • 在需要映射的类的包中创建一个XML的配置文件,文件名通常为:类名**.hbm.xml**

    • 在XML文件中,做类名和表名的引索

    • 做主键和属性的映射(顺便让主键自增)

    • 其他类属性和其他字段映射

    <hibernate-mapping>
    	<!-- 对象与表做映射 -->
    	<class name="com.edu.hibernateT01.Customer" table="cst_customer">
    		<!-- 主键映射关系 -->
    		<id name="cust_id" column="cust_id">
    			<!-- 做主键的增长方式 -->
    			<generator class="native"></generator>
    		</id>
    		<property name="cust_name" column="cust_name"></property>
    		...
    	</class>
    </hibernate-mapping>
    
做数据库的核心配置,配置文件在src下并叫hibernate.cfg.xml
<hibernate-configuration>
	<!-- 生产session的工厂 -->
	<session-factory>
		<!-- 数据库的驱动 -->
		<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
		<!-- 数据库的url -->
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate?useSSL=false&amp;serverTimezone=UTC</property>
		<!-- 数据库的用户名 -->
		<property name="hibernate.connection.username">root</property>
		<!-- 数据库的密码 -->
		<property name="hibernate.connection.password">12356</property>
		<!-- 数据库的方言 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<!-- 配置C3P0 -->
		<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
		<!-- 配置hibernate在控制台显示sql语句 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 配置sql语句显示格式 -->
		<property name="hibernate.format_sql">true</property>
        <!-- 加载映射文件Customer.hbm.xml -->
		<mapping resource="com/edu/hibernateT01/Customer.hbm.xml"/>
	</session-factory>
</hibernate-configuration>
  • hibernate-release-5.0.7.Final\project\etc\hibernate.properties
  • mysql 8.0 配置url的时候,因为数据库改变了其默认编码集需要在后面追加?useSSL=false&serverTimezone=UTC";在xml中&是被禁止,需要用转义字符&
XML中的一些配置说明
<!-- 如果数据库中没表,创建表,有则更新 -->
<property name="hibernate.hbm2ddl.auto">update</property>
映射配置文件中的说明
  1. class标签:建立类和表的映射
    ​ name:类的全路径
    ​ table:数据库中表的名称。
    ​ catalog :数据库名称(可以省略)
  2. id标签:建立主键和类中属性映射
    ​ name:类中的属性的名称
    ​ column:表中的字段名称。(如果类中的属性名和表中的字段名一致,column可以省略)
  3. property标签:建立普通字段与类中属性映射
    ​ name :类中的属性的名称
    ​ column :表中的字段名称。(如果类中的属性名和表中的字段名一致,column可以省略)
    ​ length:字段的长度(自动创建表)
    ​ not-null:非空(自动创建表)
    ​ unique:唯一(自动创建表)
Hibernate 数据库操作API(增删改查)
  1. 查询get/load
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.get(Customer.class, 1L);
//Customer load = session.load(Customer.class, 1L);	延迟查询
System.out.println(customer.getCust_name());
transaction.commit();
session.close();

get和load的主要区别:get是直接查询;load是延迟查询,需要用到时才去数据库查询数据,效率高

  1. 增加save
Customer customer = new Customer();
customer.setCust_name("tom");
session.save(customer);
  1. 删除delete(需要先查询出来,再删除)
Customer customer = session.get(Customer.class, 1L);
session.delete(customer);
  1. 修改update(需要查询出来,再修改)
Customer customer = session.get(Customer.class, 2L);
customer.setCust_phone("11111414");
session.update(customer);	//可不进行存储,持久态对象会自动更新数据库
Hibernate 的一级缓存

session在查询数据库的数据时,先在一级缓存中查询,如存在直接返回,若不存在去数据库查询,并放在一级缓存中

作用:减少对数据库的访问次数

一级缓存:称为session级别的缓存,与session生命周期一致,自带的,不可卸载(有session种的一系列java集合构成的)

  • 一级缓存内部分为存储区和快照区:

    存储区:存放数据库查询出来的信息

    快照区:对存储区的数据进行简单的存储

    在程序执行提交时,系统会自动去一级缓存对比存储区和快照区的数据是否一致,若不一致则执行update语句更新数据库

二级缓存:称为SessionFactory级别的缓存。需要进行配置的缓存插件。默认不开启。ehche被redis代替

Hibernate批量查询方式
  1. HQL查询(query查询):
//全查
Query qr = session.createQuery("from Customer");
List<Customer> list = qr.list();
//条件查询
Query qr = session.createQuery("from Customer where cust_id = ?");
qr.setParameter(0, 1L);	//填充问号
Object result = qr.uniqueResult();	//返回单个对象时用此方法
//分页查
Query qr = session.createQuery("from Customer");
qr.setFirstResult(0);
qr.setMaxResults(2);
List<Customer> list = qr.list();
//单列或者多列查询
Query qr = session.createQuery("select cust_id,cust_name from Customer");
List<Object[]> list = qr.list();
for (Object[] objects : list) {
	System.out.println(Arrays.toString(objects));
}
//投影查询---多列查询后封装成对象返回,需要在持久化类中书写构造函数
Query qr = session.createQuery("select new Customer(cust_id,cust_name) from Customer");
List<Customer> list = qr.list();
//聚合查询
Query qr = session.createQuery("select count(*) from Customer");
Object object = qr.uniqueResult();
  1. QBC查询(Criteria查询):

    普通查询

//全查
Criteria crit = session.createCriteria(Customer.class);
List<Customer> list = crit.list();
//条件查
Criteria crit = session.createCriteria(Customer.class);
crit.add(Restrictions.like("cust_name", "b%"));	//调用Restrictions类中的各方法
//分页查
Criteria crit = session.createCriteria(Customer.class);
crit.setFirstResult(0);
crit.setMaxResults(3);
//聚合查
Criteria crit = session.createCriteria(Customer.class);
crit.setProjection(Projections.rowCount());		//调用Projections中的各方法
Object result = crit.uniqueResult();

​ **离线条件查询:**可以离开session连接的查询方式。可用于在Web层编写好查询SQL语句

//Web层:添加sql条件
DetachedCriteria dx = DetachedCriteria.forClass(Customer.class);
dx.add(Restrictions.like("cust_name", "张三"));
dx.add(Restrictions.like("cust_phone", "12345678"));

//Dao层:获取此对象进行查询
Criteria crit = dx.getExecutableCriteria(session);
  1. 对象导航查询:当查询当前对象时,不仅会把当前对象的所有数据查出,还会把对象或者集合的数据查询出来
<!-- 默认为延迟查询,修改方式在set配置中添加 -->
<!-- lazy:true 默认使用延迟加载
 			false 不适应延迟加载立即加载-->
<set name="roles" lazy="true">

注意:对象导航查询是一个关联级别的延迟加载:在使用对象或者集合中的数据时,才去数据库查询。此方式可提高hibernate的效率,与load查询方式类似

session与当前线程绑定

底层实现为TreadLocal。使用时,需要在hibernate.cfg.xml配置文件中配置。并且不需要手动关闭session

<!-- 配置ThreadLocal为开启状态 -->
<property name="hibernate.current_session_context_class">thread</property>
//获取当前线程的连接
Session session = sessionFactory.getCurrentSession();
hibernate一对多的配置

一的一方的配置:需要在持久化类中新建一个多的一方的set集合属性,xml配置文件配置如下:

<!-- 
	name:当前实体类多一方的set集合名字
	column:多一方的外键的名字
	class:多一方的类全限定名
	inverse:是否放弃管理外键
 -->
<set name="Linkmans" inverse="true">
	<key column="wj_id"></key>
	<one-to-many class="com.edu.hibernateT02.Linkman"/>
</set>

注意:为了防止sql语句冗余,需要在一的一方设置放弃外键管理

多的一方的配置:需要在持久化类中新建一个一的一方的对象,xml配置文件配置如下:

<!-- 
	name:当前实体类中,一一方的对象名字
	class:一一方的全限定名
	column:外键名
 -->
<many-to-one name="customer" class="com.edu.hibernateT02.Customer" column="wj_id"></many-to-one>
hibernate多对多的配置

双方配置方法一样,常常避免使用级联保存与级联删除

<!-- 
	name:此对象set集合名字
	table:自动生成表的名字
	inverse:true 放弃外键维护,多对多常常是被动一方放弃维护外键
  -->
<set name="roles" table="sys_user_role" inverse="true">
	<!-- column:自己在中间表的外键名  -->
	<key column="user_id"></key>
	<!-- column:对方在中间表的外键名  -->
	<many-to-many class="com.edu.domain.Role" column="role_id"></many-to-many>
</set>

注意:为避免出现sql语句冗余,需要使被动的一方放弃外键的维护

级联保存与删除
  1. 级联保存:保存数据时,自动保存与之有关联的数据;只需要在需要级联保存的持久类的配置文件进行配置,配置如下:
<!-- cascade:save-update 开启级联保存 -->
<set name="Linkmans" cascade="save-update">
  1. 级联删除:在删除数据时,删除与之关联的数据;只需在需要级联删除的持久类的配置文件进行配置,配置如下:
<!-- cascade:delete 开启级联删除 -->
<set name="Linkmans" cascade="delete">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值