Hibernate保姆教学 (从Hibernate到JPA到SpringDate)

Hibernate入门到大神

Hibernate用idea或者Eclipse操作项目(全文配图)
已经学会了增删改查但是动不动就几十行或者上百行的代码,还有那让人讨厌的sql语句,让我们广大程序员是深表厌恶,为此国外的一个牛人就创建了一个能够进行持久化操作的框架他就是我们今天要讲的Hibernate.
持久化操作: 持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。但是这些方式一般没有完整的配套的对数据的管理工具,而这正是关系型数据库的优势
简而言之:就是将内存中的数据保存到数据库中,或者进一步简化就是增删改查
1.hibernate:是一款ORM形式的数据库持久化框架,主要是通过直接操作对象进而达到间接的操作关系型数据库数据表的目的

ORM:即是Object/Relational Mapping(意思叫对象关系映射),是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。

  • hibernate与传统的jdbc的比较

相同点:
两者都是JAVA的数据库操作中间件。
两者对于数据库进行直接操作的对象都不是线程安全的,都需要及时关闭。
两者都可以对数据库的更新操作进行显式的事务处理。
不同点:
使用的SQL语言不同:JDBC使用的是基于关系型数据库的标准SQL语言,Hibernate使用的是HQL(Hibernate query language)语言
操作的对象不同:JDBC操作的是数据,将数据通过SQL语句直接传送到数据库中执行,Hibernate操作的是持久化对象,由底层持久化对象的数据更新到数据库中。
数据状态不同:JDBC操作的数据是“瞬时”的,变量的值无法与数据库中的值保持一致,而Hibernate操作的数据是可持久的,即持久化对象的数据属性的值是可以跟数据库中的值保持一致的。

一:myeclisp创建Hibernate项目

0.创建数据库

  • 在mysql中新建一个hibernates的库,然后把下载的数据复制运行
  • 说明:user表是单表
  • Student的sid字段绑定classes的sid字段(主外键)
  • 学生和教室的关系
