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 table
subclass
- Does not comply with database design specifications
- You need to use a discriminator
- Subclasses and superclasses have their own tables
joined-subclass
So 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