Hibernate 多对多映射 - 连接表

今天,我们将使用XML和注释配置来研究Hibernate多对多映射 。前面我们研究了如何在Hibernate中实现一到One和[一对多mapping](/community/tutorials/hibernate-one-to-many-mapping-annotationHibernate一到多映射]。

多对多休眠

多对多 映射通常使用** JOIN表** 在数据库中实现。例如,我们可以有CartItem表,以及用于多对多映射的Cart_Items表。每个购物车可以有多个项目,每个项目可以是多个购物车的一部分,所以我们在这里有一个多对多的映射。

Hibernate多对多映射数据库设置

下面的脚本可以用来创建我们的多对多示例数据库表,这些脚本用于MySQL数据库。如果您使用的是任何其他数据库,则可能需要进行一些小的更改才能使其正常工作。

 1DROP TABLE IF EXISTS `Cart_Items`;
 2DROP TABLE IF EXISTS `Cart`;
 3DROP TABLE IF EXISTS `Item`;
 4
 5CREATE TABLE `Cart` (
 6  `cart_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 7  `cart_total` decimal(10,0) NOT NULL,
 8  PRIMARY KEY (`cart_id`)
 9) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
10
11CREATE TABLE `Item` (
12  `item_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
13  `item_desc` varchar(20) NOT NULL,
14  `item_price` decimal(10,0) NOT NULL,
15  PRIMARY KEY (`item_id`)
16) ENGINE=InnoDB DEFAULT CHARSET=utf8;
17
18CREATE TABLE `Cart_Items` (
19  `cart_id` int(11) unsigned NOT NULL,
20  `item_id` int(11) unsigned NOT NULL,
21  PRIMARY KEY (`cart_id`,`item_id`),
22  CONSTRAINT `fk_cart` FOREIGN KEY (`cart_id`) REFERENCES `Cart` (`cart_id`),
23  CONSTRAINT `fk_item` FOREIGN KEY (`item_id`) REFERENCES `Item` (`item_id`)
24) ENGINE=InnoDB DEFAULT CHARSET=utf8;

注意,Cart_Items表没有任何额外的列,实际上在多对多映射表中有额外的列没有多大意义。但如果你有额外的专栏,实现会有一些变化,我们将在另一篇文章中研究这一点。下图显示了这些表之间的实体关系。Hibernate多对多映射Tables我们的数据库设置现在已经准备好了,让我们继续创建Hibernate多对多映射项目。

Hibernate多对多映射项目结构

在Eclipse或您最喜欢的IDE中创建一个maven项目,下图显示了应用程序中的结构和不同组件。Hibernate Many To Many Mapping Project,Hibernate Many to Many我们将首先研究基于XML的映射实现,然后转向使用JPA注释。

Hibernate Maven依赖

最终的pom.xml包含最新版本4.3.5的Hibernate依赖项 和MySQL驱动程序依赖项** 。pom.xml

 1<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
 2    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 3    <modelVersion>4.0.0</modelVersion>
 4    <groupId>com.journaldev.hibernate</groupId>
 5    <artifactId>HibernateManyToManyMapping</artifactId>
 6    <version>0.0.1-SNAPSHOT</version>
 7
 8    <dependencies>
 9    	<dependency>
10    		<groupId>org.hibernate</groupId>
11    		<artifactId>hibernate-core</artifactId>
12    		<version>4.3.5.Final</version>
13    	</dependency>
14    	<dependency>
15    		<groupId>mysql</groupId>
16    		<artifactId>mysql-connector-java</artifactId>
17    		<version>5.0.5</version>
18    	</dependency>
19    </dependencies>
20
21</project>

休眠多对多XML配置模型类

Cart.java

 1package com.journaldev.hibernate.model;
 2
 3import java.util.Set;
 4
 5public class Cart {
 6
 7    private long id;
 8    private double total;
 9
10    private Set<Item> items;
11    
12    public double getTotal() {
13    	return total;
14    }
15
16    public void setTotal(double total) {
17    	this.total = total;
18    }
19
20    public long getId() {
21    	return id;
22    }
23
24    public void setId(long id) {
25    	this.id = id;
26    }
27
28    public Set<Item> getItems() {
29    	return items;
30    }
31
32    public void setItems(Set<Item> items) {
33    	this.items = items;
34    }
35
36}

