ç¶æ¿ã¯ãOOPã®äž»èŠãªååã®1ã€ã§ãã åæã«ãããªãã®æ°ã®ãšã³ã¿ãŒãã©ã€ãºã¢ããªã±ãŒã·ã§ã³ããªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ã«åºã¥ããŠããŸãã
ãªããžã§ã¯ãæåã¢ãã«ãšãªã¬ãŒã·ã§ãã«ã¢ãã«ã®äž»ãªççŸã¯ããªããžã§ã¯ãã¢ãã«ã2çš®é¡ã®ãªã¬ãŒã·ã§ã³ïŒãis aã-ãisãããã³ãhas aã-ãhasãïŒããµããŒãããSQLããŒã¹ã®ã¢ãã«ããªã¬ãŒã·ã§ã³ã®ã¿ããµããŒãããããšã§ãã ãæã£ãŠãããã
ã€ãŸãã
SQLã¯åã®ç¶æ¿ãç解ããããµããŒãããŸãã ã
ãããã£ãŠããšã³ãã£ãã£ãšããŒã¿ããŒã¹ã¹ããŒããæ§ç¯ãã段éã§ãéçºè
ã®äž»ãªã¿ã¹ã¯ã®1ã€ã¯ãç¶æ¿éå±€ãè¡šãããã®æé©ãªæŠç¥ãéžæããããšã§ãã
次ã®4ã€ã®æŠç¥ããããŸãã
1ïŒã¯ã©ã¹ããšã«1ã€ã®ããŒãã«ã䜿çšããããã©ã«ãã®ããªã¢ãŒãã£ãã¯åäœã䜿çšããŸãã
2ïŒç¹å®ã®ã¯ã©ã¹ããšã«1ã€ã®ããŒãã«ãSQLã¹ããŒãããããªã¢ãŒãã£ãºã ãšç¶æ¿é¢ä¿ãå®å
šã«é€å€ããŸãïŒå®è¡æã®ããªã¢ãŒãã£ãã¯ãªåäœã«ã¯ãUNIONã¯ãšãªã䜿çšãããŸãïŒ
3ïŒã¯ã©ã¹ã®éå±€å
šäœã®åäžã®ããŒãã«ã SQLã¹ããŒãã®éæ£èŠåã«ãã£ãŠã®ã¿å¯èœã§ãã æååãåºå¥ããããšã«ãããã¹ãŒããŒã¯ã©ã¹ãšãµãã¯ã©ã¹ãå®çŸ©ããããšãã§ããŸãã
4ïŒãµãã¯ã©ã¹ããšã«1ã€ã®ããŒãã«ããªã¬ãŒã·ã§ã³ãis aãã¯ãhas aããšããŠè¡šãããŸãã -JOINã䜿çšããå€éšãââãŒéä¿¡ã
éžæããæŠç¥ã«ãã£ãŠåœ±é¿ãåããäž»ãªèŠå ã¯3ã€ãããŸãã
1ïŒããã©ãŒãã³ã¹ïŒãhibernate_show_sqlãã䜿çšããŠãããŒã¿ããŒã¹ã«å¯Ÿãããã¹ãŠã®ã¯ãšãªã衚瀺ããã³è©äŸ¡ããŸãïŒ
2ïŒã¹ããŒã ã®æ£èŠåãšããŒã¿ã®æŽåæ§ã®ä¿èšŒïŒãã¹ãŠã®æŠç¥ãNOT NULLå¶çŽãžã®æºæ ãä¿èšŒããããã§ã¯ãããŸããïŒ
3ïŒåè·¯ãé²åãããèœå
ã«ããã®äžã§ããããã®æŠç¥ã®ããããã詳现ã«æ€èšãããå©ç¹ãšæ¬ ç¹ã瀺ããç¹å®ã®ã±ãŒã¹ã§ã®æŠç¥ã®éžæã«é¢ããæšå¥šäºé
ã瀺ãããŸãã
äœè
ããã®ããã€ãã®èšèãšäŸã®æäœæé ãã®èšäºã¯ããJava Persistance with Hibernateããšããæ¬ããã®æç²ã§ãã èè
-Hibernateãããžã§ã¯ãGaââvin KingïŒGavin KingïŒã®åµèšè
ã§ãããHibernateéçºããŒã Christian BauerïŒChristian BauerïŒã®ã¡ã³ããŒã
2017幎ã®å€ã«ããã·ã¢èªã§ç¿»èš³ããã³å
¬éãããŸããã
çŽ æã®ãã¬ãŒã³ããŒã·ã§ã³ãç°¡çŽ åãããšãšãã«ãäŸã䜿ã£ãŠäœæ¥ãè©Šã¿ãŸããã éå§ããã®ã«1æéæ··ä¹±ããå¿
èŠãããäŸã«åŒ·ãå«æªæãèŠããã®ã§ããã®èšäºã§ã¯ã§ããéã䟿å©ã«äœæ¥ã§ããããã«ããŸããã
-IDEã«ã³ããŒã§ãããã¹ãŠã®Javaã³ãŒãã ããæŠç¥ããå¥ã®æŠç¥ã«ç§»è¡ããéã®Javaã³ãŒããžã®ãã¹ãŠã®å€æŽã¯ãã¿ãã¬ã§ç€ºããããããæ°ããæŠç¥ã«åãæ¿ãããšãå€ãã¯ã©ã¹ã³ãŒããç°¡åã«åé€ããŠãæ°ããã¯ã©ã¹ã³ãŒããã³ããŒã§ããŸãã Mainã¯ã©ã¹ãšHibernateUtilã¯ã©ã¹ã¯å€æŽãããã«æ®ãããã¹ãŠã®äŸãæ€èšãããšãã«æ©èœããŸãã
-åæŠç¥ã®ãã¿ãã¬ã«ã¯ããã¹ãŠã®ããŒã¿ããŒã¹ããŒãã«ãäœæããããã®ã¹ã¯ãªããããããŸãã ãããã£ãŠã次ã®æŠç¥ãæ€èšããåŸããã¹ãŠã®ããŒãã«ãåé€ã§ããŸãã次ã®ã»ã¯ã·ã§ã³ã§ã¯ãæ°ããããŒãã«ãäœæããããã®å®éã®ã¹ã¯ãªãããèŠã€ããŸãã
Java 1.7ãHibernate5ããã³PostgreSQL9ã䜿çšããŠèšè¿°ãããã³ãŒã
èªæžãã楜ãã¿ãã ããïŒ
æŠç¥1
ã¯ã©ã¹ããšã«1ã€ã®ããŒãã«
ç¶æ³ïŒ
eBayã®æ å
ãèŠãããšã«ãããã®ç®çã®ããã«ãªã³ã©ã€ã³ãªãŒã¯ã·ã§ã³ã¢ããªã±ãŒã·ã§ã³ãäœæããŠããŸãã åãŠãŒã¶ãŒã¯è³ããããããšãã§ãã圌ã®ã¬ãŒããæ倧ã®å Žåã¯ãªã³ã©ã€ã³ã§æ¯æããè¡ããŸãã
å®éã«ã¯ãæ¯æãããã»ã¹ãããŒã¿ã¢ãã«ãšèŠãªããŸãã
ãŠãŒã¶ãŒã¯ãéè¡ã«ãŒãã䜿çšããæ¹æ³ãšéè¡å£åº§ã®è©³çŽ°ã䜿çšããæ¹æ³ã®2ã€ã®æ¹æ³ã§æ¯æããè¡ãããšãã§ããŸãã
ã¯ã©ã¹å³ã以äžã«ç€ºããŸãã

