Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01

目录

  • 第一节 Hibernate简介
    • 1.1 项目中框架的体系结构
    • 1.2 ORM框架
    • 1.3 什么是hibernate
    • 1.4 Hibernate总结
    • 1.5 主流的ORM框架
    • 1.6 Hibernate的优点
  • 第二节 hibernate的简单使用
    • 2.1 下载hibernate的jar包
    • 2.2 数据库建表
    • 2.3 在IDEA中新建一个javaweb项目
    • 2.4 导入jar包
    • 2.4 hibernate的核心配置文件
    • 2.6 编写JavaBean和映射文件.hbm.xml
    • 2.7 测试
    • 2.8 常见的问题
      • 1.The server time zone value '?й???????' is unrecognized or represents more than one time zone
      • 2. org.hibernate.exception.GenericJDBCException: Cannot open connection
      • 3. table里报错和Cannot resolve column 'id'
      • 4. org.hibernate.MappingException: Unknown entity: com.it.hibernate.domain.User
  • 第三节 API详解
    • 3.1 Configuration 配置对象
      • Hibernate的核心配置文件的多种形式
      • Configuration 对象
      • 加载映射文件方式
      • 常见异常
        • org.hibernate.InvalidMappingException: Could not parse mapping document from resource com/it/hibernate/domain/User.hbm.xml
    • 3.2 SessionFactory 工厂
    • 3.3 Session 会话
      • session会话的获取
    • 3.4 Transaction事务
    • 3.5 session的api(方法)
      • save保存、get与load查询
      • delete删除
      • update更新
    • 3.6 get和load方法的区别
    • 3.7 Query 查询对象
    • 3.8 Criteria
    • 3.9 SQLQuery
    • 3.10 抽取工具类

第一节 Hibernate简介

1.1 项目中框架的体系结构

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第1张图片

1.2 ORM框架

  • 对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)
  • 对象和表字段进行对应
  • 是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换
    • Object:对象,java对象,此处特指JavaBean,Model
    • Relational:关系,二维表,数据库中的表。
    • Mapping:映射

1.3 什么是hibernate

  • Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装。
  • DBUtils也是对JDBC的封装
  • 它将POJO与数据库表建立映射关系,是一个全自动的orm框架
    • POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans
  • hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
  • Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用。

1.4 Hibernate总结

  • Hibernate是一个数据持久化层(dao)的ORM框架,它的主要功能就是把对象映射到表中,操作API,只需要将一个对象存储到数据库,不需要写sql语句。
  • Hibernate提供了对关系型数据库增删改查操作
    在这里插入图片描述

1.5 主流的ORM框架

  • JPA(Java Persistence API-java持久层API)JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系。(只有接口规范)
  • Hibernate 最流行ORM框架,通过对象-关系映射配置,可以完全脱离底层SQL。
  • MyBatis 本是apache的一个开源项目 iBatis,支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。
  • Apache DBUtils 、Spring JDBCTemplate

1.6 Hibernate的优点

  • Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
  • Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作 session.save(User);
  • Hibernate使用java的反射机制。
  • Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,有一对一到多对多的各种复杂关系映射。

hibernate如果有非常多的对象转换成sql就不如MyBatis自己写sql来的快了,因为它有一个转换的过程。

第二节 hibernate的简单使用

2.1 下载hibernate的jar包

  1. 下载hibernate的jar包
  • 官方网址:http://hibernate.org/orm/.
  • 最新的5.4,一般不用最新的,使用hibernate一般是老项目不会使用最新的版本
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第2张图片
  • 这里使用的是3.6.10版本的
  • 百度云链接无故被封。。。无法提供。。。

2.2 数据库建表

Navicat Premium 11 64位本来也放在上面百度云盘中

  1. 打开Navicat Premium新建查询
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第3张图片
create database hibernate_day1;
use hibernate_day1;
create table t_user(
  id int auto_increment primary key,
  username varchar(50),
  password varchar(30)
);

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第4张图片

