Hibernate Learning Notes 7 (Configuration and Operation of One-to-Many Relations)

Relationships between database tables and tables

This one was written in mysql, and here it is written again at https://blog.csdn.net/qq_40817827/article/details/90637303.

  • One-to-many relationship

    • What kind of relationship belongs to one-to-many?
      A Department corresponds to multiple employees, and an employee can only belong to one department.
      A customer corresponds to multiple contacts, and a contact can only belong to one customer.
    • One-to-many tabulation principle:
  • Many-to-many relationship

    • What kind of relationship belongs to many-to-many?
      One student can choose many courses, and one course can also be chosen by many students.
      A user can choose multiple roles, and a role can also be selected by multiple users.
    • The principle of multi-to-many table building is as follows:
  • One-to-one relationship

    • What kind of relationship belongs to one-to-one?
      A company can only have one registration address, and a registration address can only be registered by one company.
    • One-to-one construction principle:

Hibernate one-to-many relationship configuration

1. Create projects and introduce jar packages
2. Creating databases and tables

CREATE TABLE `cst_customer` (
  `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'Customer Number(Primary key)',
  `cust_name` varchar(32) NOT NULL COMMENT 'Customer Name(Corporate name)',
  `cust_source` varchar(32) DEFAULT NULL COMMENT 'Customer Information Sources',
  `cust_industry` varchar(32) DEFAULT NULL COMMENT 'Customer Information',
  `cust_level` varchar(32) DEFAULT NULL COMMENT 'Customer Level',
  `cust_phone` varchar(64) DEFAULT NULL COMMENT 'Fixed telephone',
  `cust_mobile` varchar(16) DEFAULT NULL COMMENT 'Mobile phone',
  PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `cst_linkman` (
  `lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'Contact Number(Primary key)',
  `lkm_name` varchar(16) DEFAULT NULL COMMENT 'Name of contact person',
  `lkm_cust_id` bigint(32) DEFAULT NULL COMMENT 'Customer id',
  `lkm_gender` char(1) DEFAULT NULL COMMENT 'Contact Gender',
  `lkm_phone` varchar(16) DEFAULT NULL COMMENT 'Contact office telephone',
  `lkm_mobile` varchar(16) DEFAULT NULL COMMENT 'Cell Phone',
  `lkm_email` varchar(64) DEFAULT NULL COMMENT 'Contact mailbox',
  `lkm_qq` varchar(16) DEFAULT NULL COMMENT 'Contacts qq',
  `lkm_position` varchar(16) DEFAULT NULL COMMENT 'Contact Title',
  `lkm_memo` varchar(512) DEFAULT NULL COMMENT 'Contact Remarks',
  PRIMARY KEY (`lkm_id`),
   KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),
  CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;



3. Creating Entities

An entity of one party, a collection of more than one party.

public class Customer {
	private Long cust_id;
	private String cust_name;
	private String cust_source;
	private String cust_industry;
	private String cust_level;
	private String cust_phone;
	private String cust_mobile;
	//Represented by ORM; one customer corresponds to multiple contacts
	//Hibernate defaults to Set collections for multiple-party collections placed
	private Set<LinkMan> LinkMans = new HashSet<LinkMan>();
	

Multi-party entity, one-party object placed

public class LinkMan {
	private Long lkm_id;
	private String lkm_name;
	private String lkm_cust_id;
	private String lkm_gender;
	private String lkm_phone;
	private String lkm_mobile;
	private String lkm_email;
	private String lkm_qq;
	private String lkm_position;
	private String lkm_memo;
	//Represented by ORM: A contact can only belong to one customer
	//Placing objects on one side
	private Customer customer;

4 Create mapping files