‘tem.java’,你知道的。

 1package com.journaldev.hibernate.model;
 2
 3import java.util.Set;
 4
 5public class Item {
 6
 7    private long id;
 8    private double price;
 9    private String description;
10
11    private Set<Cart> carts;
12    
13    public long getId() {
14    	return id;
15    }
16
17    public void setId(long id) {
18    	this.id = id;
19    }
20
21    public double getPrice() {
22    	return price;
23    }
24
25    public void setPrice(double price) {
26    	this.price = price;
27    }
28
29    public String getDescription() {
30    	return description;
31    }
32
33    public void setDescription(String description) {
34    	this.description = description;
35    }
36
37    public Set<Cart> getCarts() {
38    	return carts;
39    }
40
41    public void setCarts(Set<Cart> carts) {
42    	this.carts = carts;
43    }
44}

请注意,购物车有一组商品,而商品有一套购物车,这样我们就实现了双向关联。这意味着我们可以将其配置为在保存购物车时保存项目,反之亦然。对于单向映射,通常我们都会在其中设置一个模型类。我们将使用注释进行单向映射。

Hibernate多对多映射XML配置

让我们为购物车和商品创建Hibernate多对多映射XML配置文件。我们将实现双向多对多映射。cart.hbm.xml

 1<?xml version="1.0"?>
 2<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3    "https://hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 4
 5<hibernate-mapping package="com.journaldev.hibernate.model">
 6    <class name="Cart" table="CART">
 7    	<id name="id" type="long">
 8    		<column name="cart_id" />
 9    		<generator class="identity" />
10    	</id>
11    	<property name="total" type="double" column="cart_total" />
12
13    	<set name="items" table="CART_ITEMS" fetch="select" cascade="all">
14    		<key column="cart_id" />
15    		<many-to-many class="Item" column="item_id" />
16    	</set>
17    </class>
18
19</hibernate-mapping>

请注意,项目集映射到CART_ITEMS表。由于Cart是主要对象,因此cart_id是键,而多对多映射使用Item类item_id列。item.hbm.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
 3"https://hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
 4
 5<hibernate-mapping package="com.journaldev.hibernate.model">
 6
 7    <class name="Item" table="ITEM">
 8    	<id name="id" type="long">
 9    		<column name="item_id" />
10    		<generator class="identity" />
11    	</id>
12    	<property name="description" type="string" column="item_desc" />
13
14    	<property name="price" type="double" column="item_price" />
15
16    	<set name="carts" table="CART_ITEMS" fetch="select" cascade="all">
17    		<key column="item_id" />
18    		<many-to-many class="Cart" column="cart_id" />
19    	</set>
20
21    </class>
22
23</hibernate-mapping>

从上面可以看到,映射与购物车映射配置非常相似。

基于XML的多对多映射的Hibernate配置

我们的Hibernate配置文件如下所示。hibernate.cfg.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE hibernate-configuration PUBLIC
 3    	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4    	"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5<hibernate-configuration>
 6    <session-factory>
 7    	<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 8    	<property name="hibernate.connection.password">pankaj123</property>
 9    	<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
10    	<property name="hibernate.connection.username">pankaj</property>
11    	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
12
13    	<property name="hibernate.current_session_context_class">thread</property>
14    	<property name="hibernate.show_sql">true</property>
15
16    	<mapping resource="cart.hbm.xml" />
17    	<mapping resource="item.hbm.xml" />
18    </session-factory>
19</hibernate-configuration>

基于XML映射的Hibernate SessionFactory实用程序类

‘HibernateUtil.java’

 1package com.journaldev.hibernate.util;
 2
 3import org.hibernate.SessionFactory;
 4import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 5import org.hibernate.cfg.Configuration;
 6import org.hibernate.service.ServiceRegistry;
 7
 8public class HibernateUtil {
 9
10    private static SessionFactory sessionFactory;
11
12    private static SessionFactory buildSessionFactory() {
13    	try {
14    		// Create the SessionFactory from hibernate.cfg.xml
15    		Configuration configuration = new Configuration();
16    		configuration.configure("hibernate.cfg.xml");
17    		System.out.println("Hibernate Configuration loaded");
18
19    		ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
20    				.applySettings(configuration.getProperties()).build();
21    		System.out.println("Hibernate serviceRegistry created");
22
23    		SessionFactory sessionFactory = configuration
24    				.buildSessionFactory(serviceRegistry);
25
26    		return sessionFactory;
27    	} catch (Throwable ex) {
28    		System.err.println("Initial SessionFactory creation failed." + ex);
29    		ex.printStackTrace();
30    		throw new ExceptionInInitializerError(ex);
31    	}
32    }
33
34    public static SessionFactory getSessionFactory() {
35    	if (sessionFactory == null)
36    		sessionFactory = buildSessionFactory();
37    	return sessionFactory;
38    }
39
40}