2.3 在IDEA中新建一个javaweb项目

  • 下载、安装、配置IDEA
  • https://blog.csdn.net/qq_43414199/article/details/107847162.
  1. 创建项目,这里可以暂时不使用Tomcat,web.xml可要可不要
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第5张图片

2.4 导入jar包

  • 这里我们使用3.6.10的版本开发,4.0开发是建议使用注解

  • 所需要导入的jar包,如下图,然后再导入一个mysql数据库连接驱动

    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第6张图片
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第7张图片
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第8张图片

  • IDEA中导完jar包不要忘了右键Add as Library 导入
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第9张图片

  • 可以设置jar包适用的范围是整个项目还是这个模块,这里选择模块即可
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第10张图片

  • jar包的作用
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第11张图片

2.4 hibernate的核心配置文件

  1. hibernate.cfg.xml放入src
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第12张图片
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第13张图片
  2. hibernate.cfg.xml配置文件内容


<hibernate-configuration>
	<session-factory>
		
		
		
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driverproperty>
		
		<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day1property>
		
		<property name="hibernate.connection.username">rootproperty>
		
		<property name="hibernate.connection.password">rootproperty>

		
		<property name="show_sql">trueproperty>
		
		
		<property name="format_sql">trueproperty>
		
		
		<property name="hibernate.connection.autocommit">trueproperty>
		
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialectproperty>
		
		<mapping resource="com/it/hibernate/domain/User.hbm.xml" />
	session-factory>
hibernate-configuration>

2.6 编写JavaBean和映射文件.hbm.xml

  1. JavaBean与.hbm.xml文件所属的包和文件名要一致
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第14张图片
  2. User.java提供getter、setter、无参构造、username、password有参构造
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第15张图片
  3. User.hbm.xml配置内容

<hibernate-mapping>
	
	<class name="com.it.hibernate.domain.User" table="t_user">
		
		<id name="uid" column="id">
			
			<generator class="native">generator>
		id>
		
		<property name="username">property>
		<property name="password">property>
	class>
hibernate-mapping>

2.7 测试

  • 创建com.it.hibernate.test包,在下面写一个Demo1.java
package com.it.hibernate.test;

import com.it.hibernate.domain.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class Demo1 {
     

	@Test
	public void test1(){
     
	
		//1.获取核心配置文件对象,默认是加载src的hibernate.cfg.xm文件
		//new Configuration()加载的是hibernate.properties,.configure()才是加载src的hibernate.cfg.xm
		Configuration cfg = new Configuration().configure();
		
		//2.创建会话工厂
		SessionFactory factory = cfg.buildSessionFactory();
		
		//3.创建会话
		Session sessoin = factory.openSession();
		
		//4.开启事务
		Transaction trans = sessoin.getTransaction();
		trans.begin();
		
		//5.保存
		User user = new User();
		user.setUsername("shu01");
		user.setPassword("123");
		sessoin.save(user);
		
		//6.提交事务
		trans.commit();
		//7.关闭会话
		sessoin.close();
		//8.关闭工厂,释放资源
		factory.close();
	}
}

  • 运行成功:
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第16张图片
  • 刷新一下数据库中的表,数据插入成功
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第17张图片

2.8 常见的问题

1.The server time zone value ‘?й???’ is unrecognized or represents more than one time zone

  • 解决方法1:(快速)
  • 在数据库连接URL后,加上 ?serverTimezone=UTC(注意大小写必须一致)
<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day1?serverTimezone=UTCproperty>
  • 解决方法2:(一劳永逸)
  1. msyql环境配置:path里添加mysql的安装路径到bin
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第18张图片
  2. 进入命令窗口(Win + R),连接数据库 mysql -hlocalhost -uroot -p,回车,输入密码,回车,如图:
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第19张图片
  3. 输入 show variables like ‘%time_zone’; (注意不要漏掉后面的分号),回车,如图:SYSTEM就表示未设置还是默认的
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第20张图片
  4. 输入 set global time_zone =’+8:00’; (注意不要漏掉后面的分号),回车,输入 flush privileges; (立即生效)再次查询后如图:即设置成功。
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第21张图片