  • The Creation of Mapping of Multiple Parties
<?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="domain.LinkMan"  table="cst_linkman">
    <! - Establish OID and Primary Key Mapping - >
    <id name="lkm_id" column="lkm_id" >
    <! - Primary Key Generation Strategy - >
    <generator class="native"/>
    </id>
    <! - Establish mapping between common attributes and table fields - >
      <property name="lkm_name"  />
		<property name="lkm_gender"  />
		<property name="lkm_phone" />
		<property name="lkm_mobile" />
		<property name="lkm_email" />
		<property name="lkm_qq" /> 
        <property name="lkm_position" /> 
        <property name="lkm_memo" /> 
   		<! - Configuring a many-to-one relationship: Placing objects on one side - >
   		<!-- 
   			many-to-one tag
   			* Name: The property name of an object on one side
   			* Class: The full path of a party's class
   			* column: The name of the foreign key of a table on more than one side
   		 -->
   		 <many-to-one name="customer" class="domain.Customer" column="lkm_cust_id"/>
    </class>
    </hibernate-mapping>
  • The Creation of Mapping of One Party
<?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>
	<! - Establish a mapping between classes and tables - >.
<class name="domain.Customer.java" table="cst_customer">
<! -- Establish the correspondence between the attributes in the class and the primary keys in the table - >
<id name="cust_id" column="cust_id" >
<! - Primary Key Generation Strategy - >
			<generator class="native"/>
</id>
<! - Establish mapping between common attributes and fields in database tables - >
		<property name="cust_name" column="cust_name"  />
		<property name="cust_source" column="cust_source" />
		<property name="cust_industry" column="cust_industry"/>
		<property name="cust_level" column="cust_level"/>
		<property name="cust_phone" column="cust_phone"/>
		<property name="cust_mobile" column="cust_mobile"/>
		 <! - Configure one-to-many mapping: a set of mu lt iple parties placed - >.
		 Set tag name: attribute name of a collection of objects of more than one party - > Set tag name
		 <set name="linkMans">
		 Key tag column: the foreign key name of more than one party - >
		 <key column="lkm_cust_id"/>
		 <! - one-to-man label class: the full path of a class of more than one party - > 1.
		 <one-to-many class="domain.LinkMan"/>
		 </set>
</class>
</hibernate-mapping>

5. Creating Core Configuration
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>
	 		<!-- Basic parameters for connecting database -->
	 		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
	 		<property name="hibernate.connection.url">jdbc:mysql:///hibernateday02</property>
		    <property name="hibernate.connection.username">root</property>
		    <property name="hibernate.connection.password">root</property>
		<!-- To configure Hibernate Dialect -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<!-- Optional configuration================ -->
		<!-- Printing SQL -->
		<property name="hibernate.show_sql">true</property>
		<!-- Format SQL -->
		<property name="hibernate.format_sql">true</property>
        <!-- Automatically create tables -->
		<property name="hibernate.hbm2ddl.auto">update</property>
		
		
		<!-- To configure C3P0 Connection pool -->
		<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
		<!--Minimum number of database connections available in connection pool -->
		<property name="c3p0.min_size">5</property>
		<!--Maximum number of database connections in connection pool  -->
		<property name="c3p0.max_size">20</property>
		<!--Setting the expiration time of database connection,In seconds,
		If a database connection in the connection pool is idle longer than timeout time,It will be cleared from the connection pool -->
		<property name="c3p0.timeout">120</property>
		 <!--Check free connections in all connection pools every 3000 seconds in seconds-->
		<property name="c3p0.idle_test_period">3000</property>
		<!-- Setting transaction isolation level -->
		<property name = "hibernate.connection.isolation">4</property>
		<!-- Configuring the current thread-bound Session -->
		<property name="hibernate.current_session_context_class">thread</property>
		<!-- Introducing mapping -->
		<mapping resource="domain/Customer.hbm.xml"/>
		<mapping resource="domain/LinkMan.hbm.xml"/>
		</session-factory>
	</hibernate-configuration>

6. Introducing Tool Classes

package hibernateUtils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/*
 * 
 * Hibernate Tool class
 * 
 * 
 */

public class HibernateUtils {
	public static final Configuration cfg;
	public static final SessionFactory sf;
	