这是一个简单的实用程序类,用作SessionFactory的工厂。

Hibernate多对多映射XML配置测试方案

我们的Hibernate多对多映射设置已经准备好了,让我们来测试一下。我们将编写两个程序,一个是保存购物车,并看到Items和Cart_Items信息也被保存。另一个用于保存物品数据并检查相应的Cart和Cart_Items是否已保存。HibernateManyToManyMain.java

 1package com.journaldev.hibernate.main;
 2
 3import java.util.HashSet;
 4import java.util.Set;
 5
 6import org.hibernate.Session;
 7import org.hibernate.SessionFactory;
 8import org.hibernate.Transaction;
 9
10import com.journaldev.hibernate.model.Cart;
11import com.journaldev.hibernate.model.Item;
12import com.journaldev.hibernate.util.HibernateUtil;
13
14public class HibernateManyToManyMain {
15    
16    //Saving many-to-many where Cart is primary
17    public static void main(String[] args) {
18    	
19    	Item iphone = new Item();
20    	iphone.setPrice(100); iphone.setDescription("iPhone");
21    	
22    	Item ipod = new Item();
23    	ipod.setPrice(50); ipod.setDescription("iPod");
24    	
25    	Set<Item> items = new HashSet<Item>();
26    	items.add(iphone); items.add(ipod);
27    	
28    	Cart cart = new Cart();
29    	cart.setItems(items);
30    	cart.setTotal(150);
31    	
32    	Cart cart1 = new Cart();
33    	Set<Item> items1 = new HashSet<Item>();
34    	items1.add(iphone);
35    	cart1.setItems(items1);
36    	cart1.setTotal(100);
37    	
38    	SessionFactory sessionFactory = null;
39    	try{
40    	sessionFactory = HibernateUtil.getSessionFactory();
41    	Session session = sessionFactory.getCurrentSession();
42    	Transaction tx = session.beginTransaction();
43    	session.save(cart);
44    	session.save(cart1);
45    	System.out.println("Before committing transaction");
46    	tx.commit();
47    	sessionFactory.close();
48    	
49    	System.out.println("Cart ID="+cart.getId());
50    	System.out.println("Cart1 ID="+cart1.getId());
51    	System.out.println("Item1 ID="+iphone.getId());
52    	System.out.println("Item2 ID="+ipod.getId());
53    	
54    	}catch(Exception e){
55    		e.printStackTrace();
56    	}finally{
57    		if(sessionFactory != null && !sessionFactory.isClosed()) sessionFactory.close();
58    	}
59    	
60    }
61
62}

当我们执行上面的Hibernate多对多映射示例程序时,我们得到以下输出。

 1Hibernate Configuration loaded
 2Hibernate serviceRegistry created
 3Hibernate: insert into CART (cart_total) values (?)
 4Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
 5Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
 6Hibernate: insert into CART (cart_total) values (?)
 7Before committing transaction
 8Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
 9Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
10Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
11Cart ID=1
12Cart1 ID=2
13Item1 ID=1
14Item2 ID=2

请注意,一旦通过第一个购物车保存了物品数据,就会生成Item_id,在保存第二个购物车时,不会再次保存它。另一个需要注意的要点是,当我们提交事务时,会保存多对多连接表数据。这样做是为了在我们选择回滚事务时获得更好的性能。HibernateBiDirectionalManyToManyMain.java

 1package com.journaldev.hibernate.main;
 2
 3import java.util.HashSet;
 4import java.util.Set;
 5
 6import org.hibernate.Session;
 7import org.hibernate.SessionFactory;
 8import org.hibernate.Transaction;
 9
10import com.journaldev.hibernate.model.Cart;
11import com.journaldev.hibernate.model.Item;
12import com.journaldev.hibernate.util.HibernateUtil;
13
14public class HibernateBiDirectionalManyToManyMain {
15
16    //Saving many-to-many where Item is primary
17    public static void main(String[] args) {
18    	
19    	Item iphone = new Item();
20    	iphone.setPrice(100); iphone.setDescription("iPhone");
21    	
22    	Item ipod = new Item();
23    	ipod.setPrice(50); ipod.setDescription("iPod");
24    	
25    	Cart cart = new Cart();
26    	cart.setTotal(150);
27    	
28    	Cart cart1 = new Cart();
29    	cart1.setTotal(100);
30    	
31    	Set<Cart> cartSet = new HashSet<Cart>();
32    	cartSet.add(cart);cartSet.add(cart1);
33    	
34    	Set<Cart> cartSet1 = new HashSet<Cart>();
35    	cartSet1.add(cart);
36    	
37    	iphone.setCarts(cartSet1);
38    	ipod.setCarts(cartSet);
39    	
40    	SessionFactory sessionFactory = null;
41    	try{
42    	sessionFactory = HibernateUtil.getSessionFactory();
43    	Session session = sessionFactory.getCurrentSession();
44    	Transaction tx = session.beginTransaction();
45    	session.save(iphone);
46    	session.save(ipod);
47    	tx.commit();
48    	sessionFactory.close();
49    	
50    	System.out.println("Cart ID="+cart.getId());
51    	System.out.println("Cart1 ID="+cart1.getId());
52    	System.out.println("Item1 ID="+iphone.getId());
53    	System.out.println("Item2 ID="+ipod.getId());
54    	
55    	}catch(Exception e){
56    		e.printStackTrace();
57    	}finally{
58    		if(sessionFactory != null && !sessionFactory.isClosed()) sessionFactory.close();
59    	}
60    	
61    }
62
63}

