hibernate框架学习及其与mybatis的关联

目录

一、什么是hibernate

二、编写一个hibernate的maven项目

三、hibernate和mybatis的对比

四、hibernate的creteria和mybatis的example.creteria


Gitee仓库:https://gitee.com/inandout/hibernate---nange/tree/dev/

一、什么是hibernate

百度百科

hibernate框架学习及其与mybatis的关联_第1张图片

Hibernate官网

Mybatis官网

1、什么是ORM?

        使用传统的JDBC开发应用系统时,如果是小型应用系统,并不觉得有什么麻烦,但是对于大型应用系统的开发,使用JDBC就会显得力不从心。例如对几十、几百张包含几十个字段的表进行插入操作时,编写的SQL语句不但很长,而且繁琐,容易出错;在读取数据时,需要写多条getXxx语句从结果集中取出各个字段的信息,不但枯燥重复,并且工作量非常大。为了提高数据访问层的编程效率,Gavin King开发出了一个当今最流行的的ORM框架,它就是Hibernate框架。
        所谓的ORM就是利用描述对象和数据库表之间映射的元数据,自动把Java应用程序中的对象,持久化到关系型数据库的表中。通过操作Java对象,就可以完成对数据库表的操作。可以把ORM理解为关系型数据和对象的一个纽带,开发人员只需要关注纽带一端映射的对象即可。ORM原理如下图所示。

hibernate框架学习及其与mybatis的关联_第2张图片

        说那么多,无非就是想说说ORM是个什么东西,对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),指的是将一个Java中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可以操作数据库中的表。

2、为什么要学习Hibernate框架?

与其它操作数据库的技术相比,Hibernate具有以下几点优势:

  • Hibernate对JDBC访问数据库的代码做了轻量级封装,大大简化了数据访问层繁琐的重复性代码,并且减少了内存消耗,加快了运行效率;
  • Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了DAO(Data Access Object,数据访问对象)层编码工作;
  • Hibernate的性能非常好,映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系;
  • 可扩展性强,由于源代码的开源以及API的开放,当本身功能不够用时,可以自行编码进行扩展。
     

总结:Hibernate是企业级开发中的主流框架,映射的灵活性很出色,并且它支持很多关系型数据库。

3、hibernate执行原理

hibernate框架学习及其与mybatis的关联_第3张图片

二、编写一个hibernate的maven项目

这个课程是我自己找的学习的,这个项目都是跟着他做的

课程地址:1、Hibernate快速入门-1_哔哩哔哩_bilibili

1、配置hibernate,数据库和实体类关联,插入一条数据

项目结构

hibernate框架学习及其与mybatis的关联_第4张图片

导入依赖


        
        
            mysql
            mysql-connector-java
            5.1.47
        

        
        
            org.hibernate
            hibernate-core
            5.4.10.Final
        

        
            org.projectlombok
            lombok
            1.18.18
        
    

    
        
            
                src/main/java
                
                    **/*.xml
                
            
            
                src/main/resources
                
                    **/*.xml
                
            
        
    

编写hibernate配置文件 hibernate.cfg.xml





    
        
        root
        
        com.mysql.jdbc.Driver
        jdbc:mysql://localhost:3306/hibernate?useSSL=false&useUnicode=true&characterEncoding=UTF-8
        

        
        10
        10000
        5000
        30
        5
        10

        
        org.hibernate.dialect.MySQLDialect

        
        true

        
        true

        
        

        
        

        
        

        
        
    

编写实体类

@Data
public class People {
    private int id;
    private String name;
    private Double money;
}

编写实体类映射文件 People.hbm.xml


    
        
            
            
        
        
            
        
        
            
        
    

编写测试方法

public class test1 {
    public static void main(String[] args) {
        //创建Configuration
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        People people = new People();
        people.setId(1);
        people.setName("张三");
        people.setMoney(1000.0);
        session.save(people);
        session.beginTransaction().commit();
        session.close();
    }
}

启动项目测试

hibernate框架学习及其与mybatis的关联_第5张图片

2、一对多

客户和订单:每个客户可以购买多个产品,⽣成多个订单,但是⼀个订单只能属于⼀个客户,所以客户
是⼀,订单是多。

hibernate框架学习及其与mybatis的关联_第6张图片

新建实体类 Customer.java

