Java数据库开发之Hibernate框架(1)Hibernate入门

本文深入探讨Java数据持久化的多种方案,包括JDBC、JdbcTemplate和ORM框架,重点讲解了Hibernate框架的原理与应用,从配置到实现CRUD操作,再到配置细节的解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Java数据持久化方案

1:JDBC

       JDBC是Java语言访问数据库的一种规范,是一套API。JDBC (Java Database Connectivity) API,即Java数据库编程接口,是一组标准的Java语言中的接口和类,使用这些接口和类,Java客户端程序可以访问各种不同类型的数据库。 


       JDBC规范采用接口和实现分离的思想设计了Java数据库编程的框架。接口包含在java.sql及javax.sql包中,其中java.sql属于JavaSE,javax.sql属于JavaEE。 

JDBC访问数据库的步骤:
1.得到数据库驱动程序 
2.创建数据库连接 
3.执行SQL语句 
4.得到结果集 
5.对结果集做相应的处理(增,删,改,查) 
6.关闭资源:这里释放的是DB中的资源文链接

2:JdbcTemplate

          JdbcTemplate是spring框架提供的替代原生JDBC的类。它是对JDBC的一种封装,抽象我们常用的一些方法。
JdbcTemplate主要提供以下五类方法:
1)execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
2)update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;
3)query方法及queryForXXX方法:用于执行查询相关语句;
4)call方法:用于执行存储过程、函数相关语句。

3:ORM

           ORM 是Object-Relation-Mapping,即对象关系影射技术,是对象持久化的核心。ORM是对JDBC的封装,从而解决了JDBC的各种存在问题。
           ORM则建立了Java对象与数据库对象之间的影射关系,程序员不需要编写复杂的SQL语句,直接操作Java对象即可,从而大大降低了代码量,也使程序员更加专注于业务逻辑的实现。
           使用ORM技术,可以将数据库层完全隐蔽,呈献给程序员的只有Java的对象,程序员只需要根据业务逻辑的需要调用Java对象的Getter和 Setter方法,即可实现对后台数据库的操作,程序员不必知道后台采用什么数据库、有哪些表、有什么字段、表与表之间有什么关系。

            目录最流行的ORM框架:Hibernate,MyBatis。
 

二、Hibernate概述

         Hibernate是开源的一个ORM(对象关系映射)框架。ORM是一种思想,Hibernate是实现了ORM思想的java持久层ORM框架。Hibernate本身是基于JDBC,对JDBC访问数据库做了抽象和封装.所以它是需要数据库的驱动包.
         它的作用就是在关系型数据库和对象之间做了一个映射。从对象(Object)映射到关系(Relation),再从关系映射到对象。这样,我们在操作数据库的时候,不需要再去和复杂SQL打交道,只要像操作对象一样操作它就可以了
Hibernate六大核心接口,两个主要配置文件,以及他们直接的关系。Hibernate的所有内容都在这了。那我们从上到下简单的认识一下,每个接口进行一句话总结。
1、Configuration接口:负责配置并启动Hibernate
2、SessionFactory接口:负责初始化Hibernate
3、Session接口:负责持久化对象的CRUD操作
4、Transaction接口:负责事务
5、Query接口和Criteria接口:负责执行各种数据库查询
 
注意:Configuration实例是一个启动期间的对象,一旦SessionFactory创建完成它就被丢弃了。

1)下载Hibernate

地址:http://hibernate.org/orm

 2)安装

下载解压后,Hibernate5.4 有18个必须jar包。将其复制到项目中,再创建build path。

 3)配置

配置文件在hibernate-release-5.4.0.Final\project\etc目录中:

1:Hibernate主配置文件(hibernate.cfg.xml):关联约束文件hibernate-configuration-3.0.dtd.

