刚开始接触Hibernate,遇到了很多问题,也学习了IDEA很多便捷的配置方法,具体可以参看前面的博文:https://blog.csdn.net/weixin_39663138/article/details/87882776
今天开始接触Hibernate比较高级的应用,对应于DB中ER模型中各种模式。但其配置也是弄了许久,下面记录一下。
Step 1:设置数据库
在 MySQL 中新建两个表,我设置的是 product 和 factory,用来反映多对一(many-to-one)的关系模式,一个产品来自一个工厂,但是一个工厂确可以生产多个产品,如图,并设置 product 的外码:
factory 表和 product 表
factory 表
product 表
外码
Step 2:IDEA设置生成类和配置文件
在此之前,新建项目,具体可参考:https://blog.csdn.net/weixin_39663138/article/details/87882776
完成项目创建后,点击左下角【Persistence】–>【右键项目名】–>【Generate Persistence Mapping】–> 【By Database Schema】
具体如图:
按如下配置,之后ok
修改一下 Product.hbm.xml 文件,如下:
<?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>
<class name="com.wyx.mapping.Product" table="product" schema="hibernate">
<id name="id">
<column name="id" sql-type="int(11)"/>
</id>
<property name="name">
<column name="name" sql-type="varchar(45)" length="45"/>
</property>
<property name="price">
<column name="price" sql-type="double" precision="-1"/>
</property>
<many-to-one name="factoryByFactoryId" class="com.wyx.mapping.Factory">
<column name="factory_id"/>
</many-to-one>
</class>
</hibernate-mapping>
再修改一下 Product.java 文件
package com.wyx.mapping;
import java.util.Objects;
public class Product {
private Integer id;
private String name;
private Double price;
private Factory factoryByFactoryId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
return Objects.equals(id, product.id) &&
Objects.equals(name, product.name) &&
Objects.equals(price, product.price);
}
@Override
public int hashCode() {
return Objects.hash(id, name, price);
}
public Factory getFactoryByFactoryId() {
return factoryByFactoryId;
}
public void setFactoryByFactoryId(Factory factoryByFactoryId) {
this.factoryByFactoryId = factoryByFactoryId;
}
}
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?serverTimezone=UTC&characterEncoding=UTF-8</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="connection.username">temp</property>
<property name="connection.password">temp</property>
<mapping resource="com/wyx/mapping/Factory.hbm.xml"/>
<mapping resource="com/wyx/mapping/Product.hbm.xml"/>
</session-factory>
</hibernate-configuration>
关于 connection.url 需要这么配置才不会报错,具体可以参看:
https://blog.csdn.net/weixin_39663138/article/details/87122321
测试文件:
SelectProduct.java
package com.wyx.mapping;
import com.wyx.hibernate.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class SelectProduct {
public static void main(String[] args){
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.beginTransaction();
Product product = session.get(Product.class, new Integer("1"));
System.out.println("name: " + product.getName());
System.out.println("price: " + product.getPrice());
System.out.println("factory: " + product.getFactoryByFactoryId().getName());
transaction.commit();
}catch (Exception e){
e.printStackTrace();
if (transaction != null){
transaction.rollback();
}
}finally {
HibernateUtil.closeSession();
}
}
}
其中,涉及 HibernateUtil.java 文件如下:(也可以简单配置获取Session,如下配置保证线程安全)
package com.wyx.hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<>();
private static SessionFactory sessionFactory = null;
static {
try {
Configuration configuration = new Configuration().configure(); // 加载 Hibernate 配置文件
sessionFactory = configuration.buildSessionFactory();
}catch (Exception e){
System.err.println("创建会话工厂失败");
e.printStackTrace();
}
}
// 获取 Session
public static Session getSession() throws HibernateException {
Session session = threadLocal.get();
if (session == null || !session.isOpen()){
if (sessionFactory == null){
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
/**
* 重建会话工厂
*/
public static void rebuildSessionFactory(){
try {
Configuration configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
}catch (Exception e){
System.err.println("创建会话工厂失败");
e.printStackTrace();
}
}
// 获取 SessionFactory 对象
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
// 关闭 session
public static void closeSession() throws HibernateException{
Session session = threadLocal.get();
threadLocal.set(null);
if (session != null){
session.close(); // 关闭 Session
}
}
}
运行结果:
如图所示,当查询工厂名称时,Hibernate又自动输出了一条语句进行查询。
记录结束~