環境說明
※Windows10 OS ver:1703
※IDEA 2017 2.3
※Hibernate 5.2.11
※JDK 1.8
※MySQL 5.7
話不多說,直接上代碼.本人初學框架,在網上搜了下,可能我不會搜索,沒找到好的基於註解的多表關聯的完整例子,導致我學起來很喫力.所以上傳上來我的代碼,希望能幫到和我一樣的初學者.
本人菜鳥,如有bug,請評論指出.以便及時改正,謝謝.
User.class
package com.cs.qsx.domain;
import javax.persistence.*;
import java.util.Set;
//聲明是一個映射實體類
@Entity
//指定實體類映射的表 name=表名(數據庫中的表名)
@Table(name = "tb_user")
public class User {
/**
* 包名: com.cs.qsx.domain
* 類名: User
* 類描述: 註解測試---------用戶類
* 作者: Lucifer
* 創建日期: 2017/9/22
* 創建時間: 19:51
*
**/
// @Id指定該屬性爲數據庫中表的主鍵
@Id
// @GeneratedValue指定主鍵的生成策略
/*
常用參數:
1.GenerationType.AUTO 根據底層數據庫自動選擇(默認),若數據庫支持自動增長類型,則爲自動增長。
2.GenerationType.INDENTITY`根據數據庫的Identity字段生成,支持DB2、MySQL、MS、SQL Server、SyBase與HyperanoicSQL數據庫的Identity類型主鍵。
3.GenerationType.SEQUENCE 註解聲明瞭一個數據庫序列、支持Oracle DB2.
4.GenerationType.TABLE 使用一張單表管理主鍵值 結合@TableGenerator使用.
*/
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
// @Column指定該屬性映射到表中的字段
/*
常用參數:
1.name 映射到表中的字段名,默認是屬性名
2.length 指定該字段的長度,String類型默認255
3.unique 該字段是否添加唯一性約束
4.nullable 該字段是否添加非空約束
*/
@Column(length = 16)
private String username;
@Column(length = 50)
private String password;
//@Transient 指定映射實體類到數據庫時忽略該字段
private int roll;
//mappedBy:表明當前類在指定類中的屬性名
//一對一雙向關聯
@OneToOne(mappedBy = "user")
private UserInfo userInfo;
/*
一個用戶有多個訂單,所以用set集合
*/
@OneToMany(mappedBy = "user",targetEntity = Order.class)
private Set<Order> orders;
public User(String username, String password, int roll) {
this.username = username;
this.password = password;
this.roll = roll;
}
public User() {
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public UserInfo getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getRoll() {
return roll;
}
public void setRoll(int roll) {
this.roll = roll;
}
}
UserInfo.class
package com.cs.qsx.domain;
import javax.persistence.*;
@Entity
@Table(name = "tb_userinfo")
public class UserInfo {
/**
* 包名: com.cs.qsx.domain
* 類名: UserInfo
* 類描述: 註解測試--------用戶詳情類
* 作者: Lucifer
* 創建日期: 2017/9/22
* 創建時間: 19:52
*
**/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 10)
private String realName;
@Column(length = 50)
private String job;
@Column(length = 2)
private String sex;
/*
UserInfo和User是一對一關係,採用外鍵關聯
UserInfo擁有user的外鍵
外鍵關係在hibernate中體現爲擁有類的對象
*/
/*
@OneToOne:體現一對一關係映射 配合@JoinColumn一起使用
@JoinColumn:多表關係中的外鍵字段
常用參數:
name:外鍵字段名稱
fetch:加載策略
FetchType.EAGER:勤加載
FetchType.LAZY:懶加載,如果是集合那麼就是懶加載
cascade:級聯設置,新增、修改、刪除
targetEnity:目標類的class
*/
@OneToOne(targetEntity = User.class,cascade = CascadeType.PERSIST,fetch = FetchType.EAGER)
@JoinColumn(name = "uid")
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public UserInfo(String realName, String job, String sex) {
this.realName = realName;
this.job = job;
this.sex = sex;
}
public UserInfo() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "UserInfo{" +
"id=" + id +
", realName='" + realName + '\'' +
", job='" + job + '\'' +
", sex='" + sex + '\'' +
", user=" + user +
'}';
}
}
Order.class
package com.cs.qsx.domain;
import javax.persistence.*;
import java.util.Set;
@Entity
@Table(name = "tb_order")
public class Order {
/**
* 包名: com.cs.qsx.domain
* 類名: Order
* 類描述: 註解測試-------訂單類
* 作者: Lucifer
* 創建日期: 2017/9/22
* 創建時間: 19:52
*
**/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private double money;
@Column(length = 10)
private String rname;
@Column(length = 11)
private String phone;
@Column(length = 100)
private String raddress;
/*
用戶和訂單是一對多的關係
*/
@ManyToOne(targetEntity = User.class)
@JoinColumn(name = "uid")
private User user;
/*
訂單和商品是多對多關係
*/
@ManyToMany
@JoinTable(name = "tb_orderitem",joinColumns = {@JoinColumn(name = "oid")},inverseJoinColumns = {@JoinColumn(name = "gid")})
private Set<Goods> goodsSet;
public Order(double money, String rname, String phone, String raddress) {
this.money = money;
this.rname = rname;
this.phone = phone;
this.raddress = raddress;
}
public Order() {
}
public Set<Goods> getGoodsSet() {
return goodsSet;
}
public void setGoodsSet(Set<Goods> goodsSet) {
this.goodsSet = goodsSet;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public String getRname() {
return rname;
}
public void setRname(String rname) {
this.rname = rname;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getRaddress() {
return raddress;
}
public void setRaddress(String raddress) {
this.raddress = raddress;
}
}
Goods.class
package com.cs.qsx.domain;
import javax.persistence.*;
import java.util.Set;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
//@Cache:開啓二級緩存的註解
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Entity
@Table(name = "tb_goods")
public class Goods {
/**
* 包名: com.cs.qsx.domain
* 類名: Goods
* 類描述: 註解測試-----商品類
* 作者: Lucifer
* 創建日期: 2017/9/22
* 創建時間: 19:52
*
**/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(length = 30)
private String name;
@Column(length = 30)
private String type;
private double price;
/*
商品和訂單是多對多
*/
/*
@ManyToMany:多對多映射
@JoinTable:隱式關係表,這張表沒有對應的實體類
*/
@ManyToMany
@JoinTable(name = "tb_orderitem",joinColumns = {@JoinColumn(name = "gid")},inverseJoinColumns = {@JoinColumn(name = "oid")})
private Set<Order> orders;
public Goods(String name, String type, double price) {
this.name = name;
this.type = type;
this.price = price;
}
public Goods() {
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8" ?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<!-- 約束文件-->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- 全局配置-->
<hibernate-configuration>
<!-- session工廠設置,也就是連接設置-->
<session-factory>
<!--1.配置數據庫驅動 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!--2.配置數據庫的url -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_cache?charset=UTF-8</property>
<!--3.配置用戶名和密碼 -->
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!--4.配置數據庫方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property>
<!--5.設置鍵表語句的執行:create or update -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--6.設置顯示自動生成的sql語句 -->
<property name="hibernate.show_sql">true</property>
<!--7.設置格式化顯示的sql語句 -->
<property name="hibernate.format_sql">true</property>
<!--開啓current_session支持 -->
<property name="hibernate.current_session_context_class">thread</property>
<!--開啓查詢緩存 -->
<property name="hibernate.cache.use_query_cache">true</property>
<!--開啓二級緩存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--使用的是哪個類管理二級緩存 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<!--8.引入映射配置文件 -->
<mapping class="com.cs.qsx.domain.User" />
<mapping class="com.cs.qsx.domain.UserInfo" />
<mapping class="com.cs.qsx.domain.Order" />
<mapping class="com.cs.qsx.domain.Goods" />
</session-factory>
</hibernate-configuration>
測試類:AnnoTest.class
package com.cs.qsx.test;
import com.cs.qsx.domain.Goods;
import com.cs.qsx.domain.Order;
import com.cs.qsx.domain.User;
import com.cs.qsx.domain.UserInfo;
import com.cs.qsx.utils.HiberUtils;
import com.cs.qsx.utils.Log;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
public class AnnoTest {
/**
* 包名: com.cs.qsx.test
* 類名: AnnoTest
* 類描述: 測試註解
* 作者: Lucifer
* 創建日期: 2017/9/22
* 創建時間: 19:50
**/
private Session session;
private Transaction transaction;
//@Before:@Test運行之前執行
@Before
public void before() {
session = HiberUtils.getCurrentSession();
transaction = session.beginTransaction();
}
//@After:@Test運行之後執行
@After
public void after() {
transaction.commit();
session.close();
}
@Test
public void test1() {
//測試一對一--------新增
User user = new User("mark", "111", 0);
session.save(user);
UserInfo userInfo = new UserInfo("張三", "IT", "男");
userInfo.setUser(user);
session.save(userInfo);
}
@Test
public void test2() {
//測試一對一-------查詢
UserInfo userInfo = session.get(UserInfo.class, 1l);
Log.info("用戶信息", userInfo);
Log.info("用戶", userInfo.getUser());
}
@Test
public void test3() {
//測試多對多------商品添加
for (int i = 0; i < 10; i++) {
Goods goods = new Goods("信陽毛尖" + i, "茶葉", 78 * (i + 2) + 100);
session.save(goods);
}
}
@Test
public void test4() {
//測試多對多------訂單添加(需開啓事務)
Order order = new Order(100, "李四", "10089389", "火星");
Set<Goods> goods = new HashSet<>();
goods.add(session.get(Goods.class, 11l));
goods.add(session.get(Goods.class, 14l));
User user = session.get(User.class, 1l);
order.setGoodsSet(goods);
order.setUser(user);
Log.info("添加訂單", session.save(order));
}
@Test
public void test5() {
//測試多對多--------查詢
Order order = session.get(Order.class, 1l);
Log.info("訂單", order.getRname() + "---" + order.getGoodsSet().size());
}
@Test
public void test6() {
//測試一對多-------查詢
User user = session.get(User.class, 1l);
Log.info("用戶", user.getUserInfo());
for (Order order : user.getOrders()) {
Log.info("用戶訂單", order.getId());
}
}
}
工具類:HiberUtils.class
package com.cs.qsx.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HiberUtils {
private static SessionFactory factory = new Configuration().configure().buildSessionFactory();
public static SessionFactory getFactory() {
return factory;
}
public static Session getSession(){
return factory.openSession();
}
public static Session getCurrentSession(){
return factory.getCurrentSession();
}
}
工具類:Log.class
package com.cs.qsx.utils;
public class Log {
private static final boolean isDebug = true;
public static void info(String info,Object msg){
if(isDebug){
System.out.println(info +": " + msg.toString());
}
}
public static void err(String info,Object msg){
if(isDebug){
System.err.println(info + ": " + msg.toString());
}
}
}
2017/9/22
Lucife