<?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>
        <!-- 1.数据库配置 -->
        <!--   1.1.连接数据库的驱动  -->
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <!--   1.2.连接数据库的地址,路径 -->
        <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hbm?serverTimezone=GMT%2B8</property>
        <!--   1.3.连接数据库的用户名 -->
        <property name="hibernate.connection.username">root</property>
        <!--   1.4.连接数据库的密码 -->
        <property name="hibernate.connection.password">root</property>
        <!--   1.5.数据库方言配置根据不同的方言生成符合当前数据库语法的sql -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 2.其它配置 -->
        <!--   2.1.在控制台打印sql语句 -->
        <property name="hibernate.show_sql">true</property>
        <!--   2.2.打印sql语句前,会将sql语句先格式化  -->
        <property name="hibernate.format_sql">true</property>
        <!--   2.3.自动建表 -->
        <!-- <property name="hibernate.hbm2ddl.auto">create</property> -->
        <!--   2.4.事务自动提交  -->
        <property name="hibernate.connection.autocommit">true</property>
        <!--   2.5.将Session与线程绑定=> 只有配置了该配置,才能使用getCurrentSession -->
        <property name="hibernate.current_session_context_class">thread</property>

        <!-- 3.加载ORM映射文件-->
        <mapping resource="com/openbox/domain/User.hbm.xml"/>		
    </session-factory>
</hibernate-configuration>

2:hibernate.properties文件,找到连接数据库的基本要素.

## MySQL

#hibernate.dialect org.hibernate.dialect.MySQLDialect
#hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
#hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql:///test
#hibernate.connection.username gavin
#hibernate.connection.password

3:对象与数据表映射文件user.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- User对象的映射文件 -->
<hibernate-mapping  package="com.openbox.domain">  
    <class name="User" table="t_user">        
        <id name="id" column="uid">
            <generator class="native"/>
        </id>
	<property name="username" column="uname" />
    </class>

</hibernate-mapping>

三、Hibernate实现CRUD操作

1):创建数据库hbm,再建表

CREATE TABLE `t_user` (
  `uid` bigint(20) NOT NULL AUTO_INCREMENT,
  `uname` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8

2):创建User对象User.java

package com.openbox.domain;

public class User {
	
	private Long id;
	private String username;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + "]";
	}
}

 

 3):创建User的DAO接口及其实现类

IUserDAO.java

package com.openbox.dao;

import java.util.List;
import com.openbox.domain.User;
public interface IUserDAO {

	//定义User对象操作增删改查的接口
     void save(User u);
     void update(User u);
     void delete(User u);
     User get(Long id);
     List<User> list();
     
}

UserDAOImpl.java

package com.openbox.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;

import com.openbox.domain.User;

public class UserDAOImpl implements IUserDAO {

	//-----------DML操作----------------//
	@Override
	public void save(User u) {
		//1.创建配置对象
		Configuration cfg = new Configuration();
		//2.读取配置文件
		cfg.configure("/hibernate.cfg.xml");
		//3.创建SessionFactory
		SessionFactory buildSessionFactory = cfg.buildSessionFactory();
		//4.获取Session
		Session openSession = buildSessionFactory.openSession();
		//5.打开事务(设置事务活动状态)
		openSession.beginTransaction();
		//6.DML操作
		openSession.save(u);
		//7.提交/回滚事务
		 openSession.getTransaction().commit();
		//8.关闭Session
		openSession.close();
		//9.关闭SessionFactory
		buildSessionFactory.close();

	}

	@Override
	public void update(User u) {
		//1.创建配置对象
		Configuration cfg = new Configuration();
		//2.读取配置文件
		cfg.configure("/hibernate.cfg.xml");
		//3.创建SessionFactory
		SessionFactory buildSessionFactory = cfg.buildSessionFactory();
		//4.获取Session
		Session openSession = buildSessionFactory.openSession();
		//5.打开事务(设置事务活动状态)
		openSession.beginTransaction();
		//6.DML操作
		openSession.update(u);
		//7.提交/回滚事务
		 openSession.getTransaction().commit();
		//8.关闭Session
		openSession.close();
		//9.关闭SessionFactory
		buildSessionFactory.close();

	}