ãµã³ãã«ãå®è¡ããJavaã³ãŒãpom.xmlïŒ
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hiber.jd2050</groupId> <artifactId>hiberLearn</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.7</java.version> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <target>${java.version}</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.0-801.jdbc4</version> </dependency> <dependency> <groupId>org.hibernate.javax.persistence</groupId> <artifactId>hibernate-jpa-2.1-api</artifactId> <version>1.0.0.Final</version> </dependency> <dependency> <groupId>javax.transaction</groupId> <artifactId>jta</artifactId> <version>1.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.0.5.Final</version> </dependency> </dependencies> </project>
hibernate.cfg.xml
<!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> <property name="connection.url">jdbc:postgresql://localhost:5432/dobrynin_db</property> <property name="connection.driver_class">org.postgresql.Driver</property> <property name="connection.username">postgres</property> <property name="connection.password">filyaSl9999</property> <property name="dialect">org.hibernate.dialect.PostgreSQL9Dialect</property> <property name="hbm2ddl.auto">create-drop</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hibernate.current_session_context_class">thread</property> <mapping class="CreditCard"/> <mapping class="BankAccount"/> <mapping class="BillingDetails"/> </session-factory> </hibernate-configuration>
import javax.persistence.*; @MappedSuperclass public abstract class BillingDetails { private String owner; public BillingDetails() { } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } @Override public String toString() { return "BillingDetails{" + "owner='" + owner + '\'' + '}'; } }
import javax.persistence.*; @Entity @Table(name = "CREDIT_CARD") public class CreditCard extends BillingDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private int id; @Column(name = "card_number") private int cardNumber; @Column(name = "exp_month") private String expMonth; @Column (name = "exp_year") private String expYear; public CreditCard() { } public int getCardNumber() { return cardNumber; } public String getExpMonth() { return expMonth; } public String getExpYear() { return expYear; } public void setCardNumber(int cardNumber) { this.cardNumber = cardNumber; } public void setExpMonth(String expMonth) { this.expMonth = expMonth; } public void setExpYear(String expYear) { this.expYear = expYear; } @Override public String toString() { return "CreditCard{" + "cardNumber=" + cardNumber + ", expMonth='" + expMonth + '\'' + ", expYear='" + expYear + '\'' + '}'; } }
import javax.persistence.*; @Entity @Table(name = "BANK_ACCOUNT") public class BankAccount extends BillingDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private int id; private int account; @Column(name = "bank_name") private String bankName; private String swift; public BankAccount() { } public int getAccount() { return account; } public void setAccount(int account) { this.account = account; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } public String getSwift() { return swift; } public void setSwift(String swift) { this.swift = swift; } @Override public String toString() { return "BankAccount{" + "account=" + account + ", bankName='" + bankName + '\'' + ", swift='" + swift + '\'' + '}'; } }
import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { public static SessionFactory getSessionFactory() { return new Configuration().configure().buildSessionFactory(); } }
mainïŒïŒã¡ãœãããæã€ã¡ã€ã³ã¯ã©ã¹ïŒ
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import java.util.*; public class Main { public static void main(String[] args) throws Exception { CreditCard creditCard = new CreditCard(); creditCard.setCardNumber(44411111); creditCard.setExpMonth("Jan"); creditCard.setExpYear("2017"); creditCard.setOwner("Bill Gates"); BankAccount bankAccount = new BankAccount(); bankAccount.setAccount(111222333); bankAccount.setBankName("Goldman Sachs"); bankAccount.setSwift("GOLDUS33"); bankAccount.setOwner("Donald Trump"); SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session; Transaction transaction = null; try { session = sessionFactory.getCurrentSession(); transaction = session.beginTransaction(); session.persist(creditCard); session.persist(bankAccount); transaction.commit(); } catch (Exception e) { transaction.rollback(); throw e; } Session session1; Transaction transaction1 = null; try { session1 = sessionFactory.getCurrentSession(); transaction1 = session1.beginTransaction(); List billingDetails = session1.createQuery("select bd from BillingDetails bd").list(); for (int i = 0; i < billingDetails.size(); i++) { System.out.println(billingDetails.get(i)); } } catch (Exception e) { transaction1.rollback(); throw e; } } }
BankAccountã¯ã©ã¹ãšCreditCardã¯ã©ã¹ã¯ãBillingDetailsã®å
±éã®æœè±¡ç¥å
ãç¶æ¿ããŸãã å³ãããããããã«ãåæ§ã®æ©èœã«ããããããããããã®ç¶æ
ã¯å€§ããç°ãªããŸããã«ãŒãã«ã€ããŠã¯ãçªå·ãšæå¹æ§ãéèŠã§ãããéè¡å£åº§ã«ã€ããŠã¯è©³çŽ°ãã£ãŒã«ããéèŠã§ãã
芪ã¯ã©ã¹ã«ã¯ããã¹ãŠã®åå«ã«å
±éã®ææè
ã«é¢ããæ
å ±ã®ã¿ãæ ŒçŽãããŸãã
ããã«ãããšãã°ãIdãã£ãŒã«ããçæã®çš®é¡ãšå
±ã«åãåºãããšãã§ããŸãïŒãã®å Žåã¯ããªãã§è¡ããŸããïŒã
æåã®æŠç¥ã®ããŒã¿ããŒã¹ã®ã¹ããŒãã¯æ¬¡ã®ããã«ãªããŸãã

