Hibernate(1)

相信很多伙伴和我一样,之前接触的JDBC->mybatis。至于hibernate只知道它是全自动的,而mybatis是半自动的。比较熟悉的或者用的比较多的可能是SSM,而SSH则接触比较少。最近几天将重新较细致认识一下hibernate。Let’s go~~

一、hibernate和mybatis区别:

二、我的第一个hibernate-demo:

2.1 准备数据库文件:

2.2 导入相关依赖:

2.3 创建相关实体类:

2.4 配置hibernate.cfg.xml文件:

2.5 创建实体类映射:

2.6 测试:

2.7 测试中可能遇到的问题和解决措施:

一、hibernate和mybatis区别:

  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

二、我的第一个hibernate-demo:

2.1 准备数据库文件:

customer表&orders表 SQL语句
customer表orders表

/*
Navicat MySQL Data Transfer

Source Server         : MySQL
Source Server Version : 80026
Source Host           : localhost:3306
Source Database       : hibernate

Target Server Type    : MYSQL
Target Server Version : 80026
File Encoding         : 65001

Date: 2022-11-12 11:47:54
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `customer`
-- ----------------------------
DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='顾客表';

-- ----------------------------
-- Records of customer
-- ----------------------------
INSERT INTO `customer` VALUES ('10', '张三');
INSERT INTO `customer` VALUES ('11', '李四');
INSERT INTO `customer` VALUES ('12', '王五');
INSERT INTO `customer` VALUES ('13', '马六');
 

/*
Navicat MySQL Data Transfer

Source Server         : MySQL
Source Server Version : 80026
Source Host           : localhost:3306
Source Database       : hibernate

Target Server Type    : MYSQL
Target Server Version : 80026
File Encoding         : 65001

Date: 2022-11-12 11:45:16
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `orders`
-- ----------------------------
DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  `cid` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of orders
-- ----------------------------
INSERT INTO `orders` VALUES ('16', '订单1', '10');
INSERT INTO `orders` VALUES ('17', '订单2', '10');
INSERT INTO `orders` VALUES ('19', '订单3', '11');
INSERT INTO `orders` VALUES ('20', '订单4', '12');
INSERT INTO `orders` VALUES ('21', '订单5', '12');
INSERT INTO `orders` VALUES ('22', '订单6', '13');
 

2.2 导入相关依赖:

导入lombok、mysql-connector-java、hibernate-core依赖

       <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.6.9.Final</version>
        </dependency>

2.3 创建相关实体类:

Customer:

package com.xgsm.entity;

import lombok.Data;

import java.util.List;

@Data
public class Customer {
    private Integer id;
    private String name;
//   在Customer中添加与Orders表的关系(一对多)
    private List<Orders> orders;
}

Orders: 

package com.xgsm.entity;

import lombok.Data;

@Data
public class Orders {
    private Integer id;
    private String name;
    private Integer cid;
//    在Orders中添加与Customer的关系(一对一)
    private Customer customer;
}

2.4 配置hibernate.cfg.xml文件:

在hibernate.cgf.xml中配置数据源以及配置连接池等信息

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!--Session-factory:针对单个数据库映射经过编译的内存镜像文件,将数据库转换成一个java可以识别的镜像文件-->
    <!-- 构造Session-factory非常消耗资源,所以通常一个工程只需要创建一个Session-factory-->
    <session-factory>
        <!--连接字符串-->
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate?useUnicode=true</property>
        <!--连接数据库的用户名-->
        <property name="connection.username">root</property>
        <!--数据库用户密码-->
        <property name="connection.password">990501</property>
        <!--数据库驱动-->
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>

        <!--C3P0连接池,每次不够的时候增10-->
        <property name="hibernate.c3p0.acquire_increment">10</property>
        <!--释放资源时间的限制,单位是s-->
        <property name="hibernate.c3p0.idle_test_period">10000</property>
        <!--设置超时时间-->
        <property name="hibernate.c3p0.timeout">5000</property>
        <!--设置最大连接数-->
        <property name="hibernate.c3p0.max_size">30</property>
        <!--设置最小连接数-->
        <property name="hibernate.c3p0.min_size">5</property>
        <!--设置缓存Statement对象的数量-->
        <property name="hibernate.c3p0.max_statements">10</property>

        <!--设置数据库方言-->
        <property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
        <!--显示执行的SQL语句-->
        <property name="show_sql">true</property>
        <!--格式化SQL语句-->
        <property name="format_sql">true</property>
        <!--是否自动生成数据表-->
        <property name="hibernate.hbm2ddl.auto"/>

        <!--设置Hibernate自动管理上下文的策略-->
        <property name="current_session_context_class">thread</property>
        <!--在启动时删除并重新创建数据库-->
        <property name="hbm2ddl.auto">create</property>
        <!--注册实体类映射关系-->
        <mapping resource="com/xgsm/entity/Customer.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

2.5 创建实体类映射:

直接在entity(实体)包下创建映射实体类文件即可,具体配置如下:

<?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.xgsm.entity.Customer" table="customer">
        <comment>顾客表</comment>
        <id name="id" type="java.lang.Integer">
            <column name="id" length="10">
                <comment>主键</comment>
            </column>
            <!-- generator标签设置主键生成策略 ,identity为自增,assigned为主键由外部程序负责生成 -->
            <generator class="identity"></generator>
        </id>

        <property name="name" type="java.lang.String">
            <!--unique-key="AUTH_ROLE_USER_UNIQUE_KEY",那么在数据库表中对应的N个字段会组成“组合唯一约束” -->
            <column name="name">
                <comment>姓名</comment>
            </column>
        </property>
    </class>
</hibernate-mapping>

2.6 测试:

创建test测试类,向数据库中添加一个数据。

import com.xgsm.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test {
    public static void main(String[] args) {
//        创建Configuration,读取hibernate.cfg.xml
        Configuration configuration = new Configuration().configure();
//        获取SessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
//        获取session
        Session session = sessionFactory.openSession();
        Customer customer = new Customer();
        customer.setName("wahaha");
        session.save(customer);
        session.beginTransaction().commit();
        session.close();
    }
}

运行结果如下: 

2.7 测试中可能遇到的问题和解决措施:

上面的测试过程还是蛮顺利的,没有遇到什么bug。但是对于初学者来说有几个需要避免的错误,在这里总结一下,后续如果有其他的bug,再进行收集。

1、如果我们将实体类映射文件,放在实体类中,我们需要在pom.xml中设置一下,让maven能够读取到entity包下的文件,要不然会报错。具体实例如下:“Exception in thread "main" org.hibernate.boot.MappingNotFoundException: Mapping (RESOURCE) not found : com/xgsm/entity/Customer.hbm.xml : origin(com/xgsm/entity/Customer.hbm.xml)”

 解决措施:在maven中配置一下,让maven能够扫描到

<!--    设置可以读取java目录下的xml文件-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

 2、在创建好实体映射文件后,没有注入到‘hibernate.cfg.xml’中,导致找不到实体类文件“Unknown entity: com.xgsm.entity.Customer”

 解决措施:在‘hibernate.cfg.xml’文件中注册实体类映射关系

 <!--注册实体类映射关系-->
        <mapping resource="com/xgsm/entity/Customer.hbm.xml"/>

3、在hibernate.cfg.xml文件中设置数据库方言的时候,要根据自己mysql的版本去设置,要不然会报错,所以要注意。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暇光曙墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值