CREATE TABLE `classes`  (
  `cid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `cinfor` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of classes
-- ----------------------------
INSERT INTO `classes` VALUES ('001', '1号教室');
INSERT INTO `classes` VALUES ('002', '2号教室');
INSERT INTO `classes` VALUES ('003', '3号教室');
INSERT INTO `classes` VALUES ('004', '4号教室');

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `sid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `sname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `sage` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `csid` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`sid`) USING BTREE,
  INDEX `Student_Classes`(`csid`) USING BTREE,
  CONSTRAINT `Student_Classes` FOREIGN KEY (`csid`) REFERENCES `classes` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('01', '张三', '15', '001');
INSERT INTO `student` VALUES ('02', '李四', '56', '002');
INSERT INTO `student` VALUES ('03', '王五', '66', '004');
INSERT INTO `student` VALUES ('06', '李莫愁', '66', '001');
INSERT INTO `student` VALUES ('07', '杨过', '33', '002');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '张三', 18);
INSERT INTO `user` VALUES (2, '李四', 11);
INSERT INTO `user` VALUES (3, '王五', 11);
INSERT INTO `user` VALUES (4, 'xxx', 1);

1.连接数据库

  • 需要用到myeclisp创建Hibernate项目,因为myeclisp可以反向生成映射文件,降低开发时间和容错
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    输入连接名,连接URL
    jdbc:mysql://127.0.0.1:3306/hibernates?useUnicode=true&characterEncoding=utf-8
    账号密码
    添加JAR包,mysql的驱动包
    在这里插入图片描述
  • 选择数据库
    在这里插入图片描述

2. 创建普通的JAVA项目

在这里插入图片描述
在创建lib的jar包

3.给项目添加Hibernate框架

  • Jar包放在lib下
    在这里插入图片描述
  • 创建配置文件放在src下
    在这里插入图片描述
  • 选择刚才创建的连接对象
  • 创建sessionFactory,放在目录下
    在这里插入图片描述

4.查看配置文件

在这里插入图片描述

4.反向生成配置文件

  • 创建文件夹
    在这里插入图片描述
    ps:数据库:

  • 3个表全选上
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    何为映射?映射就是开学了,老师带着一本花名册,里面有你的名字,老师通过花名册的名字可以找到你(抽象比喻)

5.配置文件

在这里插入图片描述
在这里插入图片描述
f---------------------------------------------------------etch="select"是抓取策略,后面会讲

在这里插入图片描述

二:idea创建Hibernate项目

1.idea创建一个maven项目

-在pom中导入相关依赖

 <dependencies>

            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-core</artifactId>
                <version>5.0.7.Final</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.36</version>
            </dependency>

        </dependencies>

2.连接数据库

在这里插入图片描述
在这里插入图片描述
点击TestConnection进行验证,如果出错会提示,下载驱动包即可

  • 无法完成可以自己导入自己本地的驱动
    在这里插入图片描述

  • 选择需要连接的库表文件
    在这里插入图片描述

  • 这里就算连接成功了

3.添加框架

在这里插入图片描述

  • 把匹配值文件也添加进来

    在这里插入图片描述
    在这里插入图片描述

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
<!--    <property name="connection.url"/>-->
<!--    <property name="connection.driver_class"/>-->
    <!-- <property name="connection.username"/> -->
    <!-- <property name="connection.password"/> -->

    <!-- DB schema will be updated if needed -->
    <!-- <property name="hibernate.hbm2ddl.auto">update</property> -->
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernates?useUnicode=true&amp;characterEncoding=utf-8</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">root</property>
    <property name="show_sql">true</property>
    <property name="dialect">  org.hibernate.dialect.MySQLDialect </property>
  </session-factory>
</hibernate-configuration>

4.配置映射文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 补充一点,上面生成映射文件之后需要将show defauit …这个选上对钩,不选上对钩不会生成外键映射属性(重要)
  • 踩坑注意点
  • 将sid删掉,删除了sid之后,把配置文件标红的也删掉,只要标红就删掉
    在这里插入图片描述
  • 测试 查询正常

在这里插入图片描述

Hibernate 查询语法

6.Hibernate七步走(重点)

package bj.sh.gy.Test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

import bj.sh.gy.entity.Student;
import bj.sh.gy.entity.User;


/**
 * @desc hb
 * @author 20505
 *
 */
public class Test {
   public static void main(String [] args){
	 
	//1.加载配置
	//默认去加载Src下的名字为hibernate.cfg.xml的文件为了启动hibernate 框架
	   Configuration config=  new Configuration().configure("xxxx");
	   
	 //2.创建sesionFactory对象
	   SessionFactory  sesionFactory =config.buildSessionFactory();
	   
	 //3.获取session  
	   Session session = sesionFactory.openSession();
-	   
	  //4.开启事务
	   Transaction transation = session.beginTransaction();
	   
	  //5.执行持久化操作
	   Criteria query_qbc = session.createCriteria(Student.class);
	   List <Student>list = query_qbc.list();
	   for( Student stu:list){
		   System.out.println(stu.getSname()+"==="+stu.getClasses().getCinfor());
	   }
	   
	  //6.提交事务
	   transation.commit();
	   
	  //7:关闭相关对象
	   session.close();
	   sesionFactory.close();
   }
}

在这里插入图片描述

7.Hibernate核心接口(重点)

  • 以后用Hibernate进行开发就会进行打交道

  • (1)Configuration 接口/类

Configuration 是Hibernate的入口,主要作用就是加载配置文件的,默认去加载Src下的名字为hibernate.cfg.xml的文件为了启动hibernate 框架,如果没找到就会报错,如果没将配置文件放在src下hibernate.cfg.xml,name就要在参数里面去指向地址
Configuration config= new Configuration().configure(“xxxx”);

  • (2)SessionFactory接口
    SessionFactory sesionFactory =config.buildSessionFactory();
    为了初始化Hibernate
  • (3)session接口
    Session session = sesionFactory.openSession();
    *所有的持久化操作都是在Sesssion接口的基础之上进行的
    session .sava()添加…等等好多方法
  • 4) Transaction transation 接口
    对事务进行一些相关的操作
  • (5)Query和Criteria接口
    Query query=session.createQuery(" from HibCode");
    Query接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作。值得注意的是Query接口也是轻量级的,它不能在Session之外使用。
    uniqueResult()返回唯一的结果,有多个就报错
    list()将结果集封装
    Criteria接口与Query接口非常类似,它允许你创建并执行面向对象的标准化查询。

8. HibernateSessionFactory

  • HibernateSessionFactory 是官方提供的一个工具类
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    总结:HibernateSessionFactory是一个工具类,可以获得session对象

三:用idea或者Eclipse操作项目

  • 如果是idea创建的项目,这步跳过
    在这里插入图片描述
  • 在myEclipse中查看项目的路径,然后用idea打开,修改jdk为自己电脑的版本即可

添加一条数据save()

 transation.begin();    //开启事务

            StudentEntity student = new StudentEntity();       //实例化实体类
            student.setSid(UUID.randomUUID().toString());
            student.setSname("果");
            student.setSage("78");

            ClassesEntity classesEntity = new ClassesEntity();
            classesEntity.setCid("001");

            student.setClassesByCsid(classesEntity);   //因为咱们的表时有主外键的,想添加student的sid,就需要有一个classes的对象的sid属性
            session.save(student);

            //6.提交事务
            transation.commit();

在这里插入图片描述

查询一条数据get()

  • get()方法查询一条:根据id直接去查询,如果没有找到就返回null
  • 通过class和条件,主键的id=01
 StudentEntity student = session.get(StudentEntity.class, "01");
            System.out.println(student.getSname());

在这里插入图片描述

查询一条数据 Load()

  • load()方法查询一条:先new一个新的对象,如果没有找到就抛出异常
 StudentEntity student = session.load(StudentEntity.class, "01");
            System.out.println(student.getSname());

在这里插入图片描述

修改数据 update

    transation.begin();    //开启事务


            StudentEntity student = session.load(StudentEntity.class, "01");
            student.setSname("xxjob");

            session.update(student);   //修改
            //6.提交事务
            transation.commit();

在这里插入图片描述

  • 还有一个修改方法
 StudentEntity student = session.get(StudentEntity.class, "02");
            System.out.println(student.getSname());
            student.setSname("瓦纳乌");


            StudentEntity student2 = session.get(StudentEntity.class, "02");
            System.out.println(student2.getSname());

对数据进行查询,查新的结果只需要set一下就可以实现修改数据的操作
在这里插入图片描述

删除数据delete


            StudentEntity student = session.load(StudentEntity.class, "01");
            session.delete(student);   //删除

在这里插入图片描述

一对多数据查询一

package bj.sh.gy.Test;

import bj.sh.gy.entity.Classes;
import bj.sh.gy.entity.Student;
import bj.sh.gy.sessionfaction.HibernateSessionFactory;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * @author LXY
 * @desc
 * @time 2022-10-14  22:40
 */
public class Test003 {

    public static void main(String[] args) {
        Session session = new HibernateSessionFactory().getSessionFactory().openSession();
        //4.开启事务
        Transaction transation = session.beginTransaction();

        Query query = session.createQuery("from bj.sh.gy.entity.Classes");  //hql语句,from 实体类的路径,通过配置文件的反射去获取数据
        List<Classes> list = query.list();   //将最终的结果转为list
        for (Classes classes : list) {   //迭代
            System.out.print(classes.getCinfor());   //打印每个教室
            Set students = classes.getStudents();   //每个教室有很多个学生,所以用set接受,自动生成的时候,就生成了set
            Iterator it = students.iterator();  //迭代
            while (it.hasNext()){
               Student student= (Student) it.next();   //将每个结果转为Student
                System.out.println(student.getSname());  //打印
            }

        }
        //6.提交事务
        transation.commit();

        //7:关闭相关对象
        session.close();
    }

}

为什么用set接受收student的

在这里插入图片描述
在这里插入图片描述

一对多查询多

package bj.sh.gy.Test;
import bj.sh.gy.entity.Student;
import bj.sh.gy.sessionfaction.HibernateSessionFactory;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import java.util.List;

/**
 * @author LXY
 * @desc
 * @time 2022-10-14  22:52
 */
public class test004 {
    public static void main(String[] args) {
        Session session = new HibernateSessionFactory().getSessionFactory().openSession();
        //4.开启事务
        Transaction transation = session.beginTransaction();

        Query query = session.createQuery("from bj.sh.gy.entity.Student");  //hql语句,from 实体类的路径,通过配置文件的反射去获取数据
        List<Student> list = query.list();   //将最终的结果转为list

        for (Student student : list) {

            System.out.print(student.getSname());
            System.out.println("===="+student.getClasses().getCinfor());
        }

        //6.提交事务
        transation.commit();

        //7:关闭相关对象
        session.close();
    }
}

在这里插入图片描述
在这里插入图片描述

配置控制台打印sql语句

  • 在配置文件中增加
  • 作用:更直观的看到sql语句的执行情况,是如何进行查询的,更加方便理解
		<property name="show_sql">true</property>

QBC 查询

QBC,即 Query By Criteria,它是 Hibernate 提供的另一种查询方式,使用 HQL 查询需要写 hql 语句,但使用 QBC 查询不需要写语句,直接使用方法实现

QBC 查询:查询一对多的多

   Criteria criteria = session.createCriteria(Student.class);
        List<Student> list = criteria.list();
        for (Student student : list) {
            System.out.println(student.getSname());
            System.out.println(student.getClasses().getCinfor());
        }

在这里插入图片描述

QBC 查询:条件查询

  • 与mybatisplus中的QueryWrapper 功能相同
    criteria.add(Restrictions.你需要的方法)
    在这里插入图片描述
    Criteria criteria = session.createCriteria(Student.class);
        criteria.add(Restrictions.eq("sid","01"));
        List<Student> list = criteria.list();




        for (Student student : list) {
            System.out.println(student.getSname());
            System.out.println(student.getClasses().getCinfor());
        }

如何理解:?
在这里插入图片描述

QBC 多条件查询

        Criteria criteria = session.createCriteria(Student.class);
        criteria.add(Restrictions.eq("sid","01"));
        criteria.add(Restrictions.like("sname","张%"));
        List<Student> list = criteria.list();

在这里插入图片描述

QBC 排序

        Criteria criteria = session.createCriteria(Student.class);
        criteria.addOrder(Order.asc("sage"));
        List<Student> list = criteria.list();

在这里插入图片描述

QBC 分页查询

     Criteria criteria = session.createCriteria(Student.class);
        criteria.setFetchSize(0); //当前页
        criteria.setMaxResults(2); //每页显示多少条

在这里插入图片描述

QBC 聚合操作

  • 里面有很多的方法提供给使用
    在这里插入图片描述

  • 查询count


        Criteria criteria = session.createCriteria(Student.class);
        criteria.setProjection(Projections.count("sid"));
        Object o = criteria.uniqueResult();
        System.out.println(Integer.parseInt(o+""));

在这里插入图片描述

QBC:条件查询显示一条

   Criteria criteria = session.createCriteria(Student.class);
        criteria.add(Restrictions.eq("sid","01"));
        Student o = (Student) criteria.uniqueResult();
        System.out.println(o.getSname());

在这里插入图片描述

HQL查询

  • (Hibernate Query Language):面向对象的查询语言。

HQL:查询全部(from 查询)

 Query query = session.createQuery("from bj.sh.gy.entity.Student");
        List <Student>  list = query.list();

在这里插入图片描述

HQL:多表查询(from )

        Query query = session.createQuery("from bj.sh.gy.entity.Student,bj.sh.gy.entity.Classes");
        List list = query.list();

        for (int i = 0; i < list.size(); i++) {
            Object[] objs=(Object[])list.get(i);
            System.out.println("Student:"+((Student)objs[0]).getSname());
            System.out.println("Classes:"+((Classes)objs[1]).getCinfor());
            System.out.println("=================");
        }

HQL: 查询数量(Select )

Query query =query=session.createQuery("select  count (*) from bj.sh.gy.entity.Student");
        List list = query.list();
        System.out.println(list.get(0));

在这里插入图片描述

在这里插入图片描述

HQL: 只查询一个字段

PS:往下是拿idea项目写的,基本架构一样,变的只是实体类的名。

  Query from_studnet = session.createQuery("select sname from StudentEntity");

            List  list = from_studnet.list();
            for (int i = 0; i <list.size() ; i++) {
                String str=(String) list.get(i);
                System.out.println(str);
            }
   

在这里插入图片描述

HQL: 查询多个字段
  Query from_studnet = session.createQuery("select sname ,sage from StudentEntity ");
            List  list = from_studnet.list();
            for (int i = 0; i <list.size() ; i++) {
                Object[] obj= (Object[]) list.get(i);
                System.out.println(obj[0]);
                System.out.println(obj[1]);
            }

在这里插入图片描述

HQL:把查询出来的字段new成对象
  • 构造器赋值
  • 实体类添加对象的构造器即可
  Query from_studnet = session.createQuery("select new bj.ft.an.enity.StudentEntity(sname ,sage)  from StudentEntity ");
            List  list = from_studnet.list();
            for (int i = 0; i <list.size() ; i++) {
                StudentEntity student= (StudentEntity) list.get(i);
                System.out.println(student.getSname()+"======"+student.getSage());
            }

在这里插入图片描述

HQL:把查询出来的字段new成Map
   Query from_studnet = session.createQuery("select new Map(sname as sname  ,sage as sage )  from StudentEntity ");
            List  list = from_studnet.list();
            for (int i = 0; i <list.size() ; i++) {
                Map map= (Map) list.get(i);
                System.out.println(map.get("sname")+"======"+map.get("sage"));
            }

在这里插入图片描述

HQL:聚合操作
  • 聚合函数太多了,自己试试
    Query from_studnet = session.createQuery("select sum(sage)  from StudentEntity ");
            List  list = from_studnet.list();
                System.out.println(Integer.parseInt(list.get(0) + ""));

在这里插入图片描述

HQL:条件查询(where)

  • ?进行站位
 Query from_studnet = session.createQuery("   from StudentEntity where sid=? ");
            from_studnet.setString(0,"01");

            List<StudentEntity>  list = from_studnet.list();

            for (StudentEntity student : list) {
                System.out.println(student.getSname());
            }

在这里插入图片描述

HQL:条件查询 :站位
  • :任意参数进行站位(第二种方式)
  Query from_studnet = session.createQuery("   from StudentEntity where sid=:no ");
            from_studnet.setString("no","01");

            List<StudentEntity>  list = from_studnet.list();

            for (StudentEntity student : list) {
                System.out.println(student.getSname());
            }

在这里插入图片描述

HQL:分页
   Query from_studnet = session.createQuery("   from StudentEntity  ");
            from_studnet.setFetchSize(0);
            from_studnet.setMaxResults(3);
            List<StudentEntity>  list = from_studnet.list();

            for (StudentEntity student : list) {
                System.out.println(student.getSname());
            }
HQL:使用外键作为条件查询
 Query from_studnet = session.createQuery("   from StudentEntity where classesByCsid.cid='001'  ");
            List<StudentEntity>  list = from_studnet.list();

            for (StudentEntity student : list) {
                System.out.println(student.getSname());
            }

在这里插入图片描述

HQL:不等于判断<>
  Query from_studnet = session.createQuery("   from StudentEntity where classesByCsid.cid <>  '2' ");

            List<StudentEntity>  list = from_studnet.list();

            for (StudentEntity student : list) {
                System.out.println(student.getSname());
            }

在这里插入图片描述

HQL 剩余语法

-in

  • isnull
  • not in
  • betwween … and…
  • is empty
  • like
    等等,自己去试试

            Query from_studnet = session.createQuery("   from StudentEntity where classesByCsid.cid in(  '002','006') ");

            List<StudentEntity>  list = from_studnet.list();

            for (StudentEntity student : list) {
                System.out.println(student.getSname());
            }

在这里插入图片描述

HQL:update
         Query query;
            query=session.createQuery("update StudentEntity set sname=? where  sid=? ");
            query.setString(0, "先锋");
            query.setString(1,"bedaf367-ce4e-4357-8c71-830da528692e");
            query.executeUpdate();

在这里插入图片描述

HQL:delete
Query query;
            query=session.createQuery("delete StudentEntity  where  sid=? ");
            query.setString(0,"bedaf367-ce4e-4357-8c71-830da528692e");
            query.executeUpdate();

在这里插入图片描述

SQL


            String sqlString = "select s.* from student s ";
            //以SQL语句创建SQLQuery对象
            List <StudentEntity>list = session.createSQLQuery(sqlString)
                    //将查询到的记录与特定实体关联起来
                    .addEntity("s" , StudentEntity.class)
                    //返回全部的记录集
                    .list () ;

            for (StudentEntity student : list) {
                System.out.println(student.getSname());
            }

在这里插入图片描述

四:Hibernate对象的三种状态

  • 三种状态
    1.游离态:该对象没有在session对象中(不在session对象的管理范围内),数据库有与之对应的数据
    2.自由态:该对象没有在session对象中(不在session对象的管理范围内), 数据库也没有与之对应的数据
    3.持久态:该对象在session对象中(在session对象的管理范围内), 数据库有与之对应的数据 持久态的数据,对象与数据库的数据保持一致,不一致时,会同步更新数据库中的数据
//创建学生对象
Student student=new Student("哈哈哈哈", "男", 20, new Date());
//新增到数据库中  --------这个时候是持久态
session.save(student);
//将对象 踢出session对象中-----------这个时候是持久态转游离态
session.evict(student);

  • 自由态:
//这里是自由态--数据库没有与之对应的数据
Student student=new Student();
student.setAge(20);//数据库有与之对应的数据,都是没有在session对象中
session.save(student);//新增到数据库 保存到session对象中

  • 持久态
Student student=session.get(Student.class, 1);//持久态
student.setName("嘻嘻嘻2222");//设置改变了值,然后如果数据库没有与之对应的值,会强制执行修改操作
//如果踢出 ,那就是游离态,游离态的属性没有同步更新就需要在后面加上一个session.update(student);
session.evict(student);

五:Hibernate主键生成策略

  • 如果没有就改造一下,这个是默认的,就是自己生成主键(指定)
    在这里插入图片描述
    主键生成策略是指数据库表中主键的生成方式:本质上就是xx.hbm.xml中该 的配置

1、 native int
对于 oracle 采用 Sequence 方式,对于MySQL 和 SQL Server 采用identity(自增主键生成机制),native就是将主键的生成工作交由数据库完成,hibernate不管(很常用)
2、assigned
在插入数据的时候主键由用户自己添加,hibernate也不管(很常用)
3、increment int
插入数据的时候hibernate会给主键添加一个自增的主键,但是一个hibernate实例就维护一个计数器,所以在多个实例运行的时候不能使用这个方法
4、sequence int
调用数据库的sequence来生成主键,要设定序列名,不然hibernate无法找到:
NAME_SEQ(Oracle中很常用)
5、identity int
使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)
6、hilo
使用hilo生成策略,要在数据库中建立一张额外的表,默认表名为hibernate_unique_key,默认字段为integer类型,名称是next_hi(比较少用)
我们也可以自己设置自定义的表名和字段名

<id name="id" type="integer">
   <column name="id"/>
   <generator class="hilo">
      <param name="my_unique_key"/>
      <param column="next_hi"/>
   </generator>
</id> 

7、sehilo
通过hilo算法实现,但是主键历史保存在Sequence中,适用于支持 Sequence 的数据库,如 Oracle(比较少用)
8、uuid.hex string
hibernate会算出一个128位的唯一值插入
9、uuid.string string
hibernate会算出一个16位的值插入
10、foreign
使用外部表的字段作为主键
11、select
使用触发器生成主键(主要用于早期的数据库主键生成机制,少用)

  • 改造一下,使用的uuid策略
    在这里插入图片描述
    在这里插入图片描述
  • 策略成功

六:Hibernate配置文件详讲

在这里插入图片描述

  • 其他方言

  • 在这里插入图片描述

  • Hibernate 的其他属性配置

1、Hibernate JDBC属性
属性名 用途
hibernate.connection.driver_class jdbc驱动类
hibernate.connection.url jdbc URL
hibernate.connection.username 数据库用户
hibernate.connection.password 数据库用户密码
hibernate.connection.pool_size 连接池容量上限数目
注:使用C3P0的properties样例代码:
hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
2、Hibernate的数据源属性
属性名 用途
hibernate.connection.datasource 数据源JNDI名字
hibernate.jndi.url JNDI提供者的URL (可选)
hibernate.jndi.class JNDI InitialContextFactory类 (可选)
hibernate.connection.username 数据库用户 (可选)
hibernate.connection.password 数据库用户密码 (可选)
注:应用程序服务器JNDI数据源的hibernate.properties样例代码:
hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class =
org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class =
org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
3、Hibernate配置属性(可选)
属性名 用途
hibernate.dialect 一个Hibernate Dialect类名允许Hibernate针对特定的关系数据库生成优化的SQL.
取值full.classname.of.Dialect

hibernate.show_sql 输出所有SQL语句到控制台.
取值true | false

hibernate.format_sql 在log和console中打印出更漂亮的sql.
取值true | false

hibernate.default_schema 在生成的SQL中, 将给定的schema/tablespace附加于非全限定名的表名上.
取值SCHEMA_NAME

hibernate.default_catalog 在生成的SQL中, 将给定的catalog附加于没全限定名的表名上.
取值CATALOG_NAME

hibernate.session_factory_name SessionFactory创建后,将自动使用这个名字绑定到JNDI中.
取值jndi/composite/name

hibernate.max_fetch_depth 为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度. 值为0意味着将关闭默认的外连接抓取.
取值 建议在0到3之间取值

hibernate.default_batch_fetch_size 为Hibernate关联的批量抓取设置默认数量.
取值 建议的取值为4, 8, 和16

hibernate.default_entity_mode 为由这个SessionFactory打开的所有Session指定默认的实体表现模式.
取值dynamic-map, dom4j, pojo

hibernate.order_updates 强制Hibernate按照被更新数据的主键,为SQL更新排序。这么做将减少在高并发系统中事务的死锁。
取值true | false

hibernate.generate_statistics 如果开启, Hibernate将收集有助于性能调节的统计数据.
取值true | false

hibernate.use_identifer_rollback 如果开启, 在对象被删除时生成的标识属性将被重设为默认值.
取值true | false

hibernate.use_sql_comments 如果开启, Hibernate将在SQL中生成有助于调试的注释信息, 默认值为false.
取值true | false

4、Hibernate JDBC和连接(connection)属性
属性名 用途
hibernate.jdbc.fetch_size 非零值,指定JDBC抓取数量的大小 (调用Statement.setFetchSize()).
hibernate.jdbc.batch_size 非零值,允许Hibernate使用JDBC2的批量更新.
取值 建议取5到30之间的值

hibernate.jdbc.batch_versioned_data 如果你想让你的JDBC驱动从executeBatch()返回正确的行计数 , 那么将此属性设为true(开启这个选项通常是安全的). 同时,Hibernate将为自动版本化的数据使用批量DML. 默认值为false.
eg.true | false

hibernate.jdbc.factory_class 选择一个自定义的Batcher. 多数应用程序不需要这个配置属性.
eg.classname.of.Batcher

hibernate.jdbc.use_scrollable_resultset 允许Hibernate使用JDBC2的可滚动结果集. 只有在使用用户提供的JDBC连接时,这个选项才是必要的, 否则Hibernate会使用连接的元数据.
取值true | false

hibernate.jdbc.use_streams_for_binary 在JDBC读写binary (二进制)或serializable (可序列化) 的类型时使用流(stream)(系统级属性).
取值true | false

hibernate.jdbc.use_get_generated_keys 在数据插入数据库之后,允许使用JDBC3 PreparedStatement.getGeneratedKeys() 来获取数据库生成的key(键)。需要JDBC3+驱动和JRE1.4+, 如果你的数据库驱动在使用Hibernate的标 识生成器时遇到问题,请将此值设为false. 默认情况下将使用连接的元数据来判定驱动的能力.
取值true|false

hibernate.connection.provider_class 自定义ConnectionProvider的类名, 此类用来向Hibernate提供JDBC连接.
取值classname.of.ConnectionProvider

hibernate.connection.isolation 设置JDBC事务隔离级别. 查看java.sql.Connection来了解各个值的具体意义, 但请注意多数数据库都不支持所有的隔离级别.
取值1, 2, 4, 8

hibernate.connection.autocommit 允许被缓存的JDBC连接开启自动提交(autocommit) (不建议).
取值true | false

hibernate.connection.release_mode 指定Hibernate在何时释放JDBC连接. 默认情况下,直到Session被显式关闭或被断开连接时,才会释放JDBC连接. 对于应用程序服务器的JTA数据源, 你应当使用after_statement, 这样在每次JDBC调用后,都会主动的释放连接. 对于非JTA的连接, 使用after_transaction在每个事务结束时释放连接是合理的. auto将为JTA和CMT事务策略选择after_statement, 为JDBC事务策略选择after_transaction.
取值on_close | after_transaction | after_statement | auto

hibernate.connection. 将JDBC属性propertyName传递到DriverManager.getConnection()中去.
hibernate.jndi. 将属性propertyName传递到JNDI InitialContextFactory中去.
5、Hibernate缓存属性
属性名 用途
hibernate.cache.provider_class 自定义的CacheProvider的类名.
取值classname.of.CacheProvider

hibernate.cache.use_minimal_puts 以频繁的读操作为代价, 优化二级缓存来最小化写操作. 在Hibernate3中,这个设置对的集群缓存非常有用, 对集群缓存的实现而言,默认是开启的.
取值true|false

hibernate.cache.use_query_cache 允许查询缓存, 个别查询仍然需要被设置为可缓存的.
取值true|false

hibernate.cache.use_second_level_cache 能用来完全禁止使用二级缓存. 对那些在类的映射定义中指定的类,会默认开启二级缓存.
取值true|false

hibernate.cache.query_cache_factory 自定义的实现QueryCache接口的类名, 默认为内建的StandardQueryCache.
取值classname.of.QueryCache

hibernate.cache.region_prefix 二级缓存区域名的前缀.
取值prefix

hibernate.cache.use_structured_entries 强制Hibernate以更人性化的格式将数据存入二级缓存.
取值true|false

6、Hibernate事务属性
属性名 用途
hibernate.transaction.factory_class 一个TransactionFactory的类名, 用于Hibernate Transaction API (默认为JDBCTransactionFactory).
取值classname.of.TransactionFactory

jta.UserTransaction 一个JNDI名字,被JTATransactionFactory用来从应用服务器获取JTA UserTransaction.
取值jndi/composite/name

hibernate.transaction.manager_lookup_class 一个TransactionManagerLookup的类名 - 当使用JVM级缓存,或在JTA环境中使用hilo生成器的时候需要该类.
取值classname.of.TransactionManagerLookup

hibernate.transaction.flush_before_completion 如果开启, session在事务完成后将被自动清洗(flush). (在Hibernate和CMT一起使用时很有用.)
取值true | false

hibernate.transaction.auto_close_session 如果开启, session在事务完成前将被自动关闭. (在Hibernate和CMT一起使用时很有用.)
取值true | false

7、其他属性
属性名 用途
hibernate.query.factory_class 选择HQL解析器的实现.
取值org.hibernate.hql.ast.ASTQueryTranslatorFactory or org.hibernate.hql.classic.ClassicQueryTranslatorFactory

hibernate.query.substitutions 将Hibernate查询中的符号映射到SQL查询中的符号 (符号可能是函数名或常量名字).
取值hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC

hibernate.hbm2ddl.auto 在SessionFactory创建时,自动将数据库schema的DDL导出到数据库. 使用 create-drop时,在显式关闭SessionFactory时,将drop掉数据库schema.
取值update | create | create-drop

hibernate.cglib.use_reflection_optimizer 开启CGLIB来替代运行时反射机制(系统级属性). 反射机制有时在除错时比较有用. 注意即使关闭这个优化, Hibernate还是需要CGLIB. 你不能在hibernate.cfg.xml中设置此属性.
取值true | false

8、Hibernate日志类别
类别 功能
org.hibernate.SQL 在所有SQL DML语句被执行时为它们记录日志
org.hibernate.type 为所有JDBC参数记录日志
org.hibernate.tool.hbm2ddl 在所有SQL DDL语句执行时为它们记录日志
org.hibernate.pretty 在session清洗(flush)时,为所有与其关联的实体(最多20个)的状态记录日志
org.hibernate.cache 为所有二级缓存的活动记录日志
org.hibernate.transaction 为事务相关的活动记录日志
org.hibernate.jdbc 为所有JDBC资源的获取记录日志
org.hibernate.hql.ast 为HQL和SQL的自动状态转换和其他关于查询解析的信息记录日志
org.hibernate.secure 为JAAS认证请求做日志
org.hibernate 为任何Hibernate相关信息做日志 (信息量较大, 但对查错非常有帮助)

七:Hibernate的缓存章节(重要)

八:Hibernate的延迟加载

何为延迟加载:用到的时候在加载,用不到不加载
我们查询的是Student表,没有用到延迟加载,所有只有一行sql语句,
为何会这么说,因为我们的student是一张有外键的表。理论上说查询的时候应该把Student对应的数据(Classes)的数据页查出来,但是我们既然不用,查出来不是浪费了么,所以默认的就是开启了延迟加载
在这里插入图片描述

  • 在Studnet里面配置关闭延迟加载
    在这里插入图片描述
    在这里插入图片描述
  • 在查询就会连classes的数据也会查出来,查出来我们并不用,就是一种资源浪费,所以就用默认的就行

九:Hibernate的级联删除

  • 我们在创建表关系的时候,一个教室对应多个学生,我们将教室删除之前必须把学生删除,
  • 如果我们只把教室删除了不把学生删除了就会出错
    在这里插入图片描述
    我们设置一下级联删除
  • cascade=“all”
    在这里插入图片描述
  • 在classes的映射文件设置级联删除,我们删除教室会将所有的学生一起删除

在这里插入图片描述

十:抓取策略

  • 稍微带过一下
  • fetch=“join”
  • 默认是select ,用不到不会加载,etch=“join” 直接将2张表一起查询
    在这里插入图片描述

十一:Hibernate的锁机制

直达链接

十二:Hibernate缓存(EhCache)

直达链接

十三:Hibernate数据库连接池(C3p0)

直达链接

十四:Springboot整合Hibernate(原生非JPA)

直达链接

十五:JPA

直达链接

十六: SpringData(jpa-Springboot篇)+SpringBoot整Mybatis+MyBatisPlus+druid

直达链接

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值