Spring Hbername 5快速入門(二)連表操作OneToOne

5346 ワード

1概要
すべてのコードは実行可能な完全なプロジェクトであり、コードはgithb.comで共有され、通常の作業でもテンプレートコードctrl+cとして使用できます.https://github.com/ZhongjunTian/spring-hibernate-examples この章の内容はintermediate-hibernate-1フォルダの下で、App.javaを実行して例を実行することができます.
基本的な連表関係:OneToOne関係
一対一の関係は一番基本的な表と表の関係です.私たちは三つの時計を持っています.それぞれPerson、Accent、Addressです.彼らの間の関係は一対の関係と定義しています.だから、Personは一つのAccelontと一つのAddressしかありません.
2.Table定義
create table person_table (
        id bigint generated by default as identity,
        name varchar(255),
        account_id bigint
        );
create table account_table (
        id bigint generated by default as identity,
        balance decimal(19,2)
        );
create table address_table (
        id bigint generated by default as identity,
        city varchar(255),
        person_id bigint
        );
ここでPersonとAccentの間のOneToOne関係は、Personがaccountのidを持っています.つまりaccount_です.id、PersonとAddressの関係、私達はaddressにpersonのidを持たせて、つまりperson_です.ID(これは2つの状況を示すためのコードです.)
2.1 Person類
まず私達は三つの@Entity種類のPerson.java Acceount.java Addres.java Personを創立します.下記の内容があります.
@Entity(name="PersonTable")
public class Person {
    @Id
    @GeneratedValue
    public Long id;

    public String name;
    
    //Person   account_id, Account    person_id,   Address  
    @OneToOne(cascade = CascadeType.ALL)
    public Account account;

    //Address   person_id
    @OneToOne(mappedBy = "owner")
    @JoinColumn
    public Address address;
    ...
 }
@Enttity.name
ここでは、読者が以下のjavaのPerson類とPerson表を混同することを避けるために、クラスと表の名前を区別しています.nameはこのEntityを示しています.Person_に対応しています.テーブル
@Id
メインキー
@OneToOne
表面AcceountはEntityであり、PersonとAcceountは一つの対応関係であり、どのPersonも一つのAcceountが一番多いです.
cascade(オプション)
カスケード(直列)の操作は、デフォルトではカスケード操作は行われません.カスケード操作とは何ですか?ここでは偽コードを使ってよりよく説明します.
    //     repository    person   
    person = personRepository.find(1L);
    person.name = "  "
    person.account.balance += 100;
    
    personRepository.save(person);
    personRepository.delete(person);
personを更新/削除するとき、Hibernateはpersonかそれともpersonかaccountかを操作します.古代の連座制度に似ています.personがxxにされるとaccountもxxになります.ここでは模範を示すために直接連結してすべての操作をします.具体的にはAlrst、MerageとReveもたくさんあります.
Addressはcascadeを設置していないので、使用する時はPersonとaddressを分けて保存します.詳細は一番後ろのpublic void oneToOneNoCascading1()を参照してください.
mappedBy
MappedはPersonが無辜の民衆であることを明示して、addressのいかなる情報がなくて、別のAddress表は外部キーを持っています(あるいはもっと専門的な言い方は関係の所有者がAddressです).そしてjavaの種類Address.ownerというメンバー変数によって彼らの関係を維持します.
暗黙的なLong accountId
ここに細かいところがありますが、PersonTableの表の中に外部キーのaccount_があります.IDですが、Entityには含まれていません.実はHybernateではpublic Account account;の外鍵はPersonTableの表の中でaccount_です.id.ここがpublic Account xx;なら、ヒベルナはPersonTableの表の中に外キーxx_があると思います.id;
2.2 Acceount類
@Entity(name = "AccountTable")
public class Account {
    @Id
    @GeneratedValue
    public Long id;

    public BigDecimal balance;//  
    ...
    }
Personは関係の所有者なので、このクラスは簡単です.そして、AccentクラスでPersonのメンバーを定義していません.Hibernate公式文書では、この関係はunidirectionalと呼ばれています.もう一つはbi-directionの双方向関係です.PersonとAddressの関係は双方向です.
2.3 Address類
@Entity(name = "AddressTable")
public class Address {
    @Id
    @GeneratedValue
    public Long id;

    public String city;

    @OneToOne
    @JoinColumn(name = "person_id") //              PersonTable    owner_id 
    public Person owner;
    ...
}
@JoinColumn
外鍵の名前を表記していますが、これがないとデフォルト外鍵はAddress Table表のowner(u)です.id
3.モデルコード

@Service
public class Demo {
    @Autowired
    PersonRepository personRepository;
    @Autowired
    AccountRepository accountRepository;

    @Transactional  //one to one relationship
    public void oneToOneCascading1() {
        System.out.println("*******************  ");
        //   account
        Account account = Account.createAccount();

        //  person  address
        Person person = Person.createPerson();
        person.account = account;

        person = personRepository.save(person);
        System.out.println("       person   account: "+person);//
    }

    @Transactional
    public void oneToOneCascading2() {
        System.out.println("*******************  ");
        //  account
        Account account = Account.createAccount();
        account = accountRepository.save(account);

        System.out.println("   account: "+account);//
        // person  address
        Person person = Person.createPerson();
        person.account = account;

        person = personRepository.save(person);
        System.out.println("   person,         address: "+person);//
    }

    @Transactional
    public void oneToOneNocascading1() {
        System.out.println("*******************  ");
        // person  address
        Person person = Person.createPerson();
        person = personRepository.save(person);
        System.out.println("   person: "+person);//

        //  account
        Account account = Account.createAccount();
        account = accountRepository.save(account);
        System.out.println("   account: "+account);//

        person.account = account;
        person = personRepository.save(person);
        System.out.println("   person: "+person);//

    }

}