②Hibernate【关联】之多对多

本文探讨了数据库中多对多关系的处理方法,通过创建中间表将多对多关系转换为一对多关系,介绍了Hibernate如何直接映射多对多关联,并通过书籍与类别的例子详细说明了多对多关系的增删操作及注意事项。

 

 

1. 数据库的多对多关系:

1.数据库中不能直接映射多对多

处理:创建一个中间表,将一个多对多关系转换为两个一对多的关系

(hibernate可以直接映射多对多的关联关系)

 

2.Demo(书籍与书籍类别的关系)

一本书可以对应多个类别,同样一个类别也可以对应多本书(demo有张中间表,存放了书籍与类别的关系)

 

2.1Book类的实体映射文件

<!-- bid 为书籍id   cid为书籍类别id -->(一本书对应多个类别)

<set table="t_hibernate_book_category" name="categories" cascade="save-update" inverse="false">
			<!-- one -->
			<key column="bid"></key>
			<!--  many -->
			<many-to-many column="cid" class="com.zking.five.entity.Category"></many-to-many>
</set>

2.2Category类的实体映射文件

public Integer add(Book book) {
		Session session = SessionFactoryUtils.getSession();
		Transaction transaction = session.beginTransaction();
		Integer bid = (Integer)session.save(book);
		transaction.commit();
		session.close();
		return bid;
	}

一个书籍类别对应多本书

<set table="t_hibernate_book_category" name="books" cascade="save-update" inverse="true">
			<!-- one -->
			<key column="cid"></key>
			<!-- many -->
			<many-to-many column="bid" class="com.zking.five.entity.Book"></many-to-many>
</set>

3.多对多之增加

public Integer add(Book book) {
		Session session = SessionFactoryUtils.getSession();
		Transaction transaction = session.beginTransaction();
		Integer bid = (Integer)session.save(book);
		transaction.commit();
		session.close();
		return bid;
}
@Test
	public void testAdd1() {
		Book book = new Book();
		book.setBookName("这个杀手不太冷");
		book.setPrice(23f);
		Category category = new Category();
		category.setCategoryId(5);
		book.getCategories().add(this.CategoryDao.get(category));
		this.bookDao.add(book);
	}

4.多对多之删除

public void del(Book book) {
		Session session = SessionFactoryUtils.getSession();
		Transaction transaction = session.beginTransaction();
		session.delete(book);
		transaction.commit();
		session.close();
		
}

//主控方删除

在删除id为5的这本书时,能直接删除中间表的数据

@Test
	public void testDel() {
		Book book = new Book();
		book.setBookId(5);
		this.bookDao.del(book);
	}

	

//被控方删除  无法删除

public void testDel2() {
		Category category = new Category();
		category.setCategoryId(5);
		this.CategoryDao.del(category);
}
	

5. 多对多关系注意事项

  1.   一定要定义一个主控方
  2.    多对多删除 
    1.  主控方直接删除
      2.   被控方先通过主控方解除多对多关系,再删除被控方
          3.禁用级联删除

  3.   关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护

 