ããŒãã«äœæã®ã¯ãšãªïŒ
CREDIT_CARD create table credit_card ( id serial not null constraint bank_account_pkey primary key, cc_owner varchar(20) not null, card_number integer not null, exp_month varchar(9) not null, exp_year varchar(4) not null ) ;
BANK_ACCOUNT create table bank_account ( id serial not null primary key, owner varchar(20), account integer not null, bank_name varchar(20) not null, swift varchar(20) not null ) ;
ãã®å Žåã®å€æ
æ§ã¯æé»çã§ãã
Entityã¢ãããŒã·ã§ã³ã§åæ ã§ããååã¯ã©ã¹ã
éèŠïŒ ã¹ãŒããŒã¯ã©ã¹ã®ããããã£ã¯ããã©ã«ãã§ã¯ç¡èŠãããŸãã ããããç¹å®ã®ãµãã¯ã©ã¹ã®ããŒãã«ã«ä¿åããã«ã¯ã@ MappedSuperClassã¢ãããŒã·ã§ã³ã䜿çšããå¿
èŠããããŸãã
ãµãã¯ã©ã¹ã®è¡šç€ºã¯çããããšã§ã¯ãããŸããã 泚æãå¿
èŠãªã®ã¯ã@ AttributeOverrideã¢ãããŒã·ã§ã³ã ãã§ããããã¯ãããããªãã¿ã®ãªããã®ã§ãã
ç¥å
ããŒãã«ãšåå«ããŒãã«ã®ååãäžèŽããªãå Žåããµãã¯ã©ã¹ããŒãã«ã®åã®ååãå€æŽããããã«äœ¿çšãããŸãïŒãã®å ŽåãBillingDetailsã®ãææè
ãã¯CREDIT_CARDããŒãã«ã®CC_OWNERã«ããããããŸãïŒã
ãã®æŠç¥ã䜿çšããå Žåã®äž»ãªåé¡ã¯ãããªã¢ãŒãã£ãã¯ãªé¢é£ä»ããæ倧éã«äœ¿çšããããšãã§ããªãããšã§ããéåžžããããã¯å€éšããŒã¢ã¯ã»ã¹ãšããŠããŒã¿ããŒã¹ã«æ瀺ãããBILLING_DETAILSããŒãã«ã¯ãããŸããã ãŸããã¢ããªã±ãŒã·ã§ã³å
ã®åBillingDetailsãªããžã§ã¯ãã¯ç¹å®ã®Userãªããžã§ã¯ãã«é¢é£ä»ãããããããåå«ããŒãã«ã®ããããã«ã¯USERSããŒãã«ãåç
§ããå€éšããŒãå¿
èŠã§ãã
ããã«ãããªã¢ãŒãã£ãã¯ã¯ãšãªãåé¡ã«ãªããŸãã
ãªã¯ãšã¹ããæºããããã«ããŸããã
SELECT bd FROM BillingDetails bd
ãããè¡ãã«ã¯ïŒä»¥éïŒãmainïŒïŒã¡ãœãããå®è¡ããŸãã
ãã®å Žåã次ã®ããã«å®è¡ãããŸãã
Hibernate: select bankaccoun0_.id as id1_1_, bankaccoun0_.owner as owner2_1_, bankaccoun0_.account as account3_1_, bankaccoun0_.bank_name as bank_nam4_1_, bankaccoun0_.swift as swift5_1_ from BANK_ACCOUNT bankaccoun0_ Hibernate: select creditcard0_.id as id1_2_, creditcard0_.owner as owner2_2_, creditcard0_.card_number as card_num3_2_, creditcard0_.exp_month as exp_mont4_2_, creditcard0_.exp_year as exp_year5_2_ from CREDIT_CARD creditcard0_
ã€ãŸããç¹å®ã®ãµãã¯ã©ã¹ããšã«ãHibernateã¯åå¥ã®SELECTã¯ãšãªã䜿çšããŸãã
ãã®æŠç¥ã䜿çšããéã®å¥ã®éèŠãªåé¡ã¯ããªãã¡ã¯ã¿ãªã³ã°ã®è€éãã§ãã ã¹ãŒããŒã¯ã©ã¹ã®ãã£ãŒã«ãã®ååãå€æŽãããšãå€ãã®ããŒãã«ã®ååãå€æŽããå¿
èŠããããæåã§ååãå€æŽããå¿
èŠããããŸãïŒã»ãšãã©ã®IDEããŒã«ã¯@AttributeOverrideãèæ
®ããŸããïŒã ã¹ããŒã ã«ããŒãã«ã2ã€ã§ã¯ãªã50ããå Žåãããã«ã¯å€ãã®æéãããããŸãã
ãã®ã¢ãããŒãã¯ãã¯ã©ã¹éå±€ã®æäžéšã§ã®ã¿äœ¿çšã§ããŸãã
aïŒããªã¢ãŒãã£ãºã ã¯å¿
èŠãããŸããïŒHibernateã®ç¹å®ã®ãµãã¯ã©ã¹ã®ãµã³ããªã³ã°ã¯1åã®ãªã¯ãšã¹ãã§å®è¡ãããŸã->ããã©ãŒãã³ã¹ãé«ããªããŸãïŒ
bïŒã¹ãŒããŒã¯ã©ã¹ã§ã®å€æŽã¯äºèŠãããŸããã
ãªã¯ãšã¹ããBillingDetailsã®èŠªã¯ã©ã¹ãåç
§ããã¢ããªã±ãŒã·ã§ã³ã®å Žåããã®æŠç¥ã¯æ©èœããŸããã
æŠç¥2
çµåïŒUNIONïŒãæã€ã¯ã©ã¹ããšã«1ã€ã®ããŒãã«
æœè±¡ã¯ã©ã¹ã¯åã³BillingDetailsã«ãªããŸãã
ããŒã¿ããŒã¹ã¹ããŒããå€æŽãããŸããã
å¯äžã®ããšã¯ãCREDIT_CARDããŒãã«ã®CC_OWNERãã£ãŒã«ãã®ååãOWNERã«å€æŽããå¿
èŠãããããšã§ãããã®æŠç¥ã¯@AttributeOverrideããµããŒãããŠããªãããã§ãã
ããã¥ã¡ã³ãããïŒ
ããã®ã¢ãããŒãã®å¶éã¯ãããããã£ãã¹ãŒããŒã¯ã©ã¹ã«ããããããå Žåãååã¯ãã¹ãŠã®ãµãã¯ã©ã¹ããŒãã«ã§åãã§ãªããã°ãªããªãããšã§ããã瀺ãããTABLE_PER_CLASSæŠç¥ãæã€ã¹ãŒããŒã¯ã©ã¹ã®äžã«ç€ºãããã¢ãããŒã·ã§ã³@Inheritanceãæ°ãããªããŸãã
éèŠïŒ ãã®æŠç¥ã®æ çµã¿ã®
äžã§ãã¹ãŒããŒã¯ã©ã¹ã«èå¥åãååšãã
ããšã¯å¿
é ã®èŠä»¶ã§ã ïŒæåã®äŸã§ã¯
ãèå¥åãªãã§è¡ããŸããïŒã
éèŠïŒ JPAæšæºã«ããã°ãTABLE_PER_CLASSæŠç¥ã¯ãªãã·ã§ã³ã§ãããããä»ã®å®è£
ã¯ãµããŒããããªãå ŽåããããŸãã
å€æŽãããJavaã³ãŒã import javax.persistence.*; @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class BillingDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private int id; private String owner; public BillingDetails() { } public int getId() { return id; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } @Override public String toString() { return "BillingDetails{" + "id=" + id + ", owner='" + owner + '\'' + '}'; } }
import javax.persistence.*; @Entity @Table(name = "CREDIT_CARD") public class CreditCard extends BillingDetails { @Column(name = "card_number") private int cardNumber; @Column(name = "exp_month") private String expMonth; @Column (name = "exp_year") private String expYear; public CreditCard() { } public int getCardNumber() { return cardNumber; } public String getExpMonth() { return expMonth; } public String getExpYear() { return expYear; } public void setCardNumber(int cardNumber) { this.cardNumber = cardNumber; } public void setExpMonth(String expMonth) { this.expMonth = expMonth; } public void setExpYear(String expYear) { this.expYear = expYear; } @Override public String toString() { return "CreditCard{" + "cardNumber=" + cardNumber + ", expMonth='" + expMonth + '\'' + ", expYear='" + expYear + '\'' + '}'; } }
import javax.persistence.*; @Entity @Table(name = "BANK_ACCOUNT") public class BankAccount extends BillingDetails { private int account; @Column(name = "bank_name") private String bankName; private String swift; public BankAccount() { } public int getAccount() { return account; } public void setAccount(int account) { this.account = account; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } public String getSwift() { return swift; } public void setSwift(String swift) { this.swift = swift; } @Override public String toString() { return "BankAccount{" + "account=" + account + ", bankName='" + bankName + '\'' + ", swift='" + swift + '\'' + '}'; } }
SQLã¹ããŒãã¯ç¶æ¿ã«ã€ããŠäœãç¥ããŸããã ããŒãã«éã«é¢ä¿ã¯ãããŸããã
ãã®æŠç¥ã®äž»ãªå©ç¹ã¯ãåã®äŸã®ããªã¢ãŒãã£ãã¯ã¯ãšãªãå®è¡ããããšã§ç¢ºèªã§ããŸãã
SELECT bd FROM BillingDetails bd
ä»åã¯ç°ãªãæ¹æ³ã§å®è¡ãããŸãã
Hibernate: select billingdet0_.id as id1_1_, billingdet0_.owner as owner2_1_, billingdet0_.card_number as card_num1_2_, billingdet0_.exp_month as exp_mont2_2_, billingdet0_.exp_year as exp_year3_2_, billingdet0_.account as account1_0_, billingdet0_.bank_name as bank_nam2_0_, billingdet0_.swift as swift3_0_, billingdet0_.clazz_ as clazz_ from ( select id, owner, card_number, exp_month, exp_year, null::int4 as account, null::varchar as bank_name, null::varchar as swift, 1 as clazz_ from CREDIT_CARD union all select id, owner, null::int4 as card_number, null::varchar as exp_month, null::varchar as exp_year, account, bank_name, swift, 2 as clazz_ from BANK_ACCOUNT ) billingdet0_
ãã®å ŽåãHibernateã¯FROMã䜿çšããŠããã¹ãŠã®ãµãã¯ã©ã¹ããŒãã«ããBillingDetailsã®ãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãååŸããŸãã ããŒãã«ã¯UNIONã䜿çšããŠçµåããããªãã©ã«ïŒ1ãš2ïŒãäžéçµæã«è¿œå ãããŸãã Hibernateã¯ãªãã©ã«ã䜿çšããŠãæ£ããã¯ã©ã¹ãã€ã³ã¹ã¿ã³ã¹åããŸãã
ããŒãã«ãçµåããã«ã¯åãåæ§é ãå¿
èŠã§ãããããååšããªãåã®ä»£ããã«NULLãæ¿å
¥ãããŸããïŒããšãã°ãcredit_cardã® "null :: varchar as bank_name"-ã¯ã¬ãžããã«ãŒãããŒãã«ã«éè¡åããããŸããïŒã
æåã®æŠç¥ã«å¯Ÿãããã1ã€ã®éèŠãªå©ç¹ã¯ãããªã¢ãŒãã£ãã¯ãªé¢é£ä»ãã䜿çšã§ããããšã§ãã ããã§ãUserã¯ã©ã¹ãšBillingDetailsã¯ã©ã¹ã®éã®é¢é£ä»ããç°¡åã«ãããã§ããŸãã
æŠç¥3
ã¯ã©ã¹éå±€å
šäœã®åäžã®ããŒãã«
ã¯ã©ã¹éå±€ã¯ã1ã€ã®ããŒãã«ã§å®å
šã«éžæã§ããŸãã éå±€å
ã®åã¯ã©ã¹ã®ãã¹ãŠã®ãã£ãŒã«ãã®åãå«ãŸããŸãã åã¬ã³ãŒãã«ã€ããŠãç¹å®ã®ãµãã¯ã©ã¹ã¯ã
ã»ã¬ã¯ã¿ãŒã®è¿œå åã®å€ã«ãã£ãŠæ±ºå®ãããŸãã
ãã€ã¢ã°ã©ã ã¯æ¬¡ã®ããã«ãªããŸãã

