zoukankan      html  css  js  c++  java
  • hibernate快速入门示例

    hibernate概述

    hibernate是一个java的全自动ORM框架,它可以自动生成SQL语句、自动建表、自动执行,使用者可以不使用SQL完成数据的CRUD操作,同时它也是基于JPA规则的一种实现方式

    建库建表

    在mysql数据库中创建测试库和表

    -- 建库
    CREATE DATABASE `hibernate-test`;
    
    -- 建表
    CREATE TABLE `hibernate-test`.`h_user`  (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      `password` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    -- 插入数据
    INSERT INTO h_user ( username, PASSWORD )
    VALUES
    	( 'zhangsan', '123' );
    INSERT INTO h_user ( username, PASSWORD )
    VALUES
    	( 'lisi', '321' );
    

    创建项目

    本实例全程使用idea进行,并使用maven导入依赖jar包

    导入依赖

    在maven的pom文件中加入hibernate的核心依赖包,为了方便使用模型,这里我还导入了lombok包,用于简写getter、setter等实体类方法

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.18.Final</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
    </dependencies>
    

    编写映射数据库的对象模型实体

    @Data
    public class User {
        private Integer id;
        private String username;
        private String password;
    }
    

    创建hibernate配置文件

    核心配置文件

    hibernate核心配置文件默认命名为hibernate.cfg.xml, 文件的默认路径是在类目录下,这里我放在resources文件夹下

    .cfg : configuration

    <?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>
            <!-- 数据库连接基本配置信息 必填-->
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate-test?serverTimezone=GMT%2B8</property>
            <!-- 数据库方言:指定使用的数据库种类 -->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
            <!-- 是否显示sql代码,用于在控制台输出执行的SQL语句 可选-->
            <property name="hibernate.show_sql">true</property>
    <!--        格式化SQL,美化SQL语句输出 可选-->
            <property name="hibernate.format_sql">true</property>
    <!--        自动生成表策略
                update: 若存在表则不生成表
                create: 不管存在不存在都重新创建
    -->
            <property name="hibernate.hbm2ddl.auto">update</property>
    <!--        指定映射配置文件的位置-->
            <mapping resource="com/welisit/hibernate/demo/model/User.hbm.xml" />
        </session-factory>
    </hibernate-configuration>
    

    对象关系映射配置文件

    映射配置文件默认命名使用[实体类名].hbm.xml,文件的默认路径放在与实体类的同个目录下,这里我的映射配置文件名为User.hbm.xml

    .hbm: hibernate mapper

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <!-- 配置表与实体对象的关系 -->
    <hibernate-mapping>
    <!--   name: 实体类的全类名
           table: 表名
    -->
        <class name="com.welisit.hibernate.demo.model.User" table="h_user">
            <id name="id" column="id">
    <!--            主键生成方式
            native:使用数据库设置的主键生成方式
    -->
                <generator class="native"/>
            </id>
            <property name="username" column="username"/>
            <property name="password" column="password"/>
        </class>
    </hibernate-mapping>
    

    测试

    增加记录

    public void testInsert() {
            // 创建hibernate核心配置文件对象
            Configuration configuration = new Configuration();
            Configuration configure = configuration.configure();
            // 创建能够构建session的sessionfactory
            SessionFactory sessionFactory = configure.buildSessionFactory();
            // 一个session相当于一个连接, 通过session对象开启事务
            Session session = sessionFactory.openSession();
            Transaction transaction = session.beginTransaction();
            // 创建映射对象模型
            User user = new User();
            user.setPassword("312");
            user.setUsername("aaa");
            // 保存对象
            session.save(user);
            // 提交事务
            transaction.commit();
            // 关闭会话
            session.close();
            // 关闭session工厂
            sessionFactory.close();
        }
    

    运行上面的代码我们发现有报错,内容大概是mapping映射文件找不到

    image-20200628203555298

    // 报错信息
    org.hibernate.boot.MappingNotFoundException: Mapping (RESOURCE) not found : com/welisit/hibernate/demo/model/User.hbm.xml : origin(
        ...
    

    通过查看编译输出文件发现原来在java文件夹中的没有User.hbm.xml,因为maven项目中,默认java目录中除了生成编译后的.class文件是不会生成其他类型的文件的。

    image-20200628205141720

    解决方法:

    方式一:直接将User.hbm.xml文件复制到输出文件目录中即可

    方式二:修改maven的pom文件中的编译打包配置

    <!-- 项目打包时会将java目录中的*.xml文件也进行打包 -->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
    

    通过查看configure方法源码,可以看出默认hibernate核心配置文件名就是hibernate.cfg.xml

    image-20200628195125305

    删除、修改

    修改和删除需要开启事务才能进行

    public void testUpdate() {
        Session session = sessionFactory.openSession();
        // 获取修改的对象
        User user = session.get(User.class, 1);
        // 修改对象值
        user.setUsername("abc");
        // 更新需要开启事务
        Transaction transaction = session.beginTransaction();
        session.update(user);
        transaction.commit();
    }
    
    public void testRemove() {
        Session session = sessionFactory.openSession();
        // 获取修改的对象
        User user = session.get(User.class, 1);
        Transaction transaction = session.beginTransaction();
        // 删除对象值
        session.remove(user);
        transaction.commit();
    }
    

    查询

    通过主键查询

    hibernate原生的session对象提供了通过对象主键查询的方法

    • get(javaBean.class, int id); 通过传入的id进行查询
    • load(javaBean.class, int id); 同上,但这是懒加载
    @Test
    public void queryById() {
        Session session = sessionFactory.openSession();
        User user = session.load(User.class, 2);
        System.out.println("懒加载执行完毕...");
        System.out.println(user);
    }
    

    输出结果

    image-20200630134529067

    HQL查询

    简介

    HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法,它是对查询条件进行了面向对象封装。

    示例

    @Test
    public void testHQL() {
        // 使用hql语句查询
        Session session = sessionFactory.openSession();
        // User类名在映射配置文件的hibernate-mapping标签配置了报名就可以在此不加包名 
        // ?1 指定占位符的索引数为1
        String hql = "from User where username = ?1";
        // 参数也可以使用指定名称
        // String hql2 = "from User where username = :name"
        Query<User> query = session.createQuery(hql, User.class);
        query.setParameter(1, "aaa");
        // query.setParameter("name", "aaa");
        // 获取单个返回结果值
        User user = query.getSingleResult();
        System.out.println(user);
    }
    
    @Test
    public void testHQL2() {
        // 使用hql语句查询
        Session session = sessionFactory.openSession();
        // User类名在映射配置文件的hibernate-mapping标签配置了报名就可以在此不加包名
        // ?1 指定占位符的索引数为1
        String hql1 = "from User where username = ?1";
        Query<User> query = session.createQuery(hql1, User.class);
        query.setParameter(1, "aaa");
        // 查询结果为多个值时使用getSingleResult会怎样? 会报错:
        // javax.persistence.NonUniqueResultException: query did not return a unique result: 2
        // getSingleResult实际调用的就是this.uniqueResult()
        User user = query.getSingleResult();
        System.out.println(user);
    }
    

    分页查询示例

    @Test
    public void testHQLPage() {
        // 使用hql语句分页查询
        Session session = sessionFactory.openSession();
        String hql = "from User";
        Query<User> query = session.createQuery(hql, User.class);
        query.setFirstResult(0); // 从第几条开始查询
        query.setMaxResults(2); // 每次查询显示几条
        List<User> userList = query.list();
        userList.forEach(System.out::println);
    }
    

    输出结果:

    image-20200630142714388

    SQL查询

    hibernate也支持原生SQL来进行查询

    示例

    @Test
    public void testSQLQuery() {
        // 原生SQL查询
        Session session = sessionFactory.openSession();
        String sql = "select * from h_user";
        // 创建sql查询对象
        NativeQuery sqlQuery = session.createSQLQuery(sql);
        // 指定结果集封装到哪个对象
        sqlQuery.addEntity(User.class);
        List list = sqlQuery.list();
        list.forEach(System.out::println);
    }
    

    QBC查询

    曾经我一直幻想着什么时候可以不使用SQL就能对数据库进行增删改查操作,这样就能少学一点东西了。现在QBC出现了,就是和我幻想的一样,不需要写一条语句就能对数据库完成各种CRUD操作,方便省事、节省写sql时间,让更多时间用在业务的逻辑开发中而不是这种简单的CRUD代码中。

    QBC: query by Criteria 【Criteria】条件、标准

    使用步骤

    QBC查询是通过创建查询对象对数据对象进行操作,首先第一步就是创建查询对象

    Criteria criteria = session.createCriteria(User.class)
    

    使用Restrictions构建条件,通过查询对象设置查询条件,最后得出结果

    @Test
    public void testQBCQuery() {
        // QBC查询
        Session session = sessionFactory.openSession();
        Criteria criteria = session.createCriteria(User.class);
        criteria.add(Restrictions.eq("username", "aaa"));
        Object o = criteria.uniqueResult();
        System.out.println(o);
    }
    

    聚合查询

    @Test
    public void testQBCQuery2() {
        // QBC聚合查询
        Session session = sessionFactory.openSession();
        Criteria criteria = session.createCriteria(User.class);
        criteria.setProjection(Projections.count("id"));
        Object o = criteria.uniqueResult();
        System.out.println(o);
    }
    

    hibernate映射文件详解

    hibernate-mapping

    <!-- 配置表和实体类的映射关系 -->
    <hibernate-mapping package="映射类所在的包">
    

    package属性: 指定实体类所在的包,凡是需要填写包名的地方,使用这个之后,都可以省略,只写类名

    class

    配置数据库表与类的对应的关系

    <class name="com.welisit.hibernate.demo.model.User" table="h_user">
    
    • name: 完整类名
    • table: 数据库表名

    class 标签内部包含两部分:idproperty

    id

    配置主键映射的属性

    • name:填写主键对应属性名

    • column:填写表中主键列名

    • type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.

    ​ 每个类型有三种填法: java类型|hibernate类型|数据库类型

    • not-null(可选):配置该属性(列)是否不能为空. 默认值:false

    • length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度

    id标签内部包含 generator标签

    generator

    组件生成策略

    <generator class="native"/>
    

    class属性的几个可选值

    • identity: 由数据库来维护,hiibernate不负责

    • increment: 每次插入前,先获取数据表中最大值,然后+1

    • sequence: 用数据库提供的sequence机制生成主键,需要数据库支持sequence,mysql不支持

    • hilo: 通过高低位算法实现

      hilo(高低位方式high low)是hibernate中最常用的一种生成方式,需要一张额外的表保存hi的值。保存hi值的表至少有一条记录(只与第一条记录有关),否则会出现错误。可以跨数据库。

    • native: 使用数据库原生设定的生成策略

    • UUID:使用uuid算法生成的id,但是需要注意主键必须是String

    • assigned: 由程序员自己决定,在保存时指定id进行保存

    property

    除id之外的普通属性映射

    属性配置参数与id标签相同

    总结

    hibernate虽然现在新项目用得不多,但是不可否则它曾经在ORM框架中的地位,同时它也是学习spring data jpa的基础,hibernate仍是一个优秀的ORM框架

  • 相关阅读:
    玩转Web之easyui(一)-----easy ui datagird 分页
    【JavaEE基础】在Java中如何使用jdbc连接Sql2008数据库
    Android访问服务器(TOMCAT)乱码引发的问题
    工厂方法模式--结合具体例子学习工厂方法模式
    FatMouse' Trade
    简单工厂模式--结合实例学习简单工厂模式
    栈-----括号匹配+表达式计算
    Android控件之RadioGroup与RadioButton(单选控件)
    Android控件之CheckBox(复选框控件)
    Android控件之ToggleButton(多状态按钮)
  • 原文地址:https://www.cnblogs.com/welisit/p/13221464.html
Copyright © 2011-2022 走看看