	static {
		cfg=new Configuration().configure();
		sf=cfg.buildSessionFactory();
	}
	
	public static Session openSession() {
		return sf.openSession();
	}
	public static Session getCurrentSession() {
		return sf.getCurrentSession();
		
	}
	
	
}

7. Test class

package demo1;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import domain.Customer;
import domain.LinkMan;
import hibernateUtils.HibernateUtils;

/**
 * 
 * One-to-many test classes
 * 
 * 
 * @author ASUS
 *
 */
public class HibernateDemo1 {
@Test
//Save two customers and three contacts
public void demo1() {
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	//Create two customers
	Customer customer1 = new Customer();
	customer1.setCust_name("Zhang Er");
	Customer customer2 = new Customer();
	customer2.setCust_name("Zhang San");
	
	//Create three contacts
	LinkMan linkman1 = new LinkMan();
	linkman1.setLkm_name("Sun Yi");
	LinkMan linkman2 = new LinkMan();
	linkman2.setLkm_name("Sun er");
	LinkMan linkman3 = new LinkMan();
	linkman3.setLkm_name("Sun San");
	
	//set relationship
	linkman1.setCustomer(customer1);
	linkman2.setCustomer(customer1);
	linkman3.setCustomer(customer2);
	
	//Save data
	session.save(customer1);
	session.save(customer2);
	session.save(linkman1);
	session.save(linkman2);
	session.save(linkman3);
	
	tx.commit();
}
}


You can see that the data has been inserted into the database

A pair of multicorrelation operations in Hibernate

1. Is it okay to save only one side of a one-to-many relationship?

@Test
public void demo2() {
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	Customer customer = new Customer();
	customer.setCust_name("Flowery");
	
	LinkMan linkMan = new LinkMan();
	linkMan.setLkm_name("Years");
	customer.getLinkMans().add(linkMan);
	linkMan.setCustomer(customer);
	//Is it okay to save only one side, or not, to report an instantaneous object exception: a persistent object associates a transient object
	//session.save(customer);
	session.save(linkMan);
	
	tx.commit();
}


Instantaneous object anomaly
Customer is instantaneous, sava() becomes persistent, but the contact is instantaneous, and then the customer is associated with it, and now the customer can't be saved.

2. One-to-many cascade operation

  • What is cascade operation?
    Cascade refers to whether other related objects will be manipulated when one object is manipulated.
  • Cascade is directional
    When operating one party, whether to operate more than one party
    Whether to operate to one side when operating more than one side

3. Cascade save or update