也可以通过修改my.cnf配置文件修改时区
default-time_zone = ‘+8:00’
重启mysql使新时区生效

2. org.hibernate.exception.GenericJDBCException: Cannot open connection

  • 解决方法:
  1. 用5版本的jar包,连接8版本的数据库,要加上
    ?useUnicode=true&characterEncoding=utf-8 (使用Unicode设置字符集utf8)
  2. 也可以换成8版本的jar,加上cj,也可以解决,主要是上面的时区设置,添加8版本的jar记得Add as Library…一下,不然不生效

3. table里报错和Cannot resolve column ‘id’

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第22张图片

  • 这是由于没有关联数据库资源,会话工厂资源。
  1. 选择IDEA右边的Database,添加一个需要的数据库,这里用的是mysql
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第23张图片
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第24张图片
  2. 测试mysql连接,需要设置时区,上面已提供(一劳永逸)。
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第25张图片
  3. View -> Tool Windows -> PersistenceHibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第26张图片
  • 也可以直接左下角打开 Persistence
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第27张图片
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第28张图片
  1. 右键->Assign Data Sources
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第29张图片
  • 点击灰色倒三角,找到刚才配置的数据库连接,ok,就会发现table和column报错消失
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第30张图片

4. org.hibernate.MappingException: Unknown entity: com.it.hibernate.domain.User

  • 未知的实体:com.it.hibernate.domain.User
  • 一般是在hibernate.cfg.xml中没有配置JavaBean与表的映射文件,或是这里写错
<mapping resource="com/it/hibernate/domain/User.hbm.xml" />

第三节 API详解

3.1 Configuration 配置对象

Hibernate的核心配置文件的多种形式

  • hibernate.cfg.xml 通常使用xml配置文件,可以配置内容更丰富。
  • hibernate.properties 用于配置key/value 形式的内容,key不能重复的。配置有很多的局限性。一般不用。【可以进入hibernate-distribution-3.6.10.Final\project\etc目录看内容】

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第31张图片

Configuration 对象

  • Configuration对象就是用来加载配置文件
  • new Configuration构造方法配置加载的是hibernate.properties
  • configre()方法加载的是hibernate.cfg.xml
  • 默认情况下,上面两种配置文件都需要放在src目录下
  • 查看源码发现:
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第32张图片
  • configure(String resource)这个方法可以指定配置文件路径

加载映射文件方式

  • 一种是在hibernate.cfg.xml配置,另一种是代码设置
  1. 在hibernate.cfg.xml配置mapping【常用】
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第33张图片

使用cfg.addResource(“com/it/hibernate/domain/User.hbm.xml”);
或者使用cfg.addClass(User.class);,都要注释hibernate.cfg.xml里的maping,否则冲突
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第34张图片

  1. cfg.addResource(“com/it/hibernate/domain/User.hbm.xml”);
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第35张图片
  2. cfg.addClass(User.class);
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第36张图片

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第37张图片

  • addClass能将mapping资源名格式转换成我们需要的格式
    在这里插入图片描述

常见异常

org.hibernate.InvalidMappingException: Could not parse mapping document from resource com/it/hibernate/domain/User.hbm.xml

  • 重复了映射文件,或删除或注释一个即可
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第38张图片

平时开发中:将 实体.hbm.xml 映射,配置在hibernate.cfg.xml中,即mapping配置

3.2 SessionFactory 工厂

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第39张图片

  • SessionFactory 相当于java web连接池,用于管理所有session
  • 获得SessionFactory 方式:config.buildSessionFactory();
  • sessionFactory 还用于缓存配置信息 (数据库配置信息、映射文件,预定义HQL语句 等)
  • SessionFactory线程安全,多个线程同时访问时,不会出现线程并发访问问题。

3.3 Session 会话