äœæã®ãªã¯ãšã¹ã create table billing_details ( id serial not null constraint billing_details_pkey primary key, bd_type varchar(2), owner varchar(20), card_number integer, exp_month varchar(9), exp_year varchar(4), account integer, bank_name varchar(20), swift varchar(20) ) ; create unique index billing_details_card_number_uindex on billing_details (card_number) ;
Javaã¯ã©ã¹ã®æ§é ïŒ

åäžã®ããŒãã«ãããã³ã°ãäœæããã«ã¯ãç¶æ¿æŠç¥SINGLE_TABLEã䜿çšããå¿
èŠããããŸãã
ã«ãŒãã¯ã©ã¹ã¯ããŒãã«BILLING_DETAILSã«ããããããŸãã ã¿ã€ããåºå¥ããããã«ãã»ã¬ã¯ã¿ãŒåã䜿çšãããŸãã ããã¯ãšã³ãã£ãã£ãã£ãŒã«ãã§ã¯ãªããHibernateå°çšã«äœæãããŸããã ãã®å€ã¯æåå-ãCCããŸãã¯ãBAãã«ãªããŸãã
éèŠïŒ ã¹ãŒããŒã¯ã©ã¹ã§ã»ã¬ã¯ã¿ãŒåãæ瀺çã«æå®ããªãå Žåãããã©ã«ãåã®DTYPEãšã¿ã€ãVARCHARãååŸãããŸãã
åéå±€ã¯ã©ã¹ã¯ã@ DiscriminatorValueã¢ãããŒã·ã§ã³ã䜿çšããŠã»ã¬ã¯ã¿ãŒå€ã瀺ãããšãã§ããŸãã
ã»ã¬ã¯ã¿ãŒã®æ瀺çãªååãç¡èŠããªãã§ãã ãããããã©ã«ãã§ã¯ãHibernateã¯å®å
šä¿®é£Ÿã¯ã©ã¹åãŸãã¯ãšã³ãã£ãã£åã䜿çšããŸãïŒXML-Hibernateãã¡ã€ã«ãŸãã¯JPA /ã¢ãããŒã·ã§ã³xmlãã¡ã€ã«ã䜿çšããããã©ããã«ãã£ãŠç°ãªããŸãïŒã
å€æŽãããJavaã³ãŒã import javax.persistence.*; @Entity @Table(name = "BILLING_DETAILS") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "BD_TYPE") public abstract class BillingDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private int id; private String owner; public BillingDetails() { } public int getId() { return id; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } @Override public String toString() { return "BillingDetails{" + "id=" + id + ", owner='" + owner + '\'' + '}'; } }
import javax.persistence.*; @Entity @DiscriminatorValue("BA") public class BankAccount extends BillingDetails { private int account; @Column(name = "bank_name") private String bankName; private String swift; public BankAccount() { } public int getAccount() { return account; } public void setAccount(int account) { this.account = account; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } public String getSwift() { return swift; } public void setSwift(String swift) { this.swift = swift; } @Override public String toString() { return "BankAccount{" + "account=" + account + ", bankName='" + bankName + '\'' + ", swift='" + swift + '\'' + '}'; } }
import javax.persistence.*; @Entity @DiscriminatorValue("CC") public class CreditCard extends BillingDetails { @Column(name = "card_number") private int cardNumber; @Column(name = "exp_month") private String expMonth; @Column (name = "exp_year") private String expYear; public CreditCard() { } public int getCardNumber() { return cardNumber; } public String getExpMonth() { return expMonth; } public String getExpYear() { return expYear; } public void setCardNumber(int cardNumber) { this.cardNumber = cardNumber; } public void setExpMonth(String expMonth) { this.expMonth = expMonth; } public void setExpYear(String expYear) { this.expYear = expYear; } @Override public String toString() { return "CreditCard{" + "cardNumber=" + cardNumber + ", expMonth='" + expMonth + '\'' + ", expYear='" + expYear + '\'' + '}'; } }
æ€èšŒã®ããã«ãmainã¡ãœããã§ããªãã¿ã®ãªã¯ãšã¹ãã䜿çšããŸã
SELECT bd FROM BillingDetails bd
åäžã®ããŒãã«ã®å Žåããã®ã¯ãšãªã¯æ¬¡ã®ããã«å®è¡ãããŸãã
Hibernate: select billingdet0_.id as id2_0_, billingdet0_.owner as owner3_0_, billingdet0_.card_number as card_num4_0_, billingdet0_.exp_month as exp_mont5_0_, billingdet0_.exp_year as exp_year6_0_, billingdet0_.account as account7_0_, billingdet0_.bank_name as bank_nam8_0_, billingdet0_.swift as swift9_0_, billingdet0_.BD_TYPE as BD_TYPE1_0_ from BILLING_DETAILS billingdet0_
èŠæ±ãç¹å®ã®ãµãã¯ã©ã¹ã«å¯ŸããŠå®è¡ãããå Žåããwhere BD_TYPE =â CCâããšããè¡ãåã«è¿œå ãããŸãã
åäžã®ããŒãã«ãžã®ãããã³ã°ã¯æ¬¡ã®ããã«ãªããŸãã

