Hibernate框架入门

本文仅用于自我学习总结,无任何高深代码,大佬绕行,多多见谅!

1.概念

1.1 ORM

什么是框架:简单来说就是大师写好的半成品,已经具有部分功能

什么是ORM:  ORM是一种思想,ORM (全称为 :Object Relative Mapping)对象-关系映射;它的作用是在关系型数据库
和业务实体对象之间作一个映射,简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。

简单来说就是ORM可以实现利用对象操纵数据库中的表。

1.2 模型:

java是域模型:面向对象:类和对象来描述和存储数据
sql是关系模型:二维表和行描述和存储数据

1.表之间的关系分为

  • 1对n  :在n表中定义外键 来引用1表的主键列
  • 1对1  :根据主次/先后顺序 区分主表和从表  把从表的主键列 同时定义为外键 来引用主表的主键列
  • n对n  : 定义个关系表 其中定义两列作为联合主键 这两列同时定义为外键 来分别引用两个主表的主键列

2.类与类之间的关系(域模型)

  • 关联关系:  订单和客户 :订单要指定其所属客户  (部分依赖)
  • 聚集关系:  轮胎和车  : 轮胎是车的一部分 (整体和部分)
  • 依赖关系:  action和service: action中所有方法都要通过service来实现  (类似于寄生)
  • 一般化关系: 儿子和父亲:继承关系

1.3 什么是Hibernate:

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用面向对象编程思维来操纵数据库

2.  hibernate初次体验

2.1 创建java项目

2.2  引入依赖

  • 在src下创建一个文件夹lib

  • 复制依赖

  • 右键点击Add as Library

 

2.3 创建hibernate的属性集文件

文件位置:必须是src
文件名字:必须是hibernate.properties

# 定义链接数据库的四大参数
# 指定方言
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost:3306/db_1
hibernate.connection.username=root
hibernate.connection.password=562412

# 显示sql
hibernate.show_sql=true

2.4 根据表创建实体类

CREATE TABLE `student` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `sname` varchar(11) NOT NULL,
  `score` float(4,1) DEFAULT NULL,
  `sex` char(1) DEFAULT NULL,
  `sage` int(11) DEFAULT NULL,
  `sphoto` varchar(100) DEFAULT '0.jpeg',
  PRIMARY KEY (`sid`),
  UNIQUE KEY `sname` (`sname`)
) ENGINE=InnoDB AUTO_INCREMENT=220 DEFAULT CHARSET=utf8
  • 实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain=true)
public class Student   implements Serializable {
    private Integer id;
    private String name;
    private String sex;
    private Float score;
    private String photo;
    private Integer age;
}

2.5 创建实体类的mapper映射文件

指定表和类对应关系::以及表中列和类中属性的对应关系
必须和实体类在同一个文件夹中
名字必须是类名.hbm.xml    hibernate mapper缩写为hbm
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <!-- 指定类名 和 表名 -->
    <class name="test01.Student" table="student">
        <!-- 指定主键列对应的属性 -->
        <id name="id" column="sid" type="int">
            <generator class="identity"/><!-- 主键自增方式:数据库自增-->
        </id>
        <!--非主键对应的属性-->
        <property name="name" column="sname" type="string"></property>
        <property name="age" column="sage"/>
        <property name="sex" column="sex"/>
        <property name="score" column="score"/>
        <property name="photo" column="sphoto"/>
    </class>
</hibernate-mapping>

2.5 启动类

public class Test01 {
    public static void main(String[] args) {
          //1 创建configer对象 读取核心配置文件
        Configuration config=new Configuration();
          //2 指定加载mapper映射文件
        config.addClass(Student.class);
          //3 获取sessionFactory对象
        SessionFactory  factory=config.buildSessionFactory();
          //4 获取session对象
        Session session = factory.openSession();
          //5 获取事务
        Transaction transaction = session.beginTransaction();
        // 6开启事务
        transaction.begin();
        //7 执行crud
        //7.1 获取一个
        Student s1 = (Student) session.get(Student.class, 91);
        Student s2 = (Student) session.load(Student.class, 92);
        //7.2 获取所有:::query接口:::hql::::把sql的表名更改为类名 把列名更改为属性名
        Query query = session.createQuery("from test01.Student where age > 18");
        List<Student> list = query.list();
        //7.3 修改一个
        s1.setAge(s1.getAge()+10);
        s1.setName(s1.getName()+"同志");
        session.update(s1);

        //7.4 添加一个
        Serializable id = session.save(new Student().setPhoto("01.jpg").setAge(11).setName("呵呵呵01").setScore(11f).setSex("妖"));
        System.out.println("id="+id);

        //7.5 删除一个
        session.delete(s2);

        //8 关闭事务
        transaction.commit();
        //9 关闭连接 释放资源
        session.close();
        factory.close();
    }
}