session会话的获取

  • sessionFactory提供了两个方法来获取session
  1. factory.openSession() 获取一个全新的session
  2. factory.getCurrentSession() 获取一个与当前线程绑定的session
  • 要使用这个方法必须在hibernate.cfg.xml中配置
    thread
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第40张图片
	
	<property name="hibernate.current_session_context_class">threadproperty>
  • hibernate支持,将创建的session绑定到本地线程中,底层使用ThreadLocal,在程序之间共享session。
  • 如果提交或者回滚事务,底层将自动关闭session
  • Demo2.java
package com.it.hibernate.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class Demo2 {
     

    @Test
    public void test1(){
     
        //保存用户数据
        //1.获取核心配置文件对象,默认是加载src的hibernate.cfg.xm文件
        Configuration cfg = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory factory = cfg.buildSessionFactory();

	/*	sessionFactory提供了两个方法来获取session
		1.factory.openSession() 获取一个全新的session
		2.factory.getCurrentSession() 获取一个与当前线程绑定的session*/

		//都是新的session,hashCode不同
        Session session1 = factory.openSession();
        Session session2 = factory.openSession();
        System.out.println(session1.hashCode());
        System.out.println(session2.hashCode());
		
		//共享的,相同session
        Session session3 = factory.getCurrentSession();
        Session session4 = factory.getCurrentSession();
        System.out.println(session3.hashCode());
        System.out.println(session4.hashCode());
		//3、4与5、6不同线程session不同
        new Thread(){
     
            public void run() {
     
            	//同一个线程共享,相同的session
                Session session5 = factory.getCurrentSession();
                Session session6 = factory.getCurrentSession();
                System.out.println(session5.hashCode());
                System.out.println(session6.hashCode());
            };
        }.start();

        //4.关闭会话
        //如果是通过open方法打开session,要自己关闭
        session1.close();
        session2.close();
        //如果是通过get方法获取session,session不需要关闭,因为事务提交或者回滚会自动关闭
        //5.关闭工厂,释放资源
        factory.close();
    }
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第41张图片

3.4 Transaction事务

  • Hibernate中怎么获取事务,开启、提交、回滚事务?
  • Demo3.java
package com.it.hibernate.test;

import com.it.hibernate.domain.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;


public class Demo3 {
     

    @Test
    public void test1(){
     
        //保存用户数据
        //1.获取核心 配置文件对象
        Configuration cfg = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory factory = cfg.buildSessionFactory();

        //3.通过会话工厂获取session对象
        Session session =  factory.openSession();

        //4.事务
        //4.1获取事务
        Transaction trans = session.getTransaction();
        //4.2开启事务【没有开启事务和提交事务,数据是不会存入数据库中的】
        trans.begin();//也可以用Session.beginTransaction();
		
		//插入数据
        User user = new User("shu03","123");
        session.save(user);
		
		//4.3回滚事务
        //trans.rollback();//回滚事务,这个代码写在catch中
		
		//4.4提交事务
		trans.commit();
		
        //5.关闭会话
        session.close();

        //6.关闭工厂,释放资源
        factory.close();
    }
}

try{
     
   //开启
   //session操作
   //提交
} catch(e){
     
   //回滚
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第42张图片
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第43张图片

注释事务,sql能运行,数据库中也成功插入数据,这是因为我们一开始在hibernate.cfg.xml文件中配置置了自动提交事务
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第44张图片
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第45张图片
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第46张图片
再将它注释,发现sql能运行,数据库中无数据插入,因为没有开启事务和提交事务,数据是不会存入数据库中的
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第47张图片
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第48张图片

  • 不需要手动的管理事务,之后所有的事务管理都交予spring。
  • 事务可以在hibernate.cfg.xml配置文件中设置

<property name="hibernate.connection.autocommit">trueproperty>

3.5 session的api(方法)

  • save 保存
  • get 通过id查询,如果没有,返回null
  • load 通过id查询,如果没有,抛异常
  • update 更新
  • delete 删除

save保存、get与load查询

  • Demo4.java,User.java要提供toString方法
package com.it.hibernate.test;

import com.it.hibernate.domain.User;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.junit.Test;


public class Demo4 {
     

    @Test
    public void test1(){
     
        //保存用户数据
        //1.获取核心配置文件对象
        Configuration configure = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory sessionFactory = configure.buildSessionFactory();

        //3.通过会话工厂获取session对象
        Session session = sessionFactory.openSession();

        //save保存,插入数据,需要提交事务
        User user1 = new User("shu04","123");
        session.save(user1);

        //get查询,根据id查询,hibernate会根据类名查表,如果没找到,返回null值
        User user2 = (User) session.get(User.class, 19);//强转为User
        System.out.println(user2);//User要提供toString方法

        //load查询,根据id查询,如果没查到,会抛出ObjectNotFoundException异常
        User user3 = (User) session.load(User.class, 19);
        System.out.println(user3);//User要提供toString方法

        //4.关闭会话
        session.close();

        //5.关闭工厂,释放资源
        sessionFactory.close();
    }
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第49张图片
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第50张图片

delete删除

  • Demo5.java
package com.it.hibernate.test;

import com.it.hibernate.domain.User;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.junit.Test;


public class Demo5 {
     

    @Test
    public void test1(){
     
        //保存用户数据
        //1.获取核心配置文件对象
        Configuration configure = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory sessionFactory = configure.buildSessionFactory();

        //3.通过会话工厂获取session对象
        Session session = sessionFactory.openSession();

        /* delete删除数据的两种方式
            1.先get方法获取删除对象,再使用delete方法删除
            2.它内部删除是根据id来删除,先获取比较麻烦,还要查询一次
            直接创建一个User对象,设置id,再调用delete方法
         */
        /*由于在hibernate.cfg.xml中配置的自动提交事务
          对insert有效,对delete无效,所有要我们自己开启、提交事务
         */
        //开启事务
        session.getTransaction().begin();
        
        //删除方法1
        User user1 = (User) session.get(User.class, 20);
        session.delete(user1);

        //删除方法2
        User user2 = new User();
        user2.setUid(23);
        session.delete(user2);

        //提交事务
        session.getTransaction().commit();

        //4.关闭会话
        session.close();

        //5.关闭工厂,释放资源
        sessionFactory.close();
    }
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第51张图片
Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第52张图片

如果数据库中没有对应的id,会报错
1.org.hibernate.StaleStateException: Batch update returned unexpected row count from update [1]; actual row count: 0; expected: 1
2.java.lang.IllegalArgumentException: attempt to create delete event with null entity

update更新

  • Demo6.java
package com.it.hibernate.test;

import com.it.hibernate.domain.User;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.junit.Test;


public class Demo6 {
     

    @Test
    public void test1(){
     
        //保存用户数据
        //1.获取核心配置文件对象
        Configuration configure = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory sessionFactory = configure.buildSessionFactory();

        //3.通过会话工厂获取session对象
        Session session = sessionFactory.openSession();

        /* update更新数据
            方式1:先使用get方法获取对象,再使用set方法设置值,事务提交,自动执行update
            方式2:自己封装User,设置id,这个时候,需要调用update方法
         */

        //开启事务
        session.getTransaction().begin();
        //update方法1,从数据库获取信息,修改
        User user = (User) session.get(User.class, 24);
        user.setPassword("456");
        //1.1更新使用update方法【一般使用这个】
        //update方法判断user,有id会更新,没有id,会报错!
        session.update(user);
        //1.2更新也可以调用save方法
        //save方法判断user,有id会更新
        //session.save(user);
        //1.3更新还可以使用saveOrUpdate方法:
        //saveOrUpdate方法会判断user里有没有id,有id,更新数据,没有id,插入数据
        //saveOrUpdate(user);
        //1.4更新还可以什么都不写,注释上面的session.update(user);,
        //发现也能执行成功,这是由于模型的状态(托管、游离)

        //update方法2,自己封装User,设置id,这时必须要调用update方法,不能不写,否则更新不了
        User user1 = new User();
        user1.setUid(25);
        user1.setUsername("shu06");
        user1.setPassword("123456");
        session.update(user1);//这时必须要写update方法

        //提交事务
        session.getTransaction().commit();

        //4.关闭会话
        session.close();

        //5.关闭工厂,释放资源
        sessionFactory.close();
    }
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第53张图片

注意:这里update方法1中只设置了password,但是执行的时候却设置了username,这是update的特性,会根据id把里面的值重新设置一遍,性能浪费,不如只更新我们所需要更新的那个字段性能好。

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第54张图片

3.6 get和load方法的区别

  • get方法是直接加载数据库,当执行完27行就执行了sql
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第55张图片
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第56张图片

  • load的设计是懒加载,用到时才去查询数据库,执行了28行,里面用到了user.getPassword()才去查询数据库。
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第57张图片
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第58张图片

  • load方法返回的是对象的一个代理对象
    在这里插入图片描述

  • load执行原理图
    Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第59张图片

3.7 Query 查询对象

  • HQL:Hibernate Query Language的缩写,就是Hibernate的查询语言
  • HQL是面向对象查询语言,最终底层要转成面向数据库查询语言
  • SQL:直接面向数据库查询语言
  • Query:用于查询的对象,可以设置查询条件和分页查询
  • Demo7.java
package com.it.hibernate.test;

import com.it.hibernate.domain.User;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.junit.Test;

import java.util.List;


public class Demo8 {
     

    @Test
    public void test1(){
     
        //保存用户数据
        //1.获取核心配置文件对象
        Configuration configure = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory sessionFactory = configure.buildSessionFactory();

        //3.通过会话工厂获取session对象
        Session session = sessionFactory.openSession();

        //HQL:Hibernate Query Language
        //(1).查询所有用户【注意:User类名】
        Query query = session.createQuery("from User ");//from大小写都可以

        //(2).查询带条件的用户【注意:username和password是User的对象属性,而不是表的字段名】
        Query query1 = session.createQuery("from User where username = ? and password = ? ");
        query1.setParameter(0,"shu04");//0代表第一个?
        query1.setParameter(1,"456");//1代表第二个?

        //(3).分页(limit ?,?)
        //Query query = session.createQuery("from User ");
        query.setFirstResult(0);//相当于limit 0,3 第一页,每页显示条数3
        query.setMaxResults(3);//3,3 第二页,每页显示条数3
        //第一页开始0、第二页开始3,计算方法:(页数-1)*每页显示条数

        //(4).查询返回单行数据
        //它只返回唯一一个,否则报错
        /*User user = (User) query.uniqueResult();
        System.out.println(user);*/

        //(5).执行查询,返回多行数据
        List<User> list = query.list();
        //遍历
        for (User user : list) {
     
            System.out.println(user);
        }

        //4.关闭会话
        session.close();

        //5.关闭工厂,释放资源
        sessionFactory.close();
    }
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第60张图片

3.8 Criteria

  • QBC(query by criteria),hibernate提供纯面向对象查询语言,提供直接使用PO对象进行操作。
  • 上面还要写少量的hql,使用criteria将可以完全不使用sql。

一些概念:
PO:persistent object ,用于与数据库交互数据。–dao层 (JavaBean + hbm )
BO:Business object 业务数据对象。–service层
VO:Value Object 值对象。–web层

  • Demo9.java
package com.it.hibernate.test;

import com.it.hibernate.domain.User;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;


public class Demo9 {
     

    @Test
    public void test9(){
     
        //保存用户数据
        //1.获取核心配置文件对象
        Configuration configure = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory sessionFactory = configure.buildSessionFactory();

        //3.通过会话工厂获取session对象
        Session session = sessionFactory.openSession();

        //Criteria:Hibernate独创的查询对象,全程无hql语句
        Criteria criteria = session.createCriteria(User.class);

        //【eq = 】(等于)
        //查询数据库中username为shu04、password为456的数据
        //criteria.add(Restrictions.eq("username", "shu04"));
        //criteria.add(Restrictions.eq("password", "456"));
        //System.out.println(criteria.uniqueResult());
        //【gt >】  【ge >=】
        //查询数据库中id大于等于27的数据
        //criteria.add(Restrictions.ge("uid",27));
        //System.out.println(criteria.list());
        //【lt <】  【le <=】 可以按住Ctrl点击Restrictions查看更多

        //【模糊查询 like】
        criteria.add(Restrictions.like("username","s%"));
        System.out.println(criteria.list());

        //4.关闭会话
        session.close();

        //5.关闭工厂,释放资源
        sessionFactory.close();
    }
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第61张图片

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第62张图片

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第63张图片

3.9 SQLQuery

  • SQLQuery:使用原生的SQL语句查询。
  • 并不是所有sql都能转换成hql,这时就要回到老本行写sql了。
  • Demo10.java
package com.it.hibernate.test;

import org.hibernate.SQLQuery;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.junit.Test;

import java.util.List;


public class Demo10 {
     

    @Test
    public void test9(){
     
        //保存用户数据
        //1.获取核心配置文件对象
        Configuration configure = new Configuration().configure();

        //2.创建会话工厂
        SessionFactory sessionFactory = configure.buildSessionFactory();

        //3.通过会话工厂获取session对象
        Session session = sessionFactory.openSession();

        //使用原生的sql来查询语句
        SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
        
        //直接遍历发现,查询结果的每一行数据存储在一个数组中,数组又存在集合中
        //所以要再遍历
        List<Object[]> list = sqlQuery.list();
        for (Object[] obj : list) {
     
            for (Object o : obj) {
     
                System.out.println(o);
            }
            System.out.println("-----------");
        }

        //4.关闭会话
        session.close();

        //5.关闭工厂,释放资源
        sessionFactory.close();
    }
}

Hibernate简介、hibernate的简单使用、常见问题、hibernate的API详解-day01_第64张图片

吐槽:虽然hibernate留了后门给我们使用,可以使用原生sql,但是这里我们还不如使用DBUtils,只用导入一个jar包。。。

3.10 抽取工具类

  • 上面有些代码是固定的,不如抽取一个工具类来简化书写。
  • HibernateUtils.java
package com.it.hibernate.uitls;

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

public class HibernateUtils {
     

	private static SessionFactory factory;
	static{
     
		//1.获取核心配置文件对象
		Configuration configuration = new Configuration().configure();
				
		//2.创建会话工厂
		factory = configuration.buildSessionFactory();
		
		//监听程序关闭,关闭时释放会话工厂
		Runtime.getRuntime().addShutdownHook(new Thread(){
     
			@Override
			public void run() {
     
				//System.out.println("Program shutdown...");//程序关闭
				//关闭会话工厂
				factory.close();
			}
		});
		
	}
	
	public static Session openSession(){
     
		return factory.openSession();
	}
	
	public static Session getCurrentSession(){
     
		return factory.getCurrentSession();
	}
	
}

  • 使用HibernateUtils后的Demo10
package com.it.hibernate.test;

import com.it.hibernate.uitls.HibernateUtils;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.junit.Test;

import java.util.List;


public class Demo10 {
     

    @Test
    public void test9(){
     
        //使用HibernateUtils获取session对象
        Session session = HibernateUtils.openSession();

        //使用原生的sql来查询语句
        SQLQuery sqlQuery = session.createSQLQuery("select * from t_user");
        
        //直接遍历发现,查询结果的每一行数据存储在一个数组中,数组又存在集合中
        //所以要再遍历
        List<Object[]> list = sqlQuery.list();
        for (Object[] obj : list) {
     
            for (Object o : obj) {
     
                System.out.println(o);
            }
            System.out.println("-----------");
        }

        //关闭会话
        session.close();

    }
}

你可能感兴趣的:(Hibernate,hibernate,java,数据库,软件框架,后端)