ã¹ããŒã ãç¶æ¿ãããã»ã¬ã¯ã¿ãŒåãè¿œå ããããšãäžå¯èœãªå Žåã@ DiscriminatorFormulaã¢ãããŒã·ã§ã³ã圹ç«ã¡ãŸããããã¯èŠªã¯ã©ã¹ã«è¿œå ããå¿
èŠããããŸãã åŒCASE ... WHENãããã«æž¡ãå¿
èŠããããŸãã
import org.hibernate.annotations.DiscriminatorFormula; import javax.persistence.*; @Entity @Table(name = "BILLING_DETAILS") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorFormula("CASE WHEN CARD_NUMBER IS NOT NULL THEN 'CC' ELSE 'BA' END") public abstract class BillingDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private int id;
ãã®æŠç¥ã®äž»ãªå©ç¹ã¯ããã©ãŒãã³ã¹ã§ãã ã¯ãšãªïŒå€æ
æ§ããã³éå€æ
æ§ã®äž¡æ¹ïŒã¯éåžžã«é«éã§ãæåã§ç°¡åã«èšè¿°ã§ããŸãã æ¥ç¶ãšãŠããªã³ã䜿çšããå¿
èŠã¯ãããŸããã åè·¯ã®é²åãéåžžã«ç°¡åã§ãã
ãã ãããã®æŠç¥ãåãå·»ãåé¡ã¯å€ãã®å Žåããã®å©ç¹ãäžåããŸãã
äž»ãªãã®ã¯ããŒã¿ã®æŽåæ§ã§ãã ãµãã¯ã©ã¹ã§å®£èšãããŠããããããã£ã®åã«ã¯ãNULLãå«ãŸããŠããå ŽåããããŸãã ãã®çµæãåçŽãªãœãããŠã§ã¢ãšã©ãŒã«ãããããŒã¿ããŒã¹ã«çªå·ãæå¹æéã®ãªãã¯ã¬ãžããã«ãŒããäœæãããå¯èœæ§ããããŸãã
å¥ã®åé¡ã¯ãæ£èŠåãå
·äœçã«ã¯
3çªç®ã®æ£èŠåœ¢ã®éåã§ãã ãã®èŠ³ç¹ãããçç£æ§ã®åäžã®å©ç¹ã¯ãã§ã«çãããããã«èŠããŸãã çµå±ã®ãšãããå°ãªããšãè·è¡ã®å©äŸ¿æ§ãç ç²ã«ããå¿
èŠããããŸããé·æçã«ã¯ãéæ£èŠåãããã¹ããŒã ã¯ããŸãæ©èœããŸããã
æŠç¥4
çµåã䜿çšããã¯ã©ã¹ããšã«1ã€ã®ããŒãã«ïŒJOINïŒ
ã¯ã©ã¹ã®æŠèŠã¯å€æŽãããŸããã