@Data
public class Customer {
    private int id;
    private String name;
    private Set ordersSet;

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

Orders.java

@Data
public class Orders {
    private int id;
    private String name;
    private Customer customer;
}

编写实体类映射文件 Customer.hbm.xml




    
        
            
            
        
        
            
        
        
        
            
            
        

    

Orders.hbm.xml




    
        
            
            
        
        
            
        
        
        

    

编写测试方法

/**
 * 基础的一对多
 */
public class test2 {
    public static void main(String[] args) {
        // 创建Configuration
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        // 获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        // 获取Session
        Session session = sessionFactory.openSession();
        // 创建 Customer
        Customer customer = new Customer();
        customer.setName("张三");
        // 创建 Orders
        Orders orders = new Orders();
        orders.setName("订单1");
        // 建⽴关联关系
        orders.setCustomer(customer);
        // 保存
        session.save(customer);
        session.save(orders);
        // 提交事务
        session.beginTransaction().commit();
        session.close();
    }
}

启动项目测试

hibernate框架学习及其与mybatis的关联_第7张图片

3、多对多

学⽣选课:⼀⻔课程可以被多个学⽣选择,⼀个学⽣可以选择多⻔课程,学⽣是多,课程也是多。
数据库中是通过两个⼀对多关系来维护的,学⽣和课程都是主表,额外增加⼀张中间表作为从表,两张
主表和中间表都是⼀对多关系。

hibernate框架学习及其与mybatis的关联_第8张图片

新建实体类 Account.java

@Getter
@Setter
@ToString
public class Account {
    private int id;
    private String name;
    private int age;
    private Set courseSet;
}

Course.java

@Getter
@Setter
public class Course {
    private int id;
    private String name;
    private Set accountSet;

    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

编写实体类映射文件 Account.hbm.xml




    
        
            
            
        
        
            
        
        
            
        

        
            
            
        

    

Course.hbm.xml




    
        
            
            
        
        
            
        

        
            
            
        

    

编写测试方法 查询

/**
 * 级联查询
 */
public class test6 {
    public static void main(String[] args) {
        //创建Configuration
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        // 条件查询
        Course course = session.get(Course.class, 1);
        System.out.println(course);
        System.out.println(course.getAccountSet());

        Account account = session.get(Account.class, 1);
        System.out.println(account);

        session.close();
    }
}

新增

/**
 * 级联新增
 */
public class test7 {
    public static void main(String[] args) {
        //创建Configuration
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        //获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取Session
        Session session = sessionFactory.openSession();

        Course course = new Course();
        course.setName("java");

        Account account = new Account();
        account.setName("jilian");

        Set courses = new HashSet<>();
        courses.add(course);
        account.setCourseSet(courses);

        session.save(course);
        session.save(account);

        session.beginTransaction().commit();
        session.close();
    }
}

启动项目测试

hibernate框架学习及其与mybatis的关联_第9张图片

4、HQL查询

HQL:Hibernate Query Language,是 Hibernate 框架提供的⼀种查询机制,它和 SQL 类似,不同的是 HQL 是⾯向对象的查询语句,让开发者能够以⾯向对象的思想来编写查询语句,对 Java 编程是⼀种友好的⽅式。

HQL 不能直接参与数据库的交互,是中间层语⾔。

Java ---》HQL ---〉Hibernate ---》SQL ---〉DB

HQL 只能完成查询、修改、删除,新增是⽆法操作的。

HQL 进⾏查询,from 关键字后⾯不能写表名,必须写表对应的实体类名。

① 列表查询

public class HQL1 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        //获取 SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取 Session
        Session session = sessionFactory.openSession();

        // 列表查询
        String hql = "from People";
        Query query = session.createQuery(hql);
        List list = query.list();
        for (People people : list) {
            System.out.println(people);
        }
        session.close();
    }
}

② 分页查询

public class HQL2 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取 SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取 Session
        Session session = sessionFactory.openSession();

        // 分页查询
        String hql = "from People";
        Query query = session.createQuery(hql);
        query.setFirstResult(1);
        query.setMaxResults(3);
        List list = query.list();
        for (People people : list) {
            System.out.println(people);
        }
        session.close();
    }
}

③ where条件查询 + 模糊查询 + 排序

public class HQL3 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取 SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取 Session
        Session session = sessionFactory.openSession();

        // where条件查询 + 模糊查询 + 排序
        String hql = "from People where id = 6 and name like '%三%' order by id asc";
        Query query = session.createQuery(hql);
        if (query.list() != null) {
            People people = (People) query.list().get(0);
            System.out.println(people);
        } else {
            System.out.println("查询结果为空");
        }
        session.close();
    }
}

④ Select条件选取

public class HQL4 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取 SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取 Session
        Session session = sessionFactory.openSession();

        // Select条件选取
        String hql = "select name from People where id = 6";
        Query query = session.createQuery(hql);
        String name = (String) query.uniqueResult();
        System.out.println(name);
        session.close();
    }
}

⑤ 占位符

public class HQL5 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取 SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取 Session
        Session session = sessionFactory.openSession();

        // 占位符
        String hql = "from People where name = :name";
        Query query = session.createQuery(hql);
        query.setString("name", "张三");
        List list = query.list();
        for (People people : list) {
            System.out.println(people);
        }
        session.close();
    }
}

⑥ 多对多级联查询

public class HQL6 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure();
        //获取 SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取 Session
        Session session = sessionFactory.openSession();

        // 级联查询
        String hql1 = "from Customer where name = :name";
        Query query1 = session.createQuery(hql1);
        query1.setString("name", "张三");
        Customer customer = (Customer) query1.uniqueResult();
        String hql2 = "from Orders where customer = :customer";
        Query query2 = session.createQuery(hql2);
        query2.setEntity("customer", customer);
        List list = query2.list();
        for (Orders orders : list) {
            System.out.println(orders);
        }
        session.close();
    }
}

三、hibernate和mybatis的对比

1、相同点

Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。

