Hibernate是一个开源的对象关系映射(ORM)框架,它对JDBC进行了轻量级的对象封装。
ORM(Object Relational Mapping,对象关系映射)是一种将数据库表结构映射到对象的技术。它通过定义对象和表之间的映射关系,使开发者可以直接使用面向对象的思想操作数据库,而不需要编写SQL语句。
依赖
1. 依赖
在pom.xml
文件中添加Hibernate
和PostgreSQL
依赖:
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.4.Final</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.1.1</version>
</dependency>
</dependencies>
2. 配置文件
创建名为hibernate.cfg.xml
的配置文件,并放在src/main/resources
路径下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//MyHibernate/MyHibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
<hibernate-configuration>
<session-factory>
<!--数据库连接驱动-->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<!--数据库地址、端口号、名称-->
<property name="hibernate.connection.url">jdbc:postgresql://192.168.71.27:9432/SIOM</property>
<!--用户名-->
<property name="hibernate.connection.username">postgres</property>
<!--密码-->
<property name="hibernate.connection.password">123456</property>
<!--数据库对应的方言-->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<!--是否打印SQL语句-->
<property name="hibernate.show_sql">true</property>
<!--是否对输出的SQL语句进行格式化 -->
<property name="hibernate.format_sql">true</property>
<!--影响数据库表结构,一般设为update-->
<property name="hbm2ddl.auto">update</property>
<!--映射文件的路径和名称-->
<mapping resource="team.hbm.xml"/>
</session-factory>
</hibernate-configuration>
3. 映射文件
创建名为team.hbm.xml
的配置文件,也放在src/main/resources
路径下
文件名中的team
主要是为了和实体类对应,可以随便取
这个文件的作用就是将Java里的实体类与数据库表中的字段一一对应起来table="t_team"
表示PostgreSQL
数据库中的表名为t_team
property
中的name
是实体类的属性名,column
是t_team
表中的字段名
注意:必须要有主键,这里的id
就是主键
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//MyHibernate/MyHibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="Team" table="t_team">
<id name="id" column="id"></id>
<property name="date" column="date" type="java.util.Date"></property>
<property name="teamName" column="teamName" length="128"></property>
<property name="points" column="points" type="java.lang.Double"></property>
</class>
</hibernate-mapping>
4. 实体类
在项目中创建一个实体类Team
Team
中属性(id
、date
、teamName
、points
)对应数据库表中的字段
import java.util.Date;
public class Team {
private int id;
private Date date;
private String teamName;
private double points;
public Team() {
}
public Team(int id, Date date, String teamName, double points) {
this.id = id;
this.date = date;
this.teamName = teamName;
this.points = points;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public double getPoints() {
return points;
}
public void setPoints(double points) {
this.points = points;
}
}
5. 操作数据
5.1 插入
如果数据库中不存在表t_team
,则会自动创建
public void insert() {
//读取并解析核心配置文件hibernate.cfg.xml
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
//读取并解析映射文件team.hbm.xml
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
//创建SessionFactory对象
SessionFactory sessionFactory = configuration.buildSessionFactory(standardServiceRegistry);
//创建并打开Session
Session session = sessionFactory.openSession();
//开启事务
Transaction transaction = session.beginTransaction();
//根据实体类构造数据
Date date = new Date();
List<Team> teamList = new ArrayList<Team>();
teamList.add(new Team(1, date, "Ferrari", 100.0));
teamList.add(new Team(2, date, "Mercedes-Benz", 99.5));
teamList.add(new Team(3, date, "BMW", 99));
teamList.add(new Team(4, date, "Porsche", 98));
teamList.add(new Team(5, date, "Lamborghini", 97));
teamList.add(new Team(6, date, "Bugatti", 96));
for (Team team : teamList) {
//添加记录
session.save(team);
}
//提交事务
transaction.commit();
//关闭资源
session.close();
sessionFactory.close();
}
5.2 删除
删除数据时必须要先创建一个对象,并且指定要删除的数据的主键
如同从表中根据主键删除一条数据
public void delete() {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = configuration.buildSessionFactory(standardServiceRegistry);
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//创建要删除的对象(必须指定主键)
Team team = new Team();
team.setId(3);
//删除记录
session.delete(team);
//提交事务
transaction.commit();
//关闭资源
session.close();
sessionFactory.close();
}
结果如下:
5.3 更新
也要先创建一个对象,根据主键修改其它字段
public void update() {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = configuration.buildSessionFactory(standardServiceRegistry);
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String dateString = "2023-07-13 12:15:59.123";
Date date = null;
try {
date = sdf.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
//根据主键(id)修改各个字段
Team team = new Team(5, date,"Audi", 97.55);
//更新记录
session.update(team);
//提交事务
transaction.commit();
//关闭资源
session.close();
sessionFactory.close();
}
结果如下:
5.4 查询
有两种方法:get()
和load()
相同: 第1个参数为实体类名(对应数据库表名),第2个参数为主键(对应表中的一条数据)
区别: 如果查不到对应的数据,get()
方法会返回null
,而load()
方法则会抛出ObjectNotFoundException
异常
public void query() {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = configuration.buildSessionFactory(standardServiceRegistry);
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//通过get方法查询
Team team1 = session.get(Team.class, 1);
System.out.println("id: " + team1.getId() + " date: " + team1.getDate() + " team_name: " + team1.getTeamName() + " points: " + team1.getPoints());
//通过load方法查询
//Team team2 = session.load(Team.class, 2);
//System.out.println("id: " + team2.getId() + " date: " + team2.getDate() + " team_name: " + team2.getTeamName() + " points: " + team2.getPoints());
//提交事务
transaction.commit();
//关闭资源
session.close();
sessionFactory.close();
}
结果如下:
5.5 有条件插入
有两种方法:saveOrUpdate()
和merge()
相同: 先根据主键进行查询,如果此条数据存在,则进行update;如果此条数据不存在,则执行insert
区别: 如果在session缓存中已经存在了一个相同主键的持久态对象,调用saveOrUpdate()
时方法会报错;而调用merge()
方法时会先将两个对象合并,所以不会报错
public void insertIfExist() {
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure().build();
SessionFactory sessionFactory = configuration.buildSessionFactory(standardServiceRegistry);
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Date date = new Date();
Team team = new Team(6, date,"Bugatti", 90.5);
//调用saveOrUpdate方法
session.saveOrUpdate(team);
//调用merge方法
//session.merge(team);
//提交事务
transaction.commit();
//关闭资源
session.close();
sessionFactory.close();
}