3 hibernate的xml配置文件

与上面只有两处不同

1 不再创建属性集文件 而是创建xml文件
2 Configuration对象不需要addClass指定加载所有的mapper映射文件  而是加载hibernate的xml核心配置文件即可

3.1 创建xml文件

位置随意  名字随意
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
​
    <session-factory>
        <!-- 指定方言 -->
        <!--hibernate.dialect=org.hibernate.dialect.MySQLDialect-->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
​
​
        <!-- 指定连接的四大参数 -->
        <!--
            hibernate.connection.driver_class=com.mysql.jdbc.Driver
            hibernate.connection.url=jdbc:mysql://localhost:3306/db_1
            hibernate.connection.username=root
            hibernate.connection.password=root
        -->
        <property name="connection.url">jdbc:mysql://localhost:3306/db_1</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.username">root</property>
        <property name="connection.password">562412</property>
​
        <!-- 是否显示sql语句 -->
        <!--hibernate.show_sql=true-->
        <property name="show_sql">true</property>
​
        <!-- 导入类与表的映射文件 -->
        <mapping resource="test02/Student.hbm.xml" />
​
    </session-factory>
</hibernate-configuration>

3.2 启动类

//1 创建configer对象 读取核心配置文件
        Configuration config=new Configuration();
        //2 指定加载mapper映射文件
        //config.addClass(test02.Student.class);
        //2 记载指定的核心配置文件
        config.configure("test02/hibernate.cfg.xml");

4 load和get的区别

相同之处:都是通过主键获取一个对象

不同之处:

1. get是立即加载::get一旦调用就立刻执行sql语句

    load是懒加载::load调用时 获取的空的代理对象::当第一次使用此代理对象

2. get方法参数主键值不存在时 返回null

    load方法参数主键值不存在时 抛出异常ObjectNotFoundException

注意:session关闭后  如果是第一次使用load获取的对象  会报错LazyInitializationException

5 hibernate的id自增方式/自增策略

id标签用于指定表的主键列和类中属性的对应关系
generator标签用于指定id的自增方式
  • identity:数据库自增:id列需要添加约束auto_increment
  • increment:hibernate自增:hibernate在服务器内存中定义一个变量记录id的最大值
  • sequence:序列自增:适用于支持序列的数据库 oracle、sqlserver
  • uuid:适用于字符串类型的主键:生成一个32位的随机字符串
  • Hilo:高低位:需要第一个一个单独的表记录id的最大值 assigned:手动赋值
  • native:根据数据库特点自动选择sequence、identity、hilo
  • foreign:适用于1对1表关系时

5.1 identity:数据库自增

数据库自增:identity:数据库自增

  • sql

CREATE TABLE demo01(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(100)
);
INSERT INTO demo01 VALUES(111,"呵呵11");
  • mapper映射文件

<class name="test03.Demo01" table="demo01">
    <!-- 指定主键列对应的属性 -->
    <id name="id" column="id" type="int">
        <generator class="identity"/><!-- 主键自增方式:数据库自增::auto_increment-->
    </id>
    <!--非主键对应的属性-->
    <property name="name" column="name" />
</class>
  • 启动类

//测试添加
System.out.println("添加一个:::"+session.save(new Demo01(1234,"呵呵1234")));
System.out.println("添加一个:::"+session.save(new Demo01(null,"呵呵12345")));
  • 打印的日志信息

Hibernate: insert into demo01 (name) values (?)
添加一个:::112
Hibernate: insert into demo01 (name) values (?)
添加一个:::113

5.2 increment:hibernate自增

hibernate在服务器内存中定义一个变量记录id的最大值       不适用多线程和分布式项目

  • sql