其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。Hibernate和MyBatis都支持JDBCJTA事务处理。

2、不同点

(1)hibernate是全自动,而mybatis是半自动

hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。

(2)hibernate数据库移植性远大于mybatis

hibernate通过它强大的映射结构和hql语言,大大降低了对象与数据库(Oracle、MySQL等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。

(3)hibernate拥有完整的日志系统,mybatis则欠缺一些

hibernate日志系统非常健全,涉及广泛,包括:sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多。

(4)mybatis相比hibernate需要关心很多细节

hibernate配置要比mybatis复杂的多,学习成本也比mybatis高。但也正因为mybatis使用简单,才导致它要比hibernate关心很多技术细节。mybatis由于不用考虑很多细节,开发模式上与传统jdbc区别很小,因此很容易上手并开发项目,但忽略细节会导致项目前期bug较多,因而开发出相对稳定的软件很慢,而开发出软件却很快。hibernate则正好与之相反。但是如果使用hibernate很熟练的话,实际上开发效率丝毫不差于甚至超越mybatis。

(5)sql直接优化上,mybatis要比hibernate方便很多

由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql;虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。总之写sql的灵活度上hibernate不及mybatis。

(6)缓存机制上,hibernate要比mybatis更好一些

MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。

而Hibernate对查询对象有着良好的管理机制,用户无需关心SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。

3、举个形象的比喻

MyBatis:机械工具,使用方便,拿来就用,但工作还是要自己来作,不过工具是活的,怎么使由我决定。(小巧、方便、高效、简单、直接、半自动)

Hibernate:智能机器人,但研发它(学习、熟练度)的成本很高,工作都可以摆脱他了,但仅限于它能做的事。(强大、方便、高效、复杂、绕弯子、全自动)

四、hibernate的creteria和mybatis的example.creteria

1、HQL和creteria的区别

① (Hibernate Query Language):面向对象的查询语言,与SQL不同,HQL中的对象名是区分大小写的(除了JAVA类属性其他部分不区分大小写);HQL中查的是对象而不是表,并且支持多态

② Criteria

是一种比HQL更面向对象的查询方式;Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口

Criterion:是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来添加查询条件。

Criterion 接口的主要实现包括: Example 、 Junction 和 SimpleExpression 。

Criterion 的实例可以通过 Restrictions 工具类来创建,Restrictions 提供了大量的静态方法,如 eq (等于)、 ge (大于等于)、 between 等来方法的创建 Criterion 查询条件(SimpleExpression 实例)。除此之外, Restrictions 还提供了方法来创建 conjunction 和disjunction 实例,通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合。

源码

hibernate框架学习及其与mybatis的关联_第10张图片

③ 编写列表查询方法

public class creteria1 {
    public static void main(String[] args) {
        //创建 Configuration
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        //获取 SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        //获取 Session
        Session session = sessionFactory.openSession();

        // 列表查询
        Criteria criteria = session.createCriteria(People.class);
        criteria.add(Restrictions.eq("name", "张三"));
        List list = criteria.list();
        for (People people : list) {
            System.out.println(people);
        }

        session.close();
    }
}

启动项目测试

hibernate框架学习及其与mybatis的关联_第11张图片

2、Mybatis的example.creteria

① 为什么要有Criteria

        Criteria英文是标准、条件和准则的意思

        在使用常规的mybatis时,我们经常碰到的问题就是条件式查询。在一个查询界面,查询条件较多,并且运算符并不总是 时,在后台就需要拼装 sql语句。这种处理方式肯定不是使用mybatis的初衷,对于使用了hibernate的我来说,如果mybatis也有一套criteria查询就好了。在具体实现中,我们只需要按照hibernate的处理方式定义好相应的criteria,最后传递给mybatis,其自身处理相应的条件和参数信息,最终返回相应的数据即可。

② 如何生成Example类?

mybatis的的配置文件可以使用mybatis-generator工具生成,它就可以帮我们生成example类。

generator依赖地址

mybatis-generator会为每个字段产生Criterion,为底层的mapper.xml创建动态sql。如果表的字段比较多,产生的example类会十分庞大。理论上通过example类可以构造你想到的任何筛选条件。

hibernate框架学习及其与mybatis的关联_第12张图片

③ 分析生成的Example中的元素

Criteria

Criteria包含一个Cretiron的集合,每一个Criteria对象内包含的Cretiron之间是由AND连接的,是逻辑与的关系。

Cretiron

各种sql的表达式方法,eq()、like()、between()、in()、lessThan()、isNull()

oredCriteria

Example内有一个成员叫oredCriteria,是Criteria的集合,就想其名字所预示的一样,这个集合中的Criteria是由OR连接的,是逻辑或关系。oredCriteria就是ORed Criteria。

其他

Example类的distinct字段用于指定DISTINCT查询。

orderByClause字段用于指定ORDER BY条件,这个条件没有构造方法,直接通过传递字符串值指定。

④ 编写测试方法

UserExample example = new UserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo("wyw");
criteria.andUsernameIsNull();
example.setOrderByClause("username asc,email desc");
Listlist = XxxMapper.selectByExample(example);

你可能感兴趣的:(hibernate,学习,mybatis)