ããããããŒã¿ããŒã¹ã¹ããŒãã«ã¯ããã€ãã®å€æŽããããŸãã

BILLING_DETAILSã®äœæãªã¯ãšã¹ã create table billing_details ( id integer not null constraint billing_details_pkey primary key, owner varchar(20) not null ) ;
CREDIT_CARDã®å Žå create table credit_card ( id integer not null constraint credit_card_pkey primary key constraint credit_card_billing_details_id_fk references billing_details, card_number integer not null, exp_month varchar(255) not null, exp_year varchar(255) not null ) ; create unique index credit_card_card_number_uindex on credit_card (card_number) ;
BANK_ACCOUNTã®å Žå create table bank_account ( id integer not null constraint bank_account_pkey primary key constraint bank_account_billing_details_id_fk references billing_details, account integer not null, bank_name varchar(255) not null, swift varchar(255) not null ) ; create unique index bank_account_account_uindex on bank_account (account) ;
Javaã³ãŒãã§ã¯ãJOINEDæŠç¥ã䜿çšããŠãã®ãããªãããã³ã°ãäœæããå¿
èŠããããŸãã
å€æŽãããJavaã³ãŒã import javax.persistence.*; @Entity @Table(name = "BILLING_DETAILS") @Inheritance(strategy = InheritanceType.JOINED) public abstract class BillingDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private int id; private String owner; public BillingDetails() { } public int getId() { return id; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } @Override public String toString() { return "BillingDetails{" + "id=" + id + ", owner='" + owner + '\'' + '}'; } }
import javax.persistence.*; @Entity @Table(name = "CREDIT_CARD") public class CreditCard extends BillingDetails { @Column(name = "card_number") private int cardNumber; @Column(name = "exp_month") private String expMonth; @Column (name = "exp_year") private String expYear; public CreditCard() { } public int getCardNumber() { return cardNumber; } public String getExpMonth() { return expMonth; } public String getExpYear() { return expYear; } public void setCardNumber(int cardNumber) { this.cardNumber = cardNumber; } public void setExpMonth(String expMonth) { this.expMonth = expMonth; } public void setExpYear(String expYear) { this.expYear = expYear; } @Override public String toString() { return "CreditCard{" + "cardNumber=" + cardNumber + ", expMonth='" + expMonth + '\'' + ", expYear='" + expYear + '\'' + '}'; } }
import javax.persistence.*; @Entity @Table(name = "BANK_ACCOUNT") public class BankAccount extends BillingDetails { private int account; @Column(name = "bank_name") private String bankName; private String swift; public BankAccount() { } public int getAccount() { return account; } public void setAccount(int account) { this.account = account; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } public String getSwift() { return swift; } public void setSwift(String swift) { this.swift = swift; } @Override public String toString() { return "BankAccount{" + "account=" + account + ", bankName='" + bankName + '\'' + ", swift='" + swift + '\'' + '}'; } }
çŸåšãããšãã°CreditCardã®ã€ã³ã¹ã¿ã³ã¹ãä¿åãããšããHibernateã¯2ã€ã®ã¬ã³ãŒããæ¿å
¥ããŸãã BillingDetailsã¹ãŒããŒã¯ã©ã¹ã®ãã£ãŒã«ãã§å®£èšãããããããã£ã¯BILLING_DETAILSããŒãã«ã«åé¡ãããCreaditCardãµãã¯ã©ã¹ã®ãã£ãŒã«ãã®å€ã¯CREDIT_CARDããŒãã«ã«æžã蟌ãŸããŸãã ãããã®ãšã³ããªã¯ãå
±éã®äž»ããŒã«ãã£ãŠçµåãããŸãã
ãããã£ãŠãåè·¯ã¯æ£åžžã«ãªããŸããã åè·¯ã®é²åãšæŽåæ§å¶çŽã®æ±ºå®ãç°¡åã§ãã
å€éšããŒã䜿çšãããšãç¹å®ã®ãµãã¯ã©ã¹ãšã®ããªã¢ãŒãã£ãã¯ãªé¢é£ä»ããè¡šãããšãã§ããŸãã
ãªã¯ãšã¹ããå®äºããããšã«ãã
SELECT bd FROM BillingDetails bd
ã次ã®å³ã衚瀺ãããŸãã
Hibernate: select billingdet0_.id as id1_1_, billingdet0_.owner as owner2_1_, billingdet0_1_.card_number as card_num1_2_, billingdet0_1_.exp_month as exp_mont2_2_, billingdet0_1_.exp_year as exp_year3_2_, billingdet0_2_.account as account1_0_, billingdet0_2_.bank_name as bank_nam2_0_, billingdet0_2_.swift as swift3_0_, case when billingdet0_1_.id is not null then 1 when billingdet0_2_.id is not null then 2 when billingdet0_.id is not null then 0 end as clazz_ from BILLING_DETAILS billingdet0_ left outer join CREDIT_CARD billingdet0_1_ on billingdet0_.id=billingdet0_1_.id left outer join BANK_ACCOUNT billingdet0_2_ on billingdet0_.id=billingdet0_2_.id
BILLING_DETAILS

