Mapim enum

Kami telah memikirkan cara untuk memetakan jenis data primitif: kami menggunakan anotasi @Column dan anotasi @Type . Tetapi tidak semua kes boleh dilindungi oleh anotasi ini. Dan kes yang paling biasa ialah enum .

Objek enum Java boleh disimpan dalam pangkalan data dalam dua cara:

  • sebagai nombor
  • sebagai rentetan

Mari tulis satu contoh kecil di mana pengguna akan mempunyai warna kegemaran, yang ditetapkan menggunakan enum.


enum Color {
   RED,
   ORANGE,
   YELLOW,
   GREEN,
   BLUE,
   VIOLET
}

Dan tambahkan medan warna pada kelas Pengguna :


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Column(name="favorite_color")
   public Color favoriteColor;
 
   @Column(name="created_date")
   public Date createdDate;
}

Jika kita mahu Hibernate menyimpan jenis Warna ke pangkalan sebagai nombor , maka kita memerlukan medanwarna kegemarantambah anotasi:


@Enumerated(EnumType.ORDINAL)

Jika kita mahu nilai disimpan sebagai strings , maka kita perlu menambah anotasi:


@Enumerated(EnumType.STRING)

Contoh:


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Enumerated(EnumType.ORDINAL) //value will be saved to the base as a number
   @Column(name="favorite_color")
   public Color favoriteColor;
 
   @Column(name="created_date")
   public Date createdDate;
}

Mapim Boolean

Senario berguna kedua ialah pemetaan jenis boolean. Ia berlaku secara sejarah bahawa SQL tidak mempunyai jenis data sendiri untuk Boolean dan sebaliknya digunakan apa-apa di sana.

Tiga pilihan yang paling biasa ialah:

  • 1 atau 0
  • 'F' atau 'T'
  • 'Y' atau 'N'

Secara umum, jika anda akan mereka bentuk pangkalan anda, maka lebih baik menulis jenis BIT dengan segera. Nah, pemetaan penuh untuknya akan kelihatan seperti ini:


	@Column(name = "is_correct", columnDefinition = "BIT")
	@Type(type = "org.hibernate.type.NumericBooleanType")
    private Boolean isCorrect;

Nah, jika anda tidak mereka bentuk pangkalan data, lihat jadual di atas dan fikirkan cara memetakan jenis yang anda perlukan dengan betul.

Medan yang dikira

Kadangkala bilangan medan dalam kelas Entiti dan bilangan lajur dalam jadual tidak sepadan. Mungkin terdapat beberapa sebab untuk ini.

Yang paling biasa ialah apabila terdapat beberapa medan dalam kelas Entiti kami yang kami tidak mahu simpan ke pangkalan data. Semuanya jelas dengan ini - hanya tambah anotasi @Transient pada medan sedemikian dan Hibernate akan mengabaikannya apabila bekerja dengan pangkalan data.

Contoh:


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Transient
           	public Integer total;
}

Ini adalah pilihan yang baik, tetapi apabila membaca objek dari pangkalan data, jumlah medan akan menjadi batal. Dan kami ingin ia mengandungi produk lebar*tinggi. Ini juga boleh dilakukan dalam Hibernate. Terdapat anotasi @Formula khas untuk ini .


@Entity(name = "Square")
public class Square {
           	@Id
           	public Long id;
 
           	public Integer width;
 
           	public Integer height;
 
           	@Formula(value = " width * height ")
          	public Integer total;
}

Medan sedemikian tidak akan disimpan ke pangkalan data, dan apabila objek dibaca daripada pangkalan data, nilai yang dikira oleh formula akan ditulis kepadanya.

Pertanyaan SQL akan kelihatan seperti ini:

 SELECT id, width, height, (width* height) AS total FROM Square;

@Terbenam

Satu lagi anotasi berguna ialah @Embedded . Ia membolehkan anda menganggap medan objek kanak-kanak sebagai medan kelas Entiti itu sendiri.

Katakan anda mempunyai kelas Pengguna dan anda memutuskan untuk menambah alamat padanya:


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
    public Integer id;
 
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
 
   @Column(name="created_date")
    public Date createdDate;
}

Segala-galanya nampaknya baik-baik saja, tetapi dari sudut pandangan Java, adalah logik untuk meletakkan alamat dalam kelas yang berasingan. Alamat masih entiti yang berasingan. Tetapi bagaimana untuk melakukan ini jika semua maklumat ini disimpan dalam pangkalan data dalam jadual pengguna?

Anotasi @Embedded akan membantu kami . Pertama, kami akan mencipta kelas UserAddress dan meletakkan semua maklumat pada alamat pengguna ke dalamnya:


@Embeddable
class UserAddress
{
   @Column(name="user_address_country")
   public String country;
   @Column(name="user_address_city")
   public String city;
   @Column(name="user_address_street")
   public String street;
   @Column(name="user_address_home")
   public String home;
}

Dan kemudian kami menggunakan medan kelas ini dalam kelas Pengguna kami :


@Entity
@Table(name="user")
class User
{
   @Column(name="id")
   public Integer id;
 
   @Embedded
   public UserAddress address;
 
   @Column(name="created_date")
   public Date createdDate;
}

Terima kasih kepada anotasi @Embedded , pada masa menyimpan objek, Hibernate akan memahami bahawa medan kelas UserAddress perlu dianggap sebagai medan kelas Pengguna itu sendiri .

Penting! Jika anda memutuskan untuk menambah dua medan UserAddress pada kelas Pengguna anda , maka menggunakan @Embedded tidak akan berfungsi lagi: anda akan mempunyai medan pendua dan anda perlu memisahkannya entah bagaimana. Ini dilakukan dengan mengatasi anotasi: menggunakan @AttributeOverrides anotasi .

Saya mahu anda tahu perkara ini, tetapi kami tidak akan menerangkan secara terperinci di sini. Saya rasa ini sudah cukup untuk awak pecahkan kepala awak. Bagi yang ingin tahu, saya boleh meninggalkan pautan ke dokumentasi rasmi .