	@Override
	public void delete(User u) {
		//1.创建配置对象
		Configuration cfg = new Configuration();
		//2.读取配置文件
		cfg.configure("/hibernate.cfg.xml");
		//3.创建SessionFactory
		SessionFactory buildSessionFactory = cfg.buildSessionFactory();
		//4.获取Session
		Session openSession = buildSessionFactory.openSession();
		//5.打开事务(设置事务活动状态)
		openSession.beginTransaction();
		//6.DML操作
		openSession.delete(u);
		//7.提交/回滚事务
		 openSession.getTransaction().commit();
		//8.关闭Session
		openSession.close();
		//9.关闭SessionFactory
		buildSessionFactory.close();

	}

	//-----------DQL操作----------------//
	@Override
	public User get(Long id) {
		//1.创建配置对象
		Configuration cfg = new Configuration();
		//2.读取配置文件
		cfg.configure("/hibernate.cfg.xml");
		//3.创建SessionFactory
		SessionFactory buildSessionFactory = cfg.buildSessionFactory();
		//4.获取Session
		Session openSession = buildSessionFactory.openSession();
		//5.具体的查询操作
		User user = (User) openSession.get(User.class, id);
		//6.关闭Session
		openSession.close();
		//7.关闭SessionFactory
		buildSessionFactory.close();
		System.out.println(user);
		return user;
	}

	@Override
	public List<User> list() {
		//1.创建配置对象
		Configuration cfg = new Configuration();
		//2.读取配置文件
		cfg.configure("/hibernate.cfg.xml");
		//3.创建SessionFactory
		SessionFactory buildSessionFactory = cfg.buildSessionFactory();
		//4.获取Session
		Session openSession = buildSessionFactory.openSession();
		//5.具体的查询操作,使用HQL语句
		Query query = openSession.createQuery("select u from User u");
		List<User> list = query.list();
		//6.关闭Session
		openSession.close();
		//7.关闭SessionFactory
		buildSessionFactory.close();

		return list;
	}
}

4):用JUnit5创建测试类UserTests.java

package com.openbox.test;

import java.util.List;

import org.junit.jupiter.api.Test;

import com.openbox.dao.IUserDAO;
import com.openbox.dao.UserDAOImpl;
import com.openbox.domain.User;

public class UserTests {

	private IUserDAO dao = new UserDAOImpl();

	@Test
	public void testSave() {
		User user=new User();
		user.setUsername("jack");
		dao.save(user);
	}

	@Test
	public void testUpdate() {
		User user=dao.get(5L);
		user.setUsername("MOMO");
		dao.update(user);
	}

	@Test
	public void testDelete() {
		User user=dao.get(2L);
		dao.delete(user);		
	}

	@Test
	public void testGet() {
		User user = dao.get(1L);
		System.out.println(user);
	}

	@Test
	public void testList() {
		List<User> users=dao.list();
		for (User user : users) {
			System.out.println(user);
		}
	}
}

5):操作结果

5):常见错误
1).操作数据库,必须拷贝数据库对于的驱动包.
2).hibernate.cfg.xml中的<property>配置不能出现空格,如:<property name="hibernate.connection.username ">root</property>
3).忘记调用configure()方法,正确写法:Configuration cfg = new Configuration().configure();  //加载hibernate.cfg.xml文件.
4).org.hibernate.PropertyNotFoundException: 找不到对象中指定的属性名.(属性property有getter/setter决定,而不是字段Field决定)
5).SessionException : Session is closed:不能再关闭Session之后,使用Session对象.
6).实体类存在无参数构造器.
7).Hibernate并不要求持久化类必须实现java.io.Serializable接口,但对于RMI或JavaEE分布式结构的Java应用,必须实现该接口.Hibernate要求持久化类,必须提供一个不带参数的构造器.


四、Hibernate配置细节

1)自动生成数据库表

在Hibernate主配置文件(hibernate.cfg.xml)中,有以下配置参数:

根据对象和映射文件,在创建SessionFactory的时候,可以生成对应(交给Hibernate管理的映射文件)的数据表:

