欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hibernate入门

程序员文章站 2024-03-23 13:16:52
...

       Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架(对象关系映射,英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换),hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,完成数据持久化的重任。(来自百度百科

      博主也接触hibernate有一段时间了,借此来写一篇博客来梳理自己学到的知识。(学习资源大部分在网站教程等视频学得)

 

话不多说,下面开始:

 

环境:eclipse、tomcat9.0.8、jdk1.8、mysql5.1.2以上

为什么要用hibernate呢?其实hibernate对于数据库的操作做了很多封装,当我们正常使用JDBC数据库操作,创建连接、关闭连接,反反复复。而hibernate对于这些操作,都将其封装了起来,用面向对象的方式来操作关系向数据库,使得代码维护更加容易,数据库的操作更加简便。

 

首先,官网下载hibernate,根据自己的系统下载不同的压缩包。并解压。

目录结构

Hibernate入门

我们选取需要的jar包

1.创建web项目

使用eclipse创建个web项目(这里不过多介绍)

Hibernate入门

将需要的jar包放入lib文件夹中

Hibernate入门

(可根据自己配置来导入jar包,目前我的jar包如上)

2.创建数据库和表和配置

创建数据库和表

create database hibernate;


use hibernate;
 
CREATE TABLE product_ (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(30) ,
  price float ,
  PRIMARY KEY (id)
) DEFAULT CHARSET=UTF8;

新建com.hibernate.pojo包,新建实体类,使之与数据库的表对应

package com.hibernate.pojo;
  
public class Product {
    int id;
    String name;
    float price;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
      
}

在包com.hibernate.pojo下 新建一个配置文件Product.hbm.xml, 用于映射Product类对应数据库中的product表(文件名 Product.hbm.xml中P一定要大写,要和类名保持一致

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="com.hibernate.pojo">
    <class name="Product" table="product">
        <id name="id" column="id">
            <!--id的自增长方式采用数据库的本地方式-->
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
        <property name="price" />
    </class>
</hibernate-mapping>

在src目录新建并配置hibernate.cfg.xml

<?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="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <!-- SQL dialect -->
        <!-- 这表示使用MYSQL方言 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- Hibernate事务管理方式,即每个线程一个事务 -->
        <property name="current_session_context_class">thread</property>
        <!-- 控制台显示执行的sql语句,true输出,false不输出 -->
        <property name="show_sql">true</property>
        <!-- 是否会自动更新数据库的表结构,其实配置了这个是不需要创建表的,因为Hibernate会自动去创建表结构 -->
        <!-- 所以之前创建表那一步也可以省略 -->
        <property name="hbm2ddl.auto">update</property>
        <!-- 识别Product这个实体类 -->
        <mapping resource="com/hibernate/pojo/Product.hbm.xml" />
    </session-factory>
 
</hibernate-configuration>

好,现在配置完成,我们来测试下是否可以使用hibernate来操作数据库

3.测试

新建测试类

package com.hibernate.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.hibernate.pojo.Product;

public class Test {
	public static void main(String[] args) {
		/*获取SessionFactory*/
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        /*通过SessionFactory 获取一个Session*/
        Session session = sf.openSession();
        /*在Session基础上开启一个事务*/
        session.beginTransaction();
        /*new一个Product对象用于测试*/
        Product p = new Product();
        p.setName("iphone2000");
        p.setPrice(666);
        /*调用Session的save方法把对象保存到数据库*/
        session.save(p);
        /*提交事务*/
        session.getTransaction().commit();
        /*关闭*/
        session.close();
        sf.close();
    }
}

其中实体类在Hibernate的有3种状态,分别为:瞬时态(Transient)、持久态(Persistent)、脱管态(Detached).处于持久态的对象也称为PO(PersistenceObject),瞬时对象和脱管对象也称为VO(ValueObject).

new 对象,而没有将它和数据库连接起来,没有标识,这就叫做瞬时态。

瞬时态进行了save  saveorUpdate方法后,与数据库有了联系,这就是持久态,

当关闭session 或者清除,但是还有和数据库联系的标识,这就是托管态,或者是游离态。

Product p = new Product();
p.setName("iphone2000");
p.setPrice(666);
//此时p是瞬时状态
s.save(p);
//此时p是持久状态
s.getTransaction().commit();
s.close();
//此时p是脱管状态
sf.close();

运行main方法

看到控制台输出

Hibernate: insert into product (name, price) values (?, ?)

查看数据库

Hibernate入门

插入成功,大功告成!

 

下面是hibernate的根据主键查询

首先Product类增加toString()方法

@Override
	public String toString() {
		return "Product [id=" + id + ", name=" + name + ", price=" + price + "]";
	}

 

修改测试类

package com.hibernate.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.hibernate.pojo.Product;

public class Test {
	public static void main(String[] args) {
		/*获取SessionFactory*/
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        /*通过SessionFactory 获取一个Session*/
        Session session = sf.openSession();
        /*在Session基础上开启一个事务*/
        session.beginTransaction();
        /*调用Session的get方法,根据id来获取对象。
         *并且除了id之外,还需要传递该类对象*/
        Product p1 = (Product) session.get(Product.class, 3);
        /*输出*/
        System.out.println(p1.toString());        
        /*提交事务*/
        session.getTransaction().commit();
        /*关闭*/
        session.close();
        sf.close();
    }
}

查看控制台

Hibernate入门

成功!

其中通过这种方法来获取对象还有另一种方法

是通过load的方法去获取对象

Product p1 = (Product) session.get(Product.class, 3);

他们的结果是一样的,但是他们不同的地方是:

get:是非延迟的加载,就是无论后面的代码能不能访问到属性,属性有没有成功获取等,都会直接执行sql语句

load:是延迟加载,就是只有属性被访问到了才会去调用sql语句

所以,如果我们用一个不存在的主键去获取的话,两种方式的结果就会不一样

get(抛空指针null)
Hibernate入门

load(抛异常)

Hibernate入门

下面是删除数据库的一条数据

修改测试类

只需要在获取到对象之后再加一行代码

session.delete(p)

package com.hibernate.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.hibernate.pojo.Product;

public class Test {
	public static void main(String[] args) {
		/*获取SessionFactory*/
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        /*通过SessionFactory 获取一个Session*/
        Session session = sf.openSession();
        /*在Session基础上开启一个事务*/
        session.beginTransaction();
        /*调用Session的get方法,根据id来获取对象。
         *并且除了id之外,还需要传递该类对象*/
        Product p1 = (Product) session.get(Product.class, 2);
        /*删除*/
        session.delete(p1);
        /*提交事务*/
        session.getTransaction().commit();
        /*关闭*/
        session.close();
        sf.close();
    }
}

下面是修改数据库的一条数据

package com.hibernate.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.hibernate.pojo.Product;

public class Test {
	public static void main(String[] args) {
		/*获取SessionFactory*/
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
        /*通过SessionFactory 获取一个Session*/
        Session session = sf.openSession();
        /*在Session基础上开启一个事务*/
        session.beginTransaction();
        /*调用Session的get方法,根据id来获取对象。
         *并且除了id之外,还需要传递该类对象*/
        Product p1 = (Product) session.get(Product.class, 2);
        /*修改属性值*/
        p1.setName("xiaomi2000");
        
        p1.setPrice(1999);
        /*update,更新下*/
        session.update(p1);
        
        /*提交事务*/
        session.getTransaction().commit();
        /*关闭*/
        session.close();
        sf.close();
    }
}