  • Save customer cascade contacts
@Test
/*
 * Cascade save or update operation
 * Save customer cascade contacts, the main body of operation is the customer object, which needs to be configured in Customer.hbm.xml
 *  <set name="linkMans" cascade="save-update">
 * 
 */
public void demo3() {
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	Customer customer = new Customer();
	customer.setCust_name("Flowery");
	
	LinkMan linkMan = new LinkMan();
	linkMan.setLkm_name("Years");
	customer.getLinkMans().add(linkMan);
	linkMan.setCustomer(customer);
	//Is it okay to save only one side, or not, to report an instantaneous object exception: a persistent object associates a transient object
	session.save(customer);
	//session.save(linkMan);
	
	tx.commit();
}
  • Keep Contacts Cascade Customers
/*
 * Cascade save or update operation
 * The main body of the operation is the contact object, which needs to be configured in LinkMan.hbm.xml.
 *  <many-to-one name="customer" cascade="save-update" class="domain.Customer" column="lkm_cust_id"/>
 */
@Test
public void demo4() {
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	Customer customer = new Customer();
	customer.setCust_name("Ruhua 2");
	
	LinkMan linkMan = new LinkMan();
	linkMan.setLkm_name("Years 2");
	customer.getLinkMans().add(linkMan);
	linkMan.setCustomer(customer);
	//Is it okay to save only one side, or not, to report an instantaneous object exception: a persistent object associates a transient object
	//session.save(customer);
	session.save(linkMan);
	
	tx.commit();
}



4. Test Object Navigation

/*
 
 * Navigation of Test Objects
 * Prerequisite: cascade="save-uodate" is set on both sides of one-to-many
 * 
 */
@Test
public void demo5() {
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	Customer customer = new Customer();
	customer.setCust_name("Ruhua 3");
	
	LinkMan linkMan1 = new LinkMan();
	linkMan1.setLkm_name("Years 3");
	LinkMan linkMan2 = new LinkMan();
	linkMan2.setLkm_name("Years 4");
	LinkMan linkMan3 = new LinkMan();
	linkMan3.setLkm_name("Years 5");
	
	linkMan1.setCustomer(customer);
	customer.getLinkMans().add(linkMan2);
	customer.getLinkMans().add(linkMan3);
	
	//Both sides have cascade s
	//session.save(linkMan1); // Sends several insert statements with four
	//First, save contact 1, enter the database, one, contact 1 and related customers, customers enter, two, customers bring in 2.3. A total of 4.
	session.save(customer);//Send several three customers and two associated contacts
	session.save(linkMan2);//Send several pieces of data, one piece
	
	tx.commit();
}

Insert 4, the same after

5. Cascade deletion
When one side is deleted, the other side's data is deleted at the same time.

  • Delete Customer Cascade Delete Contacts
@Test
/*
 * 
 * cascading deletion
 * Delete the customer cascade delete contacts, delete the theme is the customer, need to configure in Customer.hbm.xml
 * 
 * 
 * 
 * Delete customers, cascade delete contacts, delete contacts before, jdbc can not be deleted, but hibernate can
 *  <set name="linkMans" cascade="save-update,delete">
 */
public void demo6() {
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	//No cascade deletion is set. By default, modify the contact's foreign key and delete the customer.
	//Customer customer = session.get(Customer.class,1l);
	//session.delete(customer);
	
	//Delete customers and contacts
	Customer customer = session.get(Customer.class,1l);
	session.delete(customer);
	
	tx.commit();

}
  • Delete Contacts Cascade Delete Clients (Basically Not Used)
@Test
/*
 * Cascade deletion: delete contacts cascade delete customers, delete the principal is contacts, need to be configured in LinkMan.hbm.xml
 * many-to-one name="customer" cascade="delete" 
 * 
 * 
 */
public void demo7(){
	
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	//Delete customers and contacts
	LinkMan linkman = session.get(LinkMan.class, 3l);
	session.delete(linkman);
	
	tx.commit();
	
}

6. One-to-many sets up two-way association to generate redundant sql statements

  • Resolve redundant SQL statements
    One-way maintenance:
    Cause one party to abandon the right of foreign key protection:
    One side gives up. Configure inverse="true" on set
    When modifying one-to-many associated queries.

7. Distinguish cascade from inverse

@Test
/*Distinguishing the difference between cascade and inverse 
 * 
 */
public void demo9() {
	Session session = HibernateUtils.getCurrentSession();
	Transaction tx = session.beginTransaction();
	
	Customer customer = new Customer();
	customer.setCust_name("Li Bing");
	
	LinkMan linkman = new LinkMan();
	linkman.setLkm_name("Miss Luo Yu Feng");
	
	customer.getLinkMans().add(linkman);
	//The condition is that the set of Customer.hbm.xml is configured with cascade="save-update" inverse="true"
	
	session.save(customer);//Customers and contacts will be inserted into the database, but the foreign key null
	
	tx.commit();
}

Keywords: Session Hibernate xml Database

Added by griffith on Fri, 02 Aug 2019 06:30:39 +0300