preface

Before we use a table operation, but we can not use only a table in the actual development of… Therefore, this post focuses on associative mapping

Set the mapping

Requirement analysis: When a user purchases a product, the user may have multiple addresses.

The database table

We usually design a database table as shown in the following figure. We usually do not design multiple columns in the User table to hold the address. Each user has a different number of addresses, resulting in data redundancy

  • Create two tables, one for the user and one for the address. Address tables use foreign keys to reference user tables

entity

Since addresses are only held as strings, we can simply use a User object


public class User {
    
    private String id;
    private String username;
    private String password;
    private Set<String> address;

	// Various setters and getters
Copy the code

The mapping file


<?xml version="1.0"? >

      

<! --> < span style = "box-sizing: border-box;
<hibernate-mapping package="zhongfucheng.domain">

    <class name="User" table="user">

        <! -- Primary key mapping -->
        <id name="id" column="id" >
            <generator class="native"/>
        </id>

        <! -- Plain field mapping -->
        <property name="username" column="username"></property>
        <property name="password" column="password"></property>

        <! -- Set: name: name of the Set to be mapped table: to which table (address) the attributes of the Set to be mapped Key: column: Specify the foreign key column in the table (address) Element: Specify other column types of the table to be mapped. -->
        <set name="address" table="address">
            <key column="user_id"></key>
            <element column="addr" type="string"></element>
        </set>


