Hibernate for Beginners
This tutorial is for newbies who want to learn Hibernate in a quite easy way.
disadvantages of accessing the database via JDBC directly
try {
PreparedStatement statement = conn.prepareStatement(insertItemSql);
statement.setString(1, item.getId());
statement.setString(2, item.getTitle());
statement.setString(3, item.getLocation());
statement.setString(4, item.getCompanyLogo());
statement.setString(5, item.getUrl());
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
- Too many columns need to be set, too much code change needed if we add more data later.
- Error-prone approach to set data.
- SQL adjustment when switching to different DB.
ORM
sql = "CREATE TABLE items ("
+ "item_id VARCHAR(255) NOT NULL,"
+ "name VARCHAR(255),"
+ "address VARCHAR(255),"
+ "image_url VARCHAR(255),"
+ "url VARCHAR(255),"
+ "PRIMARY KEY (item_id)"
+ ")";
@Entity
@Table(name = "items")
public class Item {
@Id
@Column(name = "item_id")
private String id;
private String address;
private String url;
private String name;
@Column(name = "image_url")
private String imageUrl;
}
Important annotations used for mapping
javax.persistence.Entity: Used with model class to specify that it is an entity and mapped to a table in the database.
javax.persistence.Table: Used with entity class to define the corresponding table name in the database.
javax.persistence.Id: Used to define the primary key in the entity class.
javax.persistence.Column: Used to define the column name in the database table.
javax.persistence.OneToOne: Used to define the one-to-one mapping between two entity classes. We have other similar annotations as OneToMany, ManyToOne and ManyToMany
OneToOne: extended information, e.g, Customer and Cart.
ManyToOne: Foreign Key. It references the property from another Entity.
OneToMany: The other direction of foreign keys. List of referencing entities.
ManyToMany: Between two entities where one can have relations with multiple other entity instances, for example, item and user relationships on the first project.
Why hibernate entity is serialized
To store objects in a relation database, queries must be executed. in JDBC, you write these queries yourself. Hibernate writes the queries for you, but it must first know how to convert entities to data that it can store in a database. This is why it uses Java’s serialization mechanism
实现序列化的两个原因:1、将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;2、按值将对象从一个应用程序域发送至另一个应用程序域。实现serializable接口的作用是就是可以把对象存到字节流,然后可以恢复,所以你想如果你的对象没实现序列化怎么才能进行持久化和网络传输呢,要持久化和网络传输就得转为字节流,所以在分布式应用中及设计数据持久化的场景中,你就得实现序列化。
第二个问题,是不是每个实体bean都要实现序列化,答案其实还要回归到第一个问题,那就是你的bean是否需要持久化存储媒体中以及是否需要传输给另一个应用,没有的话就不需要,例如我们利用fastjson将实体类转化成json字符串时,并不涉及到转化为字节流,所以其实跟序列化没有关系。
serialVersionUID
it can be generated by IDEA
composite
Modeling a composite identifier using an EmbeddedId simply means defining an embeddable to be a composition for one or more attributes making up the identifier, and then exposing an attribute of that embeddable type on the entity.
sql = "CREATE TABLE favorite_records ("
+ "user_id VARCHAR(255) NOT NULL,"
+ "item_id VARCHAR(255) NOT NULL,"
+ "last_favor_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ "PRIMARY KEY (user_id, item_id),"
+ "FOREIGN KEY (user_id) REFERENCES users(id),"
+ "FOREIGN KEY (item_id) REFERENCES items(id)"
+ ")";
@Embeddable
public class PK implements Serializable {
@Column(name = "item_id")
private String itemId;
@Column(name = "user_id")
private String userId;
}
@Entity
@Table(name = "favorite_records")
public class FavoriteRecords {
@EmbeddedId
private PK ck;
private Date timestamp;
}
---------------------------------------------------------------
public class PK implements Serializable {
private String itemId;
private String userId;
}
@Entity
@Table(name = "favorite_records")
@IdClass(PK.class)
public class FavoriteRecords {
@Id
private String itemId;
@Id
private String userId;
private Date timestamp;
}
Customer 1 : 1 Cart
Customer {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(unique = true)
private Cart cart;
...
public Cart getCart() {}
setCart
}
Cart 1 : N OrderItem
Cart {
@OneToMany(mappedBy="cart", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<OrderItem> orderItemList;
...
public List<OrderItem> getOrderItemList() {}
setOrderItemList
}
OrderItem N : 1 MenuItem
OrderItem {
@ManyToOne
private MenuItem menuItem;
@ManyToOne
@JsonIgnore
private Cart cart;
...
public MenuItem getMenuItem() {
return menuItem;
}
public void setMenuItem(MenuItem menuItem) {
this.menuItem = menuItem;
}
public Cart getCart() {
return cart;
}
public void setCart(Cart cart) {
this.cart = cart;
}
}
Restaurant 1 : N MenuItem
MenuItem {
@ManyToOne
@JsonIgnore
private Restaurant restaurant;
...
public Restaurant getRestaurant() {}
setRestaurant
}
Restaurant {
@OneToMany(mappedBy = "restaurant", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonIgnore
private List<MenuItem> menuItemList;
...
public List<MenuItem> getMenuItemList() {
return menuItemList;
}
public void setMenuItemList(List<MenuItem> menuItemList) {
this.menuItemList = menuItemList;
}
}
set up application
ApplicationConfig.java
Bootstrapping Hibernate 5 with Spring
Main.java
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfig.class)