上述程序的输出是:

 1Hibernate Configuration loaded
 2Hibernate serviceRegistry created
 3Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
 4Hibernate: insert into CART (cart_total) values (?)
 5Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
 6Hibernate: insert into CART (cart_total) values (?)
 7Hibernate: insert into CART_ITEMS (item_id, cart_id) values (?, ?)
 8Hibernate: insert into CART_ITEMS (item_id, cart_id) values (?, ?)
 9Hibernate: insert into CART_ITEMS (item_id, cart_id) values (?, ?)
10Cart ID=3
11Cart1 ID=4
12Item1 ID=3
13Item2 ID=4

您可以很容易地将其与以前的测试程序相关联,因为我们已经配置了双向映射,我们可以保存物品或购物车,映射的数据将自动保存。

休眠多对多映射注释

现在我们已经看到了如何使用hibernate xml配置来配置 多对多 映射,让我们看一个通过注释实现它的例子。我们将使用JPA注释实现单向多对多映射。

Hibernate配置XML文件

我们的基于注释的Hibernate配置文件如下所示。休眠-注解.cfg.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE hibernate-configuration PUBLIC
 3    	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 4    	"https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 5<hibernate-configuration>
 6    <session-factory>
 7    	<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
 8    	<property name="hibernate.connection.password">pankaj123</property>
 9    	<property name="hibernate.connection.url">jdbc:mysql://localhost/TestDB</property>
10    	<property name="hibernate.connection.username">pankaj</property>
11    	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
12
13    	<property name="hibernate.current_session_context_class">thread</property>
14    	<property name="hibernate.show_sql">true</property>
15
16    	<mapping class="com.journaldev.hibernate.model.Cart1" />
17    	<mapping class="com.journaldev.hibernate.model.Item1" />
18    </session-factory>
19</hibernate-configuration>

Hibernate SessionFactory工具类

我们用来创建SessionFactory的工具类如下所示。HibernateAnnotationUtil.java

 1package com.journaldev.hibernate.util;
 2
 3import org.hibernate.SessionFactory;
 4import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 5import org.hibernate.cfg.Configuration;
 6import org.hibernate.service.ServiceRegistry;
 7
 8public class HibernateAnnotationUtil {
 9
10    private static SessionFactory sessionFactory;
11    
12    private static SessionFactory buildSessionFactory() {
13        try {
14            // Create the SessionFactory from hibernate-annotation.cfg.xml
15        	Configuration configuration = new Configuration();
16        	configuration.configure("hibernate-annotation.cfg.xml");
17        	System.out.println("Hibernate Annotation Configuration loaded");
18        	
19        	ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
20        	System.out.println("Hibernate Annotation serviceRegistry created");
21        	
22        	SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
23        	
24            return sessionFactory;
25        }
26        catch (Throwable ex) {
27            System.err.println("Initial SessionFactory creation failed." + ex);
28            ex.printStackTrace();
29            throw new ExceptionInInitializerError(ex);
30        }
31    }
32    
33    public static SessionFactory getSessionFactory() {
34    	if(sessionFactory == null) sessionFactory = buildSessionFactory();
35        return sessionFactory;
36    }
37}

Hibernate多对多映射注释模型类

这是基于注释的映射最重要的部分,让我们首先看看Item表模型类,然后我们将研究Cart表模型类。项目1.java

 1package com.journaldev.hibernate.model;
 2
 3import javax.persistence.Column;
 4import javax.persistence.Entity;
 5import javax.persistence.GeneratedValue;
 6import javax.persistence.GenerationType;
 7import javax.persistence.Id;
 8import javax.persistence.Table;
 9