CREATE TABLE demo02(
  id INT PRIMARY KEY,
  NAME VARCHAR(100)
);
INSERT INTO demo02 VALUES(111,"呵呵11");
  • mapper映射文件

<!-- 指定类名 和 表名 -->
<class name="test03.Demo02" table="demo02">
    <!-- 指定主键列对应的属性 -->
    <id name="id" column="id" type="int">
        <!--<generator class="identity"/>--><!-- 主键自增方式:数据库自增::auto_increment-->
        <generator class="increment"/><!--主键自增方式:hibernate自增-->
    </id>
    <!--非主键对应的属性-->
    <property name="name" column="name" />
</class>
  • 启动类

//测试添加
System.out.println("添加一个:::"+session.save(new Demo02(1234,"呵呵1234")));
System.out.println("添加一个:::"+session.save(new Demo02(null,"呵呵12345")));
  • 打印的日志信息

Hibernate: select max(id) from demo02 # 先访问数据库获取id的最大值 使用hibernate的内存一个变量记录此值
添加一个:::112
添加一个:::113
Hibernate: insert into demo02 (name, id) values (?, ?)
Hibernate: insert into demo02 (name, id) values (?, ?)

5.3 hilo:高低位

需要定义另外一张表 记录当前表的主键的最大值

  • sql

-- hilo高低位
CREATE TABLE demo03(
  id INT PRIMARY KEY,
  NAME VARCHAR(100)
);
INSERT INTO demo03 VALUES(111,"呵呵11");
-- 定义一个表:记录demo03的主键的最大值
CREATE TABLE demo03_hilo(
  hilo_value INT
);
-- 字段hilo_value必须先初始化一个值
INSERT INTO demo03_hilo VALUES(1000);
  • mapper映射文件

<!-- 指定类名 和 表名 -->
    <class name="test03.Demo03" table="demo03">
        <!-- 指定主键列对应的属性 -->
        <id name="id" column="id" type="int">
            <!--<generator class="identity"/>--><!-- 主键自增方式:数据库自增::auto_increment-->
            <!--<generator class="increment"/>--><!--主键自增方式:hibernate自增-->
            <generator class="hilo">
                <param name="table">demo03_hilo</param><!--数据库中主键发生表-->
                <param name="column">hilo_value</param><!--主键发生所在字段,必须初始化,即有一条记录设置了初始值-->
                <param name="max_lo">0</param><!--高位连接数字-->
            </generator>
        </id>
        <!--非主键对应的属性-->
        <property name="name" column="name" />
</class>
  • 启动类

System.out.println("添加一个:::"+session.save(new Demo03(1234,"呵呵1234")));
System.out.println("添加一个:::"+session.save(new Demo03(null,"呵呵12345")));
  • 打印的日志信息

添加一个:::1000
添加一个:::1001
Hibernate: insert into demo03 (name, id) values (?, ?)
Hibernate: insert into demo03 (name, id) values (?, ?)

5.4 uuid:随机字符串

针对于字符串类型的主键
  • sql

-- uuid随机字符串
CREATE TABLE demo04(
  id VARCHAR(100) PRIMARY KEY,
  NAME VARCHAR(100)
);
INSERT INTO demo04 VALUES("abcdeheh11","呵呵11");
  • mapper映射文件

<!-- 指定类名 和 表名 -->
<class name="test03.Demo04" table="demo04">
    <!-- 指定主键列对应的属性 -->
    <id name="id" column="id" type="string">
        <!--<generator class="identity"/>--><!-- 主键自增方式:数据库自增::auto_increment-->
        <!--<generator class="increment"/>--><!--主键自增方式:hibernate自增-->
        <!--name="table" 数据库中主键发生表-->
        <!--name="column" 主键发生所在字段,必须初始化,即有一条记录设置了初始值-->
        <!--name="max_lo" 高位连接数字-->
        <!--hilo:高低位
            <generator class="hilo">
                <param name="table">demo03_hilo</param>
                <param name="column">hilo_value</param>
                <param name="max_lo">0</param>
            </generator>
            -->
        <generator class="uuid"/>
    </id>
    <!--非主键对应的属性-->
    <property name="name" column="name" />
</class>
  • 启动类

//测试添加
System.out.println("添加一个:::"+session.save(new Demo04("1234","呵呵1234")));
System.out.println("添加一个:::"+session.save(new Demo04(null,"呵呵12345")));
  • 日志信息

