This time let’s talk about the hierarchical design of hibernate, which is the design of the inheritance relationship between entities.
Maybe this is more abstract, let's look at the examples directly.
1) Let’s first look at the common practice and directly enter the code: the three real classes are as follows:
public class TItem implements Serializable{ //Omit Get/Set method private int id; private String manufacturing; private String name; } public class TBook extends TItem{ //Omit Get/Set method private int pageCount; } public class TDVD extends TItem{ //Omit Get/Set method private String regionCode; }
Here we need three mapping files, the contents are as follows:
<class name="TItem" table="ITEM"> <id name="id" column="id" type="java.lang.Integer"> <generator /> </id> <property name="name" column="name" type="java.lang.String"/> <property name="manufacture" column="manufacture" type="java.lang.String"/> </class> <class name="TBook" table="Book"> <id name="id" column="id" type="java.lang.Integer"> <generator /> </id> <property name="name" column="name" type="java.lang.String"/> <property name="manufacture" column="manufacture" type="java.lang.String"/> <property name="pageCount" column="pageCount" type="java.lang.Integer"/> </class> <class name="TDVD" table="DVD"> <id name="id" column="id" type="java.lang.Integer"> <generator /> </id> <property name="name" column="name" type="java.lang.String"/> <property name="manufacture" column="manufacture" type="java.lang.String"/> <property name="regionCode" column="regionCode" type="java.lang.String"/> </class>
Very ordinary mapping files, no difference from the previous ones.
Let's write a test method directly:
public void testSelect() { Query query = session.createQuery("from TItem "); List list = query.list(); Iterator iter = list.iterator(); while(iter.hasNext()) { System.out.println("Name:"+((((TItem)iter.next()).getName())); } } Note that here we are using the TItem class, not the specific word class. Here it will automatically look for subclasses inherited from the TItem class and find all results. This involves a polymorphism. The class tag has the property polymorphism, and its default value is implicit, which means that the result can be queryed without specifying a name. If it is explicit, it means that you need to specify a specific class name before you can find the result of this type.
2) In the previous example, we used three mapping files. When we need to modify, we need to modify three mapping files, which is not feasible for large projects. Moreover, each table has corresponding fields for the corresponding main class, which is redundant. So we have the following method.
The entity class is still the same as in 1). We change the mapping file from three to one, and only retain the TItem mapping file. But we need to make corresponding modifications, and the content is now as follows:
<class name="TItem" table="ITEM" polymorphism="explicit"> <id name="id" column="id" type="java.lang.Integer"> <generator /> </id> <property name="name" column="name" type="java.lang.String"/> <property name="manufacture" column="manufacture" type="java.lang.String"/> <joined-subclass name="TBook" table="TBOOK"> <key column="id" /> <property name="pageCount" column="pageCount" type="java.lang.Integer" /> </joined-subclass> <joined-subclass name="TDVD" table="TDVD"> <key column="id"/> <property name="regionCode" column="regionCode" type="java.lang.String"/> </joined-subclass> </class>
Here, we only have a mapping file, but there is a joined-subclass tag, which indicates that this class inherits from the current class, <key> indicates the primary key of the sub-table. Here, the sub-table refers to the two tables corresponding to the sub-classes, TBOOK and TDVD. Only fields in the subtable are specified in property.
In this way, the generated table after we run is as follows:
The table corresponding to the two subclasses is only the fields we specify through property. This avoids multiple fields in the table, so that the word table only maintains its separate fields. When the item class changes, there is no need to make too many modifications.
3) Let’s learn about another method to implement hierarchical design, which is achieved by putting flags into the table. In the hibernate mapping file, we implement it through the descriminator tag.
Without further ado, let's take a look at the example:
We modified the mapping file of yesterday's TItem to:
<class name="TItem" table="ITEM" polymorphism="explicit"> <id name="id" column="id" type="java.lang.Integer"> <generator /> </id> <discriminator column="category" type="java.lang.String"/> <property name="name" column="name" type="java.lang.String"/> <property name="manufacture" column="manufacture" type="java.lang.String"/> </class>
Seeing the middle, we added a discriminator tag, which shows which field our two subclasses are distinguished by.
<subclass name="TBook" discriminator-value="1"> <property name="pageCount" column="pageCount"/> </subclass> <subclass name="TDVD" discriminator-value="2" > <property name="regionCode" column="regionCode"/> </subclass>
We see these two paragraphs, which indicates that when the value of the field specified by the discriminator is 1, it indicates that it is a TBook class and pageCount has a value; when the value of the field specified by the discriminator is 2, it indicates that it is a TDVD class and regionCode has a value.
In this way, we only need to use one table, which indicates the relationship between them and several classes. Note that this method is not good for too many subclasses. It will cause too many fields in the main table and cause certain design inconvenience.