10@Entity
11@Table(name="ITEM")
12public class Item1 {
13
14    @Id
15    @Column(name="item_id")
16    @GeneratedValue(strategy=GenerationType.IDENTITY)
17    private long id;
18    
19    @Column(name="item_price")
20    private double price;
21    
22    @Column(name="item_desc")
23    private String description;
24    
25// Getter Setter methods
26}

Item1类看起来很简单,这里没有关系映射。Cart1.java

 1package com.journaldev.hibernate.model;
 2
 3import java.util.Set;
 4
 5import javax.persistence.CascadeType;
 6import javax.persistence.Column;
 7import javax.persistence.Entity;
 8import javax.persistence.GeneratedValue;
 9import javax.persistence.GenerationType;
10import javax.persistence.Id;
11import javax.persistence.JoinColumn;
12import javax.persistence.JoinTable;
13import javax.persistence.ManyToMany;
14import javax.persistence.Table;
15
16@Entity
17@Table(name = "CART")
18public class Cart1 {
19
20    @Id
21    @Column(name = "cart_id")
22    @GeneratedValue(strategy = GenerationType.IDENTITY)
23    private long id;
24
25    @Column(name = "cart_total")
26    private double total;
27
28    @ManyToMany(targetEntity = Item1.class, cascade = { CascadeType.ALL })
29    @JoinTable(name = "CART_ITEMS", 
30    			joinColumns = { @JoinColumn(name = "cart_id") }, 
31    			inverseJoinColumns = { @JoinColumn(name = "item_id") })
32    private Set<Item1> items;
33
34//Getter Setter methods
35}

这里最重要的部分是使用ManyToMany注释和JoinTable注释,其中我们提供用于多对多映射的表名和列。

Hibernate多对多注释映射测试程序

下面是一个简单的测试程序,用于我们的基于Hibernate多对多映射注释的配置。HibernateManyToManyAnnotationMain.java

 1package com.journaldev.hibernate.main;
 2
 3import java.util.HashSet;
 4import java.util.Set;
 5
 6import org.hibernate.Session;
 7import org.hibernate.SessionFactory;
 8import org.hibernate.Transaction;
 9
10import com.journaldev.hibernate.model.Cart1;
11import com.journaldev.hibernate.model.Item1;
12import com.journaldev.hibernate.util.HibernateAnnotationUtil;
13
14public class HibernateManyToManyAnnotationMain {
15
16    public static void main(String[] args) {
17    	Item1 item1 = new Item1();
18    	item1.setDescription("samsung"); item1.setPrice(300);
19    	Item1 item2 = new Item1();
20    	item2.setDescription("nokia"); item2.setPrice(200);
21    	Cart1 cart = new Cart1();
22    	cart.setTotal(500);
23    	Set<Item1> items = new HashSet<Item1>();
24    	items.add(item1); items.add(item2);
25    	cart.setItems(items);
26    	
27    	SessionFactory sessionFactory = null;
28    	try{
29    	sessionFactory = HibernateAnnotationUtil.getSessionFactory();
30    	Session session = sessionFactory.getCurrentSession();
31    	Transaction tx = session.beginTransaction();
32    	session.save(cart);
33    	System.out.println("Before committing transaction");
34    	tx.commit();
35    	sessionFactory.close();
36    	
37    	System.out.println("Cart ID="+cart.getId());
38    	System.out.println("Item1 ID="+item1.getId());
39    	System.out.println("Item2 ID="+item2.getId());
40    	
41    	}catch(Exception e){
42    		e.printStackTrace();
43    	}finally{
44    		if(sessionFactory != null && !sessionFactory.isClosed()) sessionFactory.close();
45    	}
46    }
47
48}

当我们执行上面的程序时,它会产生以下输出。

 1Hibernate Annotation Configuration loaded
 2Hibernate Annotation serviceRegistry created
 3Hibernate: insert into CART (cart_total) values (?)
 4Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
 5Hibernate: insert into ITEM (item_desc, item_price) values (?, ?)
 6Before committing transaction
 7Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
 8Hibernate: insert into CART_ITEMS (cart_id, item_id) values (?, ?)
 9Cart ID=5
10Item1 ID=6
11Item2 ID=5

显然,保存购物车也就是将数据保存到Item和Cart_Items表中。如果只保存商品信息,您将注意到没有保存Cart和Cart_Items数据。这就是Hibernate多对多映射示例教程,您可以从下面的链接下载样例项目并尝试了解更多信息。

下载Hibernate ManyToMany映射Project

Published At
Categories with 技术
Tagged with
comments powered by Disqus