添加一个:::40284ccd8a645197018a6451999d0001
添加一个:::40284ccd8a645197018a645199bf0002
Hibernate: insert into demo04 (name, id) values (?, ?)
Hibernate: insert into demo04 (name, id) values (?, ?)

5.5 sequence:序列自增

sequence:序列自增 适用于支持序列的数据库 只能针对于数字类型的主键

  • 项目引入oracle的驱动           ojdbc6.jar

  • oracle创建表和序列

CREATE TABLE demo05(
  id int PRIMARY KEY,
  NAME VARCHAR(100)
);
create sequence seq_demo05 start with 1000;
  • 更改hibernate的核心配置文件::指定连接数据库的四大参数和方言

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 指定方言 -->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl40</property>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.username">tian</property>
        <property name="connection.password">123</property>
        <!-- 是否显示sql语句 -->
        <property name="show_sql">true</property>
​
        <!-- 导入类与表的映射文件 -->
        <mapping resource="test03/Demo05.hbm.xml" />
    </session-factory>
</hibernate-configuration>
  • mapper映射文件

<!-- 指定类名 和 表名 -->
<class name="test03.Demo05" table="demo05">
    <!-- 指定主键列对应的属性 -->
    <id name="id" column="id" type="int">
        <!--<generator class="identity"/>--><!-- 主键自增方式:数据库自增::auto_increment-->
        <!--<generator class="increment"/>--><!--主键自增方式:hibernate自增-->
        <!--name="table" 数据库中主键发生表-->
        <!--name="column" 主键发生所在字段,必须初始化,即有一条记录设置了初始值-->
        <!--name="max_lo" 高位连接数字-->
        <!--hilo:高低位
            <generator class="hilo">
                <param name="table">demo03_hilo</param>
                <param name="column">hilo_value</param>
                <param name="max_lo">0</param>
            </generator>
            -->
        <!--<generator class="uuid"/>-->
        <generator class="sequence">
            <param name="sequence">seq_demo05</param>
        </generator>
​
    </id>
    <!--非主键对应的属性-->
    <property name="name" column="name" />
</class>
  • 启动类

//测试添加
System.out.println("添加一个:::"+session.save(new Demo05(1234,"呵呵1234")));
System.out.println("添加一个:::"+session.save(new Demo05(null,"呵呵12345")));
  • 打印的日志信息

Hibernate: select seq_demo05.nextval from dual
添加一个:::1000
Hibernate: select seq_demo05.nextval from dual
添加一个:::1001
Hibernate: insert into demo05 (name, id) values (?, ?)
Hibernate: insert into demo05 (name, id) values (?, ?)

5.6 assigned:手动赋值

assigned:手动赋值 调用save前 对象的id必须手动赋值

  • sql

CREATE TABLE demo06(
  id int PRIMARY KEY,
  NAME VARCHAR(100)
);
  • mapper映射文件

<!-- 指定类名 和 表名 -->
<class name="test03.Demo06" table="demo06">
    <!-- 指定主键列对应的属性 -->
    <id name="id" column="id" type="int">
        <!--<generator class="identity"/>--><!-- 主键自增方式:数据库自增::auto_increment-->
        <!--<generator class="increment"/>--><!--主键自增方式:hibernate自增-->
        <!--name="table" 数据库中主键发生表-->
        <!--name="column" 主键发生所在字段,必须初始化,即有一条记录设置了初始值-->
        <!--name="max_lo" 高位连接数字-->
        <!--hilo:高低位
            <generator class="hilo">
                <param name="table">demo03_hilo</param>
                <param name="column">hilo_value</param>
                <param name="max_lo">0</param>
            </generator>
            -->
        <!--<generator class="uuid"/>-->
        <!--
            <generator class="sequence">
                  <param name="sequence">seq_demo05</param>
            </generator>
            -->
        <generator class="assigned"></generator>
​
    </id>
    <!--非主键对应的属性-->
    <property name="name" column="name" />
</class>
  • 启动类

 System.out.println("添加一个:::"+session.save(new Demo06(1234,"呵呵1234")));
 System.out.println("添加一个:::"+session.save(new Demo06(null,"呵呵12345")));
  • 报错

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值