CREDIT_CARD

BANK_ACCOUNT

CASE ... WHENå¥ã«ãããHibernateã¯åã¬ã³ãŒãã«ç¹å®ã®ãµãã¯ã©ã¹ãå®çŸ©ã§ããŸãã ãªãã©ã«ã䜿çšããŠããµãã¯ã©ã¹CREDIR_CARDããã³BANK_ACCOUNTã®ããŒãã«ã®è¡ã®æç¡ããã§ãã¯ããŸãã
ãã®ãããªæŠç¥ãæåã§å®è£
ããããšã¯éåžžã«å°é£ã§ãã ä»»æã®ã¯ãšãªã«åºã¥ããŠã¬ããŒããå®è£
ããããšã§ãããã¯ããã«å°é£ã§ãã
ã¯ãšãªã¯è€æ°ã®ããŒãã«ã®çµåãŸãã¯å€ãã®é 次èªã¿åãæäœãå¿
èŠãšãããããç¹å®ã®ãããžã§ã¯ãã§ã¯ããã©ãŒãã³ã¹ã蚱容ã§ããªãå ŽåããããŸãã
ç¶æ¿ãããã³ã°æŠç¥ã®æ··å
æŠç¥TABLE_PER_CLASSãSINGLE_TABLEãããã³JOINEDã䜿çšããå Žåãé倧ãªäžäŸ¿ã¯ãããããåãæ¿ããããšãã§ããªããšããäºå®ã§ãã éžæããæŠç¥ãæåŸãŸã§é å®ããå¿
èŠããããŸãïŒãŸãã¯ã¹ããŒã ãå®å
šã«å€æŽããŸãïŒã
ãã ããç¹å®ã®ãµãã¯ã©ã¹ã®è¡šç€ºæŠç¥ãåãæ¿ããããšãã§ããããªãã¯ããããŸãã
ããšãã°ãã¯ã©ã¹éå±€ãåäžã®ããŒãã«ïŒæŠç¥3ïŒã«ãããã³ã°ããããšã§ãåå¥ã®ãµãã¯ã©ã¹ïŒæŠç¥4ïŒã®åå¥ã®ããŒãã«ãšå€éšããŒãæã€æŠç¥ãéžæã§ããŸãã


BILLING_DETAILSãäœæããã¹ã¯ãªãã create table billing_details ( id integer not null constraint billing_details_pkey primary key, owner varchar(20), account integer, bank_name varchar(20), swift varchar(20) ) ;
CREDIT_CARDã®å Žå create table credit_card ( card_number integer not null, exp_month varchar(255) not null, exp_year varchar(255) not null, id integer not null constraint credit_card_pkey primary key constraint fksf645frtr6h3i4d179ff4ke9h references billing_details ) ;
ããã§ãCreditCardãµãã¯ã©ã¹ãå¥ã®ããŒãã«ã«ãããã³ã°ã§ããŸãã
ãããè¡ãã«ã¯ãInheritanceType.SINGLE_TABLEæŠç¥ãBillingDetailsã¹ãŒããŒã¯ã©ã¹ã«é©çšããå¿
èŠããããŸãã@ SecondaryTableã¢ãããŒã·ã§ã³ã¯ãCreditCardã¯ã©ã¹ã®æäœã«åœ¹ç«ã¡ãŸãã
å€æŽãããJavaã³ãŒã import javax.persistence.*; @Entity @Table(name = "BILLING_DETAILS") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "BD_TYPE") public abstract class BillingDetails { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private int id; private String owner; public BillingDetails() { } public int getId() { return id; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } @Override public String toString() { return "BillingDetails{" + "id=" + id + ", owner='" + owner + '\'' + '}'; } }
import javax.persistence.*; @Entity public class BankAccount extends BillingDetails { private int account; @Column(name = "bank_name") private String bankName; private String swift; public BankAccount() { } public int getAccount() { return account; } public void setAccount(int account) { this.account = account; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } public String getSwift() { return swift; } public void setSwift(String swift) { this.swift = swift; } @Override public String toString() { return "BankAccount{" + "account=" + account + ", bankName='" + bankName + '\'' + ", swift='" + swift + '\'' + '}'; } }
import javax.persistence.*; @Entity @DiscriminatorValue("CC") @SecondaryTable(name = "CREDIT_CARD", pkJoinColumns = @PrimaryKeyJoinColumn(name = "ID")) public class CreditCard extends BillingDetails { @Column(table = "CREDIT_CARD",name = "card_number") private int cardNumber; @Column(table = "CREDIT_CARD",name = "exp_month") private String expMonth; @Column (table = "CREDIT_CARD",name = "exp_year") private String expYear; public CreditCard() { } public int getCardNumber() { return cardNumber; } public String getExpMonth() { return expMonth; } public String getExpYear() { return expYear; } public void setCardNumber(int cardNumber) { this.cardNumber = cardNumber; } public void setExpMonth(String expMonth) { this.expMonth = expMonth; } public void setExpYear(String expYear) { this.expYear = expYear; } @Override public String toString() { return "CreditCard{" + "cardNumber=" + cardNumber + ", expMonth='" + expMonth + '\'' + ", expYear='" + expYear + '\'' + '}'; } }
ã¢ãããŒã·ã§ã³@SecondaryTableããã³@Columnã䜿çšããŠãã¡ã€ã³ããŒãã«ãšãã®åãåå®çŸ©ããããŒã¿ã®ååŸå
ãHibernateã«ç€ºããŸããSINGLE_TABLEæŠç¥ãéžæãããšããµãã¯ã©ã¹åã«NULLãå«ãŸããå ŽåããããŸãããã®ææ³ã䜿çšãããšãç¹å®ã®ãµãã¯ã©ã¹ïŒãã®å Žåã¯CreditCardïŒã®ããŒã¿æŽåæ§ãä¿èšŒã§ããŸããããªã¢ãŒãã£ãã¯ã¯ãšãªãå®è¡ããããšã«ãããHibernateã¯å€éšçµåãå®è¡ããŠBillingDetailsããã³ãã®ãã¹ãŠã®ãµãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãååŸããŸããè©ŠããŠã¿ãŸãããïŒ
SELECT bd FROM BillingDetails bd
çµæïŒ
Hibernate: select billingdet0_.id as id2_0_, billingdet0_.owner as owner3_0_, billingdet0_.account as account4_0_, billingdet0_.bank_name as bank_nam5_0_, billingdet0_.swift as swift6_0_, billingdet0_1_.card_number as card_num1_1_, billingdet0_1_.exp_month as exp_mont2_1_, billingdet0_1_.exp_year as exp_year3_1_, billingdet0_.BD_TYPE as BD_TYPE1_0_ from BILLING_DETAILS billingdet0_ left outer join CREDIT_CARD billingdet0_1_ on billingdet0_.id=billingdet0_1_.ID