    </class>
</hibernate-mapping>

Copy the code

Testing:


package zhongfucheng.domain;

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

/** * Created by ozc on 2017/5/6. */
public class App {
    public static void main(String[] args) {

        // Create an object

        User user = new User();
        user.setUsername("123");
        user.setPassword("1234");
        user.getAddress().add("Guangzhou");


        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the User mapping file!
        configuration.configure().addClass(User.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        session.save(user);
        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code


List Collection mapping configuration

Now that we know how to configure sets, what about lists?

Think about the difference between a List and a Set… The List collection is ordered, so configure one more column to maintain the order of the data!

        <list name="address" table="address">
            <key column="user_id"></key>

            <! -- Index is the keyword. !!!! cannot be used -->
            <list-index column="indexNum"></list-index>
            <element column="addr" type="string"></element>
        </list>
Copy the code

Map Set mapping configuration

The difference between a Map Collection and a Collection Collection is the key-value pair model.


        <map name="address" table="address">
            <key column="user_id"  ></key>
            <map-key type="string" column="short"></map-key>
            <element type="string" column="addr"></element>
        </map>
Copy the code


One-to-many and many-to-one

Above we explained how the collection map is configured, but can the elements loaded by the collection be objects? Instead of a simple String.. That’s too much! In general, we load collections with objects, not simple strings. If we load collections with multiple types of data, then strings won’t work! .

Needs: Relationships between departments and employees

  • Multiple employees in a department; One to many
  • Multiple employees, belonging to the same department

Designing database tables

The employee table should use a foreign key to remember the department table. In this way, the relationship between employees and departments can be maintained

The design entity

Department entities use a collection to remember all employees, and employees use an object to refer to the department

  • Dept.java
package zhongfucheng.domain;

import java.util.HashSet;
import java.util.Set;

/** * Created by ozc on 2017/5/6. */
public class Dept {
    private int id ;

    private Set<Employee> set = new HashSet<>();

    private String deptName;

    public String getDeptName(a) {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }


    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Set<Employee> getSet(a) {
        return set;
    }

    public void setSet(Set<Employee> set) {
        this.set = set; }}Copy the code
  • Employee.java

package zhongfucheng.domain;

/** * Created by ozc on 2017/5/6. */
public class Employee {


    private int id;
    private String empName;
    private double salary;
    private Dept dept;

    public Dept getDept(a) {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEmpName(a) {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public double getSalary(a) {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary; }}Copy the code

Map analysis

Before we write the mapping configuration file, let’s analyze how to write it. Take the department mapping configuration file as an example…

We now use a Set Set of type employee objects to maintain relationships with employees… Therefore, the following points are needed in the mapping file

  • The name of the mapping collection property (employees)
  • The data table corresponding to the mapping collection (EMPLOYEE)
  • The foreign key field of the corresponding table (dept_id)
  • The element type in the collection (Employee) [From this type, Hibernate can find the mapping file for that type and get the corresponding information!]

Department mapping configuration file


<?xml version="1.0"? >

      

<! --> < span style = "box-sizing: border-box;
<hibernate-mapping package="zhongfucheng.domain">

    <class name="Dept" table="dept">
        <id column="id" name="id">
            <generator class="native">

            </generator>
        </id>
        
        <! -- Plain field mapping -->
        <property name="deptName" column="deptname"></property>

        <! Select * from employee where employee = employee;
        <set  cascade="save-update" name="set" table="employee">

            <! -- Employee foreign key column dept_no-->
            <key column="dept_no"></key>

            <! -- A department corresponds to multiple employees, and the set type is Employee-->
            <one-to-many class="Employee" ></one-to-many>
        </set>
    </class>

</hibernate-mapping>

Copy the code

Employee mapping profile


<?xml version="1.0"? >

      

<! --> < span style = "box-sizing: border-box;
<hibernate-mapping package="zhongfucheng.domain">

    <class name="Employee" table="employee">
        <id column="id" name="id">
            <generator class="native">

            </generator>
        </id>

        <! -- Common field data -->
        <property name="empName" column="empName"></property>
        <property name="salary" column="salary"></property>

        <! Set a foreign key dept_no in the current table
        <many-to-one name="dept" class="Dept" column="dept_no"></many-to-one>
    </class>

</hibernate-mapping>

Copy the code

Test on the side of “one”


package zhongfucheng.domain;

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

/** * Created by ozc on 2017/5/6. */
public class App {
    public static void main(String[] args) {

        // Create an object
        Dept dept = new Dept();
        dept.setDeptName(Development department);

        Employee zs = new Employee();
        zs.setEmpName("Zhang Shan");
        zs.setSalary(1111);
        Employee ls = new Employee();
        ls.setEmpName("Bill");
        ls.setSalary(2222);

        // Add relationships
        dept.getSet().add(zs);
        dept.getSet().add(ls);

        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the User mapping file!
        configuration.configure().addClass(Dept.class).addClass(Employee.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();


        session.save(dept);
        session.save(zs);
        session.save(ls);

        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code

Hibernate executes five SQL statements


Test on the “many” side


package zhongfucheng.domain;

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

/** * Created by ozc on 2017/5/6. */
public class App {
    public static void main(String[] args) {

        // Create an object
        Dept dept = new Dept();
        dept.setDeptName(Development department);

        Employee zs = new Employee();
        zs.setEmpName("Zhang Shan");
        zs.setSalary(1111);
        Employee ls = new Employee();
        ls.setEmpName("Bill");
        ls.setSalary(2222);

        // Maintain the relationship
        zs.setDept(dept);
        ls.setDept(dept);



        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the User mapping file!
        configuration.configure().addClass(Dept.class).addClass(Employee.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();


        session.save(dept);
        session.save(zs);
        session.save(ls);



        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code

Hibernate executes three SQL pieces

One-to-many and many-to-one summaries

In one-to-many and many-to-one relationships, it is best to save data by maintaining the relationship with the many party, which can reduce the generation of update statements and improve hibernate execution efficiency!

  • Configuring one-to-many and many-to-one is called “bidirectional association”
  • Configure only one-to-many, called “one-item one-to-many”
  • Configure many-to-one only, called “single many-to-one”

It is worth noting that: which party is configured, which party has the permission to maintain the association relationship!

  • When I do not configure the employee association in the department, then I cannot get the employee data when I operate the department.

Many-to-many mapping

Requirements: One project is developed by multiple employees, and one employee develops multiple projects

Designing database tables

Generally, for many-to-many mappings, we use an intermediate table to hold their associations….

The design entity

When we design entities, there is usually one JavaBean entity for the core table (the middle table is not the core table), so we will design two JavaBean objects

project.java


package zhongfucheng.many2many;

import java.util.HashSet;
import java.util.Set;

/** * Created by ozc on 2017/5/7. */


public class Project {
    
    private int projectId;
    private String projectName;

    // Use the Set Set to maintain relationships with developer entities
    private Set<Developer> developers = new HashSet<>();

    public int getProjectId(a) {
        return projectId;
    }

    public void setProjectId(int projectId) {
        this.projectId = projectId;
    }

    public String getProjectName(a) {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public Set<Developer> getDevelopers(a) {
        return developers;
    }

    public void setDevelopers(Set<Developer> developers) {
        this.developers = developers; }}Copy the code

developer.java



package zhongfucheng.many2many;

import java.util.HashSet;
import java.util.Set;

/** * Created by ozc on 2017/5/7. */
public class Developer {

    private int developerId;
    private String developerName;

    // Use the Set Set to maintain the relationship with Project
    private Set<Project> projects = new HashSet<>();


    public int getDeveloperId(a) {
        return developerId;
    }

    public void setDeveloperId(int developerId) {
        this.developerId = developerId;
    }

    public String getDeveloperName(a) {
        return developerName;
    }

    public void setDeveloperName(String developerName) {
        this.developerName = developerName;
    }

    public Set<Project> getProjects(a) {
        return projects;
    }

    public void setProjects(Set<Project> projects) {
        this.projects = projects; }}Copy the code

Mapping configuration file

Take the project mapping file as an example: let’s not rush to write, but first analyze the key points…… The following steps are necessary to generate the correct association in a many-to-many mapping:

  • Configure mapping Collection properties (Developers)
  • Intermediate tables corresponding to the mapping collection (developer_project)
  • Foreign key fields for intermediate tables (project_id)
  • Type of collection element (Developer)
  • Additional foreign key fields for intermediate tables (developer_id)

These key steps are required for both Project and Developer mapping files

Project mapping file

<?xml version="1.0"? >

      

<! --> < span style = "box-sizing: border-box;
<hibernate-mapping package="zhongfucheng.many2many">

    <class name="Project" table="Project">

        <! -- Mapping primary key -->
        <id name="projectId" column="projectId">
            <generator class="native"></generator>
        </id>

        <! Mapping common fields -->
        <property name="projectName" column="projectName"></property>


        <! Mapping many-to-many relationships -->
        <! -- Developers for Set -- developer_project
        <set name="developers" table="developer_project">
            <! -- foreign key column corresponding to developer_project table -->
            <key column="project_id"></key>

            <! -- Collection type and another foreign key column for developer_Project table -->
            <many-to-many column="developer_id" class="Developer"></many-to-many>
        </set>

    </class>

</hibernate-mapping>


Copy the code

Developer mapping file


<?xml version="1.0"? >

      

<! --> < span style = "box-sizing: border-box;
<hibernate-mapping package="zhongfucheng.many2many">

    <class name="Developer" table="Developer">

        <! -- Mapping primary key -->
        <id name="developerId" column="developerId">
            <generator class="native"></generator>
        </id>

        <! Mapping common fields -->
        <property name="developerName" column="developerName"></property>


        <! Mapping many-to-many relationships -->
        <! -- Developers for Set -- developer_project
        <set name="projects" table="developer_project">
            <! -- foreign key column corresponding to developer_project table -->
            <key column="developer_id"></key>

            <! -- Collection type and another foreign key column for developer_Project table -->
            <many-to-many column="project_id" class="Project"></many-to-many>
        </set>

    </class>

</hibernate-mapping>

Copy the code

test


package zhongfucheng.many2many;

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

/** * Created by ozc on 2017/5/6. */
public class App2 {
    public static void main(String[] args) {


        /* * * * Project Developer Cao Ji wang Chun OA System Wang Chun Lao Zhang */
        // Create an object
        Developer cj = new Developer();
        Developer wc = new Developer();
        Developer lz = new Developer();
        Project ds = new Project();
        Project oa = new Project();

        // Set the object's data
        cj.setDeveloperName("Cao Ji");
        wc.setDeveloperName("Dream");
        lz.setDeveloperName("Old zhang");

        oa.setProjectName("OA system");
        ds.setProjectName("E-commerce System");

        // Use Project to correlate data [many-to-many, same thing]
        oa.getDevelopers().add(wc);
        oa.getDevelopers().add(lz);

        ds.getDevelopers().add(cj);
        ds.getDevelopers().add(wc);


        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the User mapping file!
        configuration.configure().addClass(Developer.class).addClass(Project.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();


        // Set the cascading in the Project mapping file to save
        session.save(oa);
        session.save(ds);


        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code

Nine SQL statements were executed and the records in the database were correct.


One-to-one mapping

Requirement: User with ID card information.. One user corresponds to one ID card

Database table design

We have two approaches to database table design

  • First: set a foreign key in the ID data table to maintain the relationship between users, this foreign key should also be unique [one user corresponds to one ID]
  • Second: in the id card data table using primary key + foreign key to maintain the relationship between users.

The design entity

idCard.java

package zhongfucheng.one2one;

/** * Created by ozc on 2017/5/7. */
public class IdCard {

    private int idCardId;
    private String idCardName;

    // Maintain relationships with users
    private User user ;

    public int getIdCardId(a) {
        return idCardId;
    }

    public void setIdCardId(int idCardId) {
        this.idCardId = idCardId;
    }

    public String getIdCardName(a) {
        return idCardName;
    }

    public void setIdCardName(String idCardName) {
        this.idCardName = idCardName;
    }

    public User getUser(a) {
        return user;
    }

    public void setUser(User user) {
        this.user = user; }}Copy the code

User.java

package zhongfucheng.one2one;

/** * Created by ozc on 2017/5/7. */
public class User {

    private int userId;
    private String userName;

    // Maintain a one-to-one relationship with id cards
    private IdCard idCard ;

    public int getUserId(a) {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getUserName(a) {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public IdCard getIdCard(a) {
        return idCard;
    }

    public void setIdCard(IdCard idCard) {
        this.idCard = idCard; }}Copy the code

The first way is to map files

There are two ways to design tables in a database to achieve one-to-one relationships. First, let’s pick the familiar foreign key way to write mapping files

User Mapping file


<?xml version="1.0"? >

      

<hibernate-mapping package="zhongfucheng.one2one">

    <class name="User" table="User">

        <! -- Mapping primary key -->
        <id name="userId" column="userId">
            <generator class="native"></generator>
        </id>

        <! Mapping common fields -->
        <property name="userName" column="userName"></property>

        <! Name = idCard type = idCard -->
        <one-to-one name="idCard" class="IdCard"></one-to-one>

    </class>

</hibernate-mapping>

Copy the code

IdCard mapping file


<?xml version="1.0"? >

      

<hibernate-mapping package="zhongfucheng.one2one">

    <class name="IdCard" table="IdCard">

        <! -- Mapping primary key -->
        <id name="idCardId" column="idCardId">
            <generator class="native"></generator>
        </id>

        <! Mapping common fields -->
        <property name="idCardName" column="idCardName"></property>

        <! --idCart is a table with foreign keys. To map fields to foreign keys, use manyToOne-->

        <! Select * from user where username = user; select * from user where username = user; select * from user where username = user;
        <many-to-one name="user" column="user_id" class="User" unique="true" cascade="save-update"></many-to-one>

    </class>

</hibernate-mapping>

Copy the code

test

You use IdCart to maintain User associations.

  • If User is used to maintain the idCart association, the idCart foreign key column is NULL because we did not assign it to the end
  • While using IdCart to maintain a User, the foreign key value is generated based on the User’s primary key ID


package zhongfucheng.one2one;

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

/** * Created by ozc on 2017/5/6. */
public class App3 {
    public static void main(String[] args) {

        // Create an object
        User user = new User();
        IdCard idCard = new IdCard();

        // Set the object's data
        user.setUserName("Hello");
        idCard.setIdCardName("Id Card 001");

        // One-to-one associative data
        idCard.setUser(user);

        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the User mapping file!
        configuration.configure().addClass(User.class).addClass(IdCard.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        // Save the data of the object. The idCard configuration file is saved in cascades
        session.save(idCard);

        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code


The second way is to map files

Since IdCart uses userId as the primary key, you need to configure an additional attribute userId in the JavaBean… Nothing else needs to change


    private int userId;
    public int getUserId(a) {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }
Copy the code

There is a foreign property under the generator node that was left unexplained in Hibernate introduction configuration… Now to fill in the hole..

IdCard mapping file

The idCart mapping file is mainly used to map the primary key to a foreign key, which requires the use of foreign attribute values

use<one-to-one>Tag to configure mappings based on primary keys


<?xml version="1.0"? >

      

<hibernate-mapping package="zhongfucheng.one2one2.one2one">

    <class name="IdCard" table="IdCard">

        <! -- Mapping primary key -->
        <id name="userId" column="userId">
            <! Foreign key (user); foreign key (user);
            <generator class="foreign">
                <param name="property">user</param>
            </generator>
        </id>

        <! Mapping common fields -->
        <property name="idCardName" column="idCardName"></property>
        <property name="idCardId" column="idCartId"></property>



        <! Constrained on primary key mapping, use oneToOne constrained="true"
        <one-to-one name="user" class="User" constrained="true"></one-to-one>




    </class>

</hibernate-mapping>

Copy the code

User Mapping file


<?xml version="1.0"? >

      

<hibernate-mapping package="zhongfucheng.one2one2.one2one">

    <class name="User" table="User">

        <! -- Mapping primary key -->
        <id name="userId" column="userId">
            <generator class="native"></generator>
        </id>

        <! Mapping common fields -->
        <property name="userName" column="userName"></property>

        <! Name = idCard type = idCard -->
        <one-to-one name="idCard" class="IdCard"></one-to-one>

    </class>

</hibernate-mapping>

Copy the code

test


package zhongfucheng.one2one2.one2one;

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

/** * Created by ozc on 2017/5/6. */
public class App4 {
    public static void main(String[] args) {

        // Create an object
        User user = new User();
        IdCard idCard = new IdCard();

        // Set the object's data
        user.setUserName("Hello 3");
        idCard.setIdCardName("Identity Card 003");
        idCard.setIdCardId(4235);

        // One-to-one associative data
        idCard.setUser(user);

        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the User mapping file!
        configuration.configure().addClass(User.class).addClass(IdCard.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        // Save the data of the object. The idCard configuration file is saved in cascades
        session.save(idCard);

        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code

The component map

Java’s main classes come in two main ways

  • Composition relationships, which correspond to component mappings
  • Inheritance relation, inheritance relation corresponds to inheritance mapping

Component mapping is actually mapping the data of a composite relationship into a table, and the component classes and the contained component classes into a table

Sometimes, the relationship between two classes is obviously not inherited, but the two classes are so close that one class needs to use the other class… Then define a variable in a class to maintain the relationship of another class, this is called a combinatorial relationship!

Needs: Cars and wheels. Cars need wheels, but the father of wheels couldn’t be a car, could he?

Design database

The design entity

Wheel.java


public class Wheel {
    
    private int  count;
    private int size;

    public int getCount(a) {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getSize(a) {
        return size;
    }

    public void setSize(int size) {
        this.size = size; }}Copy the code

Car. Java, using variables to maintain Wheel

package zhongfucheng.aa;

/** * Created by ozc on 2017/5/7. */
public class Car {

    private int id;
    private String name;
    private Wheel wheel;

    public Wheel getWheel(a) {
        return wheel;
    }

    public void setWheel(Wheel wheel) {
        this.wheel = wheel;
    }

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name; }}Copy the code

The mapping table

A new tag < Component > is used, the component mapping tag.


<?xml version="1.0"? >

      

<hibernate-mapping package="zhongfucheng.aa" >

    <class name="Car" table="Car" >

        <! -- Mapping primary key -->
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>

        <! Mapping common fields -->
        <property name="name" column="name" ></property>


        <! Mapping component fields -->
        <component name="wheel">
            <property name="count"></property>
            <property name="size"></property>
        </component>

    </class>

</hibernate-mapping>

Copy the code

test

package zhongfucheng.aa;

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

/** * Created by ozc on 2017/5/6. */
public class App5 {
    public static void main(String[] args) {


        // Create an object
        Wheel wheel = new Wheel();
        Car car = new Car();

        // Set the properties
        wheel.setCount(43);
        wheel.setSize(22);
        car.setName("BMW");

        // Maintain the relationship
        car.setWheel(wheel);
        // Get the load configuration management class
        Configuration configuration = new Configuration();

 
        configuration.configure().addClass(Car.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        session.save(car);

        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code

Traditional inheritance

Needs: animals, cats, monkeys. Cats inherit from animals

The traditional way of inheritance is to write as many configuration files as there are subclasses.

Table structure

Our table should look like this: ID and name inherit from Animal, catchMouse is the concrete behavior of the subclass.

entity

Animal.java


package zhongfucheng.aa;

/ / animal
public abstract class Animal {

	private int id;
	private String name;
	
	
	public int getId(a) {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName(a) {
		return name;
	}
	public void setName(String name) {
		this.name = name; }}Copy the code

Cat. Java inherits Animail


package zhongfucheng.aa;

public class Cat extends Animal{

	/ / catch mice
	private String catchMouse;

	public String getCatchMouse(a) {
		return catchMouse;
	}

	public void setCatchMouse(String catchMouse) {
		this.catchMouse = catchMouse; }}Copy the code

The mapping file

Simple inherited mapping files are easy to write. In terms of properties, write the attributes of the parent class directly.

But there is a fatal drawback: if you have many subclasses, you need to write a lot of configuration files


<?xml version="1.0"? >

      

<hibernate-mapping package="zhongfucheng.aa" >

    <class name="Cat" table="cat" >

        <! -- Mapping primary key -->
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>

        <! -- Mapping common field parent class attributes directly reference line, such as the name attribute, directly write line! -->
        <property name="name" column="name" ></property>
        <property name="catchMouse" column="catchMouse" ></property>


    </class>

</hibernate-mapping>

Copy the code

test


package zhongfucheng.aa;

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

public class App5 {
    public static void main(String[] args) {


        // Create an object
        Cat cat = new Cat();

        // Set the properties

        cat.setName("Big Cat");
        cat.setCatchMouse("Catch a rat.");

        // Get the load configuration management class
        Configuration configuration = new Configuration();

    
        configuration.configure().addClass(Cat.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        session.save(cat);
		
		// If the Animal parent receives data, it needs to give the full name of Anmail


        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code


Map all subclasses to a table

Each subclass needs to be written as a configuration file, mapped to a table…

If the subclass structure is very simple, only a few more attributes than the parent class. As in the above example… We can map all subclasses into a table

However, this is not in accordance with the database design specification….. Because the data in the table ** could be a cat, could be a monkey… ** This is clearly inappropriate…

Since there may be cats in the table, there may be monkeys, in order to distinguish what type. We need to use a discriminator

Let’s see…

The data table

entity

The entity is the same as above, only one more monkey entity table

Monkey.java


public class Monkey extends Animal {
	
	/ / to eat bananas
	private String eatBanana;

	public String getEatBanana(a) {
		return eatBanana;
	}

	public void setEatBanana(String eatBanana) {
		this.eatBanana = eatBanana; }}Copy the code

The mapping file

The subClass node and the discriminator are used

<?xml version="1.0"? >

      

<! All subclasses map to a table -->
<hibernate-mapping package="cn.itcast.e_extends2">
	
	<class name="Animal" table="t_animal">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<! -- Specify discriminator field (distinguish different subclasses) -->
		<discriminator column="type_"></discriminator>
		
		<property name="name"></property>
		
		<! Note: The discriminator field must be specified, otherwise an error will be reported! Discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator field: discriminator value="cat_"
		 <subclass name="Cat" discriminator-value="cat_">
		 	<property name="catchMouse"></property>
		 </subclass>
		 
		 <! -- Subclass: Monkey -->
		  <subclass name="Monkey" discriminator-value="monkey_">
		  	<property name="eatBanana"></property>
		  </subclass>
		
	</class>
	

</hibernate-mapping>

Copy the code

test

I’m loading a mapping file for the Animal parent. Save cat and monkey.


package zhongfucheng.aa;

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

public class App5 {
    public static void main(String[] args) {


        // Create an object
        Cat cat = new Cat();
        Monkey monkey = new Monkey();

        // Set the properties
        cat.setName("Big Cat");
        cat.setCatchMouse("Little Mouse");
        monkey.setEatBanana("Eat a banana");
        monkey.setName("Big Monkey");

        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load Animal mapping file!
        configuration.configure().addClass(Animal.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        session.save(cat);
        session.save(monkey);

        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code


Map one table per class (3 tables)

Each parent class and child class corresponds to a table. So there are three tables

This structure looks completely object-oriented, but the structure between tables can be complex, requiring two SQL statements to insert a subclass of information

Data table design

The mapping file

Using the<joined-subclass >This node

<?xml version="1.0"? >

      


<hibernate-mapping package="zhongfucheng.aa">

    <class name="Animal" table="t_animal">
        <id name="id">
            <generator class="native"></generator>
        </id>

        <property name="name"></property>


        <! < Animal > < Animal > < Animal > < Animal > < Animal > < Animal >
        <joined-subclass name="Cat" table="cat_">
            <! Key = foreign key ();
            <key column="animal_id"></key>
            <property name="catchMouse"></property>
        </joined-subclass>

        <joined-subclass name="Monkey" table="monkey_">
            <! Key = foreign key ();
            <key column="animal_id"></key>
            <property name="eatBanana"></property>
        </joined-subclass>


    </class>


</hibernate-mapping>



Copy the code

test

package zhongfucheng.aa;

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

public class App5 {
    public static void main(String[] args) {


        // Create an object
        Cat cat = new Cat();
        Monkey monkey = new Monkey();

        // Set the properties
        cat.setName("Big Cat");
        cat.setCatchMouse("Little Mouse");
        monkey.setEatBanana("Eat a banana");
        monkey.setName("Big Monkey");

        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the mapping file corresponding to the class!
        configuration.configure().addClass(Animal.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        session.save(cat);
        session.save(monkey);

        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code

Two SQL statements are required for each subclass object saved!


(Recommended) Each subclass maps a table, the parent class does not correspond to the table (2 tables)

  • A single table was used to hold data for all subclasses, which is not consistent with the database design specification
  • Each subclass, parent class has a table.. Table structure too cumbersome.. Too much SQL when adding information

What we are going to use is: each subclass maps to a table, and the parent class does not map to the table… It’s the same way we inherited in the traditional way. We just use the

node in the hbm.xml file. Thanks to this node, we don’t need to write a configuration file for each subclass.

Database table design

The mapping file

  • If you want the parent class not to map to a database table, you simply configure it as Abstract in class
  • With the union-subclass node, the primary key cannot grow automatically. We can just change it to UUID. Of course, the corresponding entity ID type should be String

<?xml version="1.0"? >

      


<hibernate-mapping package="zhongfucheng.aa">

    
    <! -- Want the parent class not to map to a table, set it to abstract -->
    <class name="Animal" abstract="true">
        
        <! Union-subclass = union-subclass = union-subclass = union-subclass = union-subclass
        <id name="id">
            <generator class="uuid"></generator>
        </id>

        <property name="name"></property>


        <! Map all subclass information to a table giving the name of the attribute corresponding to the common field of the database table -->
        <union-subclass name="Cat" table="cat_">
            <property name="catchMouse"></property>
        </union-subclass>
        
        <union-subclass name="Monkey" table="monkey_">
            <property name="eatBanana"></property>
        </union-subclass>


    </class>


</hibernate-mapping>

Copy the code

test


package zhongfucheng.aa;

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

public class App5 {
    public static void main(String[] args) {


        // Create an object
        Cat cat = new Cat();
        Monkey monkey = new Monkey();

        // Set the properties
        cat.setName("Big Cat");
        cat.setCatchMouse("Little Mouse");
        monkey.setEatBanana("Eat a banana");
        monkey.setName("Big Monkey");

        // Get the load configuration management class
        Configuration configuration = new Configuration();

        // Load the mapping file corresponding to the class!
        configuration.configure().addClass(Animal.class);

        // Create a Session factory object
        SessionFactory factory = configuration.buildSessionFactory();

        // Get the Session object
        Session session = factory.openSession();

        // If you use Hibernate to operate a database, you need to start a transaction and get the transaction object
        Transaction transaction = session.getTransaction();

        // Start the transaction
        transaction.begin();

        session.save(cat);
        session.save(monkey);

        // Commit the transaction
        transaction.commit();

        / / close the Sessionsession.close(); }}Copy the code

Component mapping and inheritance mapping summaries

Since our traditional inheritance map has a configuration file for each subclass, this is cumbersome. Therefore, **.hbm. XML gives several nodes for us to use **, including the following:

  • The subclass parent class shares one tablesubclass
    • Does not comply with database design specifications
    • You need to use a discriminator
  • Subclasses and superclasses have their own tablesjoined-subclassSo there are three tables
    • The structure of the table is too cumbersome
    • At least two sets of SQL are required to generate SQL when inserting data
  • The subclass has its own table, and the parent class does not correspond to the table.union-subclass
    • The parent class does not correspond to the table to be decorated with abstract
    • The primary key ID cannot use the autogrowth policy, change to UUID. The JavaBean id is set to String

If the article has the wrong place welcome to correct, everybody exchanges with each other. Students who are used to reading technical articles on wechat and want to get more Java resources can follow the wechat public account :Java3y