Hibernate入门
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,根据自己的系统下载不同的压缩包。并解压。
目录结构
我们选取需要的jar包
1.创建web项目
使用eclipse创建个web项目(这里不过多介绍)
将需要的jar包放入lib文件夹中
(可根据自己配置来导入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的根据主键查询
首先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();
}
}
查看控制台
成功!
其中通过这种方法来获取对象还有另一种方法
是通过load的方法去获取对象
Product p1 = (Product) session.get(Product.class, 3);
他们的结果是一样的,但是他们不同的地方是:
get:是非延迟的加载,就是无论后面的代码能不能访问到属性,属性有没有成功获取等,都会直接执行sql语句
load:是延迟加载,就是只有属性被访问到了才会去调用sql语句
所以,如果我们用一个不存在的主键去获取的话,两种方式的结果就会不一样
get(抛空指针null)
load(抛异常)
下面是删除数据库的一条数据
修改测试类
只需要在获取到对象之后再加一行代码
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();
}
}