ãã®ææ³ã¯ãéå±€ã®ä»ã®ã¯ã©ã¹ã«é©çšã§ããŸãããåºç¯ãªéå±€ã§ã¯ããã®å Žåã®å€éšæ¥ç¶ãåé¡ã«ãªããããããŸãããŸãæ©èœããŸããããã®ãããªéå±€ã®å Žåãå€éšçµåã§ã¯ãªã2çªç®ã®SQLã¯ãšãªãããã«å®è¡ããæŠç¥ãæé©ã§ããæŠç¥ã®éžæ
äžèšã®æŠç¥ãšææ³ã«ã¯ããããé·æãšçæããããŸããç¹å®ã®æŠç¥ãéžæããããã®äžè¬çãªæšå¥šäºé
ã¯æ¬¡ã®ããã«ãªããŸãã-å€æ
çãªã¯ãšãªãšé¢é£ä»ããäžèŠãªå ŽåãæŠç¥çªå·2ïŒUNIONã«åºã¥ãTABLE_PER_CLASSïŒããBillingDetails bdããbdãéžæãããããšããã£ãã«ãªãïŒãŸãã¯ãŸã£ããå®è¡ããªãïŒå ŽåãBillingDetailsãåç
§ããã¯ã©ã¹ããªãå Žåã¯ããã®ãªãã·ã§ã³ã®æ¹ãé©ããŠããŸãïŒæé©åãããããªã¢ãŒãã£ãã¯ã¯ãšãªãšé¢é£ä»ããè¿œå ããæ©èœãæ®ãããïŒã-æŠç¥çªå·3ïŒSINGLE_TABLEïŒã䜿çšããå¿
èŠããããŸããaïŒåçŽãªã¿ã¹ã¯ã®ã¿ãæ£èŠåãšNOT NULLå¶çŽãéèŠãªç¶æ³ã§ã¯ãæŠç¥ïŒ4ïŒåå ïŒãæšå¥šããŸããç¶æ¿ãå®å
šã«æŸæ£ããŠå§ä»»ã«çœ®ãæãã 䟡å€ããããã©ãããèããããšã¯çã«ããªã£ãŠããŸããbïŒããªã¢ãŒãã£ãã¯ãªã¯ãšãªãšé¢é£ä»ããããã³å®è¡æã®ç¹å®ã®ã¯ã©ã¹ã®åçå®çŸ©ãå¿
èŠãªå Žåããã ãããµãã¯ã©ã¹ã§å®£èšãããæ°ãããã£ãŒã«ãã¯æ¯èŒçå°ãªããã¹ãŒããŒã¯ã©ã¹ãšã®äž»ãªéãã¯åäœã§ããããŠãããã«å ããŠãDBAãšã®çå£ãªäŒè©±ããããŸãã-æŠç¥ïŒ4ïŒJOINEDïŒã¯ãå€æ
çãªã¯ãšãªãšé¢é£ä»ããå¿
èŠã§ãããããµãã¯ã©ã¹ãæ¯èŒçå€ãã®æ°ãããã£ãŒã«ãã宣èšããå Žåã«é©ããŠããŸããããã§èšåãã䟡å€ããããŸãïŒJOINEDãšTABLE_PER_CLASSã®éã®æ±ºå®ã¯ãç¶æ¿éå±€ã®å¹
ãšæ·±ããæ¥ç¶ã®ã³ã¹ãïŒçµæãšããŠããã©ãŒãã³ã¹ïŒãåãå
¥ããããªãããã«ããå¯èœæ§ããããããå®éã®ããŒã¿ã«å¯Ÿããã¯ãšãªå®è¡ã®èšç»ãè©äŸ¡ããå¿
èŠããããŸãããŸããç¶æ¿ã¢ãããŒã·ã§ã³ãã€ã³ã¿ãŒãã§ã€ã¹ã«é©çšã§ããªãããšãèæ
®ã«å
¥ããå¿
èŠããããŸãããæž
èŽããããšãããããŸããïŒ