hibernate.hbm2ddl.auto=create-drop:删除并创建表,关闭SessionFactory时,删除数据库表.
hibernate.hbm2ddl.auto=create:删除并创建表 平时上课,测试
hibernate.hbm2ddl.auto=update:更新表结构:开发项目过程中:
hibernate.hbm2ddl.auto=validate:验证表结构:如果表结构和映射文件不匹配,hibernate启动失败

1):create-drop
    1,删除那些表?创建那些表:删除本次hibernate管理的对象对应的表;创建hibernate本次管理的对象对应的表;
    2,如果新加一个domain会怎么处理:创建对应的表;
    3,如果删除一个domain会怎么处理:不管;
    4,一定要正常关闭SessionFactory,才会正常删除表;
    5,使用:一般不会使用create-drop;
----------------------------------------------
2):create
    1,删除那些表?创建那些表:删除本次hibernate管理的对象对应的表;创建hibernate本次管理的对象对应的表;
    2,如果新加一个domain会怎么处理:创建对应的表;
    3,如果删除一个domain会怎么处理:不管;
   使用:
    4,一般在做测试的时候使用create方法;
    5,因为每次都是删除表并重新创建表;所以可以保证多次测试的代码不用重写;
    6,注意在黑盒测试的时候不能使用create;
-----------------------------------------------
3):update
    1,检查并修改那些表?修改本次hibernate管理的表;
    2,如果表已经存在,怎么处理?检查表结构和当前对象结构是否匹配,如果不匹配,尝试更新当前表结构;
    3,如果表不存在,怎么处理:创建新表;
    4,如果对象的结构有变化,怎么更新
        1,添加一个属性:在表中添加一列;
        2,删除一个属性:不管;
        3,修改一个属性:尝试修改属性对应的列类型,如果不能修改,抛出警告;
    使用:
    1,在黑盒测试的时候使用update;
    2,在生产环境不建议使用update(运营过程中);
    3,在启动的时候一定要关注由update导致的更新表结构失败;
4):validate:
    检查当前hibernate管理的对象对应的表和数据库的表结构是否匹配,如果有任何不匹配,直接报错,hibernate启动失败;
    在生产环境中一般使用vaildate,保证当前数据库表版本和hibernate当前对象版本匹配;

2):映射文件细节User.hbm.xml

1.package是可以不写的,如果不写package,其中所有的类都必须有全限定名.
2.在一个hbm.xml中,可以写多个对象的映射,但是一般来说,一个映射文件对应一个实体对象.建议和类名相同(User.java --> User.hbm.xml)
3.class元素的table属性是可以省略的,如果不写table,对应table的名称和类的名称一模一样(大小写一样).
4.property元素对应的是对象的属性:fullName
  什么是属性:由一对符合命名规范的getter和setter构成的;hibernate找的是getter和setter
  hibernate什么时候使用getter:把对象-->数据库列中,getter方法返回的内容就是要保存到数据库中的内容
  hibernate什么时候使用setter:数据库列-->对象中,setter方法传入的值就是数据库中的值
  hibernate不关心getter和setter方法的可见性
5.可以通过修改property元素的access属性来改变访问策略(访问属性/字段).<property name="bornDate" access="field"/>:使用字段来关联表字段
6.property元素的type属性可以为对象的属性添加指定的映射类型
            type里面写的类型,不是数据库的类型,是hibernate定义的一种中间类型,
            JAVA类型-中间类型-数据表类型
7.为列添加更多的额外控制 
            在property元素的子元素column中,可以添加更多的列的控制条件
8.控制属性的可变性:
  insert属性决定该列是否出现在INSERT语句中:<property name="" insert = "true">:
  有值就出现在SQL语句,没有值就不出现:<class name="User" dynamic-insert="true">
9.auto-import:自动导入,hibernate为其中的对象自动的起一个别名(默认就是类的名称,用于查询封装VO对象)
    <hibernate-mapping auto-import="false">
    <!-- 自己为类起别名 -->
    <import class="com._520it.day1._03_config.Person" rename="Person2"/>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值