<think>我们正在创建个项目并添加Hibernate进行配置。根据引用内容,Hibernate个ORM框架,用于映射Java对象到数据库表。配置Hibernate需要核心配置文件和映射信息。以下是步骤: 1. 创建项目(假设使用Maven) 2. 添加Hibernate依赖 3. 创建Hibernate配置文件(hibernate.cfg.xml) 4. 创建实体类(POJO) 5. 创建实体类的映射文件(或使用注解) 由于引用[2]提到配置文件可以是属性文件或XML文件,这里我们使用更常见的hibernate.cfg.xml。 详细步骤: 步骤1:创建Maven项目 可以使用IDE(如IntelliJ IDEA或Eclipse)创建个Maven项目。 步骤2:添加Hibernate依赖 在pom.xml中添加Hibernate核心依赖和数据库驱动。例如,使用Hibernate 5.6.x和MySQL 8.0驱动: ```xml <dependencies> <!-- Hibernate core --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.15.Final</version> </dependency> <!-- MySQL connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies> ``` 步骤3:创建Hibernate配置文件(hibernate.cfg.xml) 在resources目录下创建hibernate.cfg.xml,配置数据库连接和基本属性。 ```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="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">your_password</property> <!-- JDBC连接池(使用内置) --> <property name="hibernate.connection.pool_size">1</property> <!-- SQL方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property> <!-- 在控制台输出SQL语句 --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <!-- 自动创建/更新表结构 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 映射文件或带注解的实体类的位置 --> <!-- 如果使用映射文件,则添加以下行 --> <!-- <mapping resource="com/example/User.hbm.xml"/> --> <!-- 如果使用注解,则添加实体类 --> <!-- <mapping class="com.example.User"/> --> </session-factory> </hibernate-configuration> ``` 步骤4:创建实体类(例如User) 使用注解方式(推荐)或XML映射文件。这里使用注解。 ```java package com.example; import javax.persistence.*; @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; // 必须有无参构造函数 public User() { } // Getter和Setter // ... 省略 } ``` 步骤5:在配置文件中指定实体类 在hibernate.cfg.xml中添加: ```xml <mapping class="com.example.User"/> ``` 步骤6:测试Hibernate 编写个简单的测试类,保存个User对象。 ```java import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Main { public static void main(String[] args) { // 创建SessionFactory SessionFactory sessionFactory = new Configuration() .configure("hibernate.cfg.xml") // 默认加载类路径下的hibernate.cfg.xml .buildSessionFactory(); // 创建Session try (Session session = sessionFactory.openSession()) { // 开始事务 session.beginTransaction(); // 创建User对象 User user = new User(); user.setName("John Doe"); user.setEmail("john.doe@example.com"); // 保存User session.save(user); // 提交事务 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); } finally { sessionFactory.close(); } } } ``` 注意事项: - 确保数据库存在(在配置文件中指定的数据库),并且用户有权限。 - hibernate.hbm2ddl.auto属性设置为update,表示如果表不存在则创建,存在则更新结构(根据实体类)。在生产环境中应谨慎使用。 以上步骤完成了Hibernate项目的搭建和基本配置。 相关问题: 1. Hibernate中如何配置多对关系? 2. Hibernate的SessionFactory和Session有什么区别? 3. 如何配置Hibernate使用连接池(如C3P0)? 4. Hibernate的缓存机制是什么? 5. 如何优化Hibernate的性能? </think> ### 建立项目并配置 Hibernate 的完整指南 #### 、创建项目基础结构 1. **使用 Maven 创建项目** ```bash mvn archetype:generate -DgroupId=com.example -DartifactId=hibernate-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false ``` 2. **项目结构** ``` hibernate-demo ├── src │ ├── main │ │ ├── java │ │ ├── resources <-- 配置文件目录 │ │ └── webapp │ └── test └── pom.xml ``` #### 、添加 Hibernate 依赖 在 `pom.xml` 中添加: ```xml <dependencies> <!-- Hibernate 核心 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.15.Final</version> </dependency> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies> ``` #### 三、配置 Hibernate 1. **创建配置文件 `hibernate.cfg.xml`** 位置:`src/main/resources/hibernate.cfg.xml` ```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="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_db</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">your_password</property> <!-- 方言设置 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property> <!-- 开发环境配置 --> <property name="hibernate.show_sql">true</property> <!-- 显示SQL --> <property name="hibernate.format_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 自动更新表结构 --> <!-- 实体类映射 --> <mapping class="com.example.model.User"/> </session-factory> </hibernate-configuration> ``` 2. **关键配置说明** - `hbm2ddl.auto` 选项: - `update`:自动更新表结构(开发环境推荐) - `create`:每次重建表 - `validate`:验证表结构是否匹配 - `none`:禁用自动更新 - 数据库方言需按版本选择: - MySQL 5.x:`MySQL5Dialect` - MySQL 8.x:`MySQL8Dialect` #### 四、创建实体类 ```java package com.example.model; import javax.persistence.*; @Entity @Table(name = "users") // 映射到数据库表 public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键 private Long id; @Column(name = "user_name", nullable = false, length = 50) private String name; @Column(unique = true) private String email; // 必须有无参构造函数 public User() {} // Getter/Setter 方法 // ... } ``` #### 五、测试 Hibernate 操作 ```java public class HibernateDemo { public static void main(String[] args) { // 1. 加载配置 Configuration config = new Configuration().configure(); // 2. 创建 SessionFactory try (SessionFactory sessionFactory = config.buildSessionFactory(); Session session = sessionFactory.openSession()) { // 3. 开启事务 session.beginTransaction(); // 4. 创建并保存对象 User user = new User(); user.setName("张三"); user.setEmail("zhangsan@example.com"); session.save(user); // 执行INSERT // 5. 提交事务 session.getTransaction().commit(); // 6. 查询验证 User savedUser = session.get(User.class, user.getId()); System.out.println("保存的用户: " + savedUser.getName()); } } } ``` #### 六、验证结果 1. **控制台输出**: ``` Hibernate: insert into users (email, name) values (?, ?) 保存的用户: 张三 ``` 2. **数据库检查**: ```sql SELECT * FROM users; ``` #### 七、配置优化建议 1. **生产环境配置**: - 移除 `hibernate.show_sql` 避免敏感信息泄露 - 将 `hbm2ddl.auto` 改为 `validate` - 添加连接池配置(如 HikariCP) 2. **连接池配置示例**: ```xml <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.timeout">1800</property> ``` --- ### 相关问题 1. Hibernate 中 `@OneToMany` 和 `@ManyToOne` 注解如何配置关联关系?[^1] 2. 如何优化 Hibernate 的 N+1 查询问题?[^2] 3. Hibernate 的缓存机制有哪几种?各自适用什么场景?[^2] 4. 如何在 Spring Boot 项目中集成 Hibernate? 5. Hibernate 的悲观锁和乐观锁实现方式有什么区别?[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值