說明:本文註釋的不是很多,只是功能上能簡單的基本達到。要看詳細的說明可參考另一篇博文超詳細的Hibernate關聯關係之雙向的一對多關聯關係的CRUD操作————學習至黑馬程序員視頻教程。。當然,one-to-one , many-to-one , many-to-many 這幾個標籤的屬性都各不相同,當用到的時還是需要去查看相關文檔的。
=================================================================
1.項目結構:
============================
2.pom.xml
<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.lin</groupId>
<artifactId>Hibernate_OneToOne</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.10.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.6.10.Final</version>
</dependency>
<!-- MySQL驅動包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!-- jstl、servlet-api、junit -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
============================
3.實體類跟其對應的映射文件:
User.java
package com.lin.domain;
import java.io.Serializable;
/**
* 用戶實體類
* */
public class User implements Serializable{
private static final long serialVersionUID = 1L;
private Long userId;
private String userName;
private String password;
//一個用戶只能對應一個身份證,一個身份證只能被一個用戶擁有。所以用戶和身份證是一對一關聯關係。
private Card card;
public User() {
super();
}
public User(Long userId, String userName, String password) {
super();
this.userId = userId;
this.userName = userName;
this.password = password;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
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 Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName
+ ", password=" + password + "]";
}
}
User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lin.domain">
<!-- name指定持久化類的類名,table指定數據表的表名 -->
<class name="User" table="table_user">
<id name="userId" column="user_id">
<generator class="native"/>
</id>
<property name="userName" column="user_name"></property>
<property name="password" column="password"></property>
<!--映射關聯屬性card。cascade="all"表示級聯保存User對象關聯的Card對象-->
<one-to-one name="card" class="Card" cascade="all" property-ref="user"></one-to-one>
</class>
</hibernate-mapping>
Card.java
package com.lin.domain;
import java.io.Serializable;
/**
* 身份證實體類
* */
public class Card implements Serializable{
private static final long serialVersionUID = 1L;
private Long cardId;
private String cardNumber;
//一個用戶只能對應一個身份證,一個身份證只能被一個用戶擁有。所以用戶和身份證是一對一關聯關係。
private User user;
public Card() {
super();
}
public Card(Long cardId, String cardNumber) {
super();
this.cardId = cardId;
this.cardNumber = cardNumber;
}
public Long getCardId() {
return cardId;
}
public void setCardId(Long cardId) {
this.cardId = cardId;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Card [cardId=" + cardId + ", cardNumber=" + cardNumber + "]";
}
}
Card.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lin.domain">
<!-- name指定持久化類的類名,table指定數據表的表名 -->
<class name="Card" table="table_card">
<id name="cardId" column="card_id">
<generator class="native"/>
</id>
<property name="cardNumber" column="card_number"></property>
<many-to-one name="user" class="User" unique="true">
<!--column屬性指定用來進行關聯的外鍵列列名-->
<column name="user_id"></column>
</many-to-one>
</class>
</hibernate-mapping>
============================
4.hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!--
Hibernate配置文件包含了連接持久層與映射文件所需的基本信息。
(Hibernate配置文件主要用來配置數據庫連接以及Hibernate運行時所需的各個屬性的值。)
-->
<hibernate-configuration>
<session-factory>
<!-- 數據庫連接設置 -->
<!-- 配置數據庫JDBC驅動 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 配置數據庫連接URL -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<!-- 配置數據庫用戶名 -->
<property name="hibernate.connection.username">root</property>
<!-- 配置數據庫密碼 -->
<property name="hibernate.connection.password">000000</property>
<!-- 配置JDBC內置連接池 -->
<property name="connection.pool_size">1</property>
<!-- 配置數據庫方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置Hibernate採用何種方式生成DDL語句 -->
<!-- update表示檢測實體類的映射配置和數據庫的表結構是否一致 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 輸出運行時生成的SQL語句 -->
<property name="show_sql">true</property>
<!-- 列出所有的映射文件 -->
<mapping resource="hibernate/mappings/User.hbm.xml" />
<mapping resource="hibernate/mappings/Card.hbm.xml" />
</session-factory>
</hibernate-configuration>
============================
5.hibernate工具類:
HibernateUtil.java
package com.lin.utils;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static Configuration configuration;
//創建線程局部變量threadLocal,用來保存Hibernate的Session
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
//使用靜態代碼塊初始化Hibernate
static{
try{
//如果不指定hibernate的配置文件位置,那麼它會默認到classpath路徑下查找名爲hibernate.cfg.xml的文件
Configuration cfg = new Configuration().configure("/hibernate/hibernate.cfg.xml");
//創建SessionFactory
sessionFactory = cfg.buildSessionFactory();
}catch(Throwable ex){
throw new ExceptionInInitializerError(ex);
}
}
//獲得SessionFactory
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
//獲得ThreadLocal對象管理的Session實例
public static Session getSession() throws HibernateException {
Session session = (Session)threadLocal.get();
if(session == null || session.isOpen()){
if(sessionFactory == null){
rebuildSessionFactory();
}
//通過SessionFactory對象創建Session對象
session = (sessionFactory != null)?sessionFactory.openSession():null;
//將新打開的Session實例保存到線程局部變量threadLocal中
threadLocal.set(session);
}
return session;
}
//關閉Session實例
public static void closeSession() throws HibernateException {
//從線程局部變量threadLocal中獲取之前存入的Session實例
Session session = (Session)threadLocal.get();
threadLocal.set(null);
if(session != null){
session.close();
}
}
//重建SessionFactory
public static void rebuildSessionFactory() {
try{
configuration.configure("/hibernate/hibernate.cfg.xml");
sessionFactory = configuration.buildSessionFactory();
}catch(Exception e){
System.out.println("Error Creating SessionFactory ");
e.printStackTrace();
}
}
//關閉緩存和連接池
public static void shutdown(){
getSessionFactory().close();
}
public static void main(String[] args){
HibernateUtil.getSession();
}
}
============================
6.一對一關聯關係的CRUD操作:
這邊測試的時候有遇到一個問題,就是插入數據的時候,明明在many-to-one 中設置了unique,該外鍵字段還是可以重複的。難道要在數據庫建表的時候設置唯一約束?(我這裏的表是通過配置好映射文件後,由Hibernate自動創建表的。。還望大神指教啊,,,)
HibernateOneToOneTest.java
package com.lin.test;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.lin.domain.Card;
import com.lin.domain.User;
import com.lin.utils.HibernateUtil;
/**
* 一對一關聯映射的CRUD操作。
* */
public class HibernateOneToOneTest {
/**
* 級聯保存操作1(保存用戶,級聯保存身份證)
* 找到User的映射文件,在one-to-one標籤上添加屬性 cascade="all"即可。
*
* 級聯保存操作2(保存身份證,級聯保存用戶)
* 找到Card的映射文件,在many-to-one標籤上添加屬性 cascade="save-update"即可。
* */
@Test
public void saveTest1(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
User user = new User();
user.setUserName("林6");
user.setPassword("123456");
Card card = new Card();
card.setCardNumber("350111111111111111");
user.setCard(card);
card.setUser(user);
// session.save(user);
session.save(card);
tx.commit();
session.close();
}
/**
* 測試用同一個身份證去關聯多個用戶
* (這裏的測試是能添加進去的,因爲many-to-one一方已經加了unique約束,不知道爲什麼還是添加進去)
* */
@Test
public void saveTest2(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
User user = (User) session.get(User.class,1L);
Card card = new Card();
card.setCardNumber("350111111111111111");
card.setUser(user);
session.save(card);
tx.commit();
session.close();
}
/**
* 刪除操作
* (我這裏測試的要找到User的映射文件中的one-to-one標籤設置 property-ref="user"後方可級聯刪除數據)
* */
@Test
public void deleteTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
//根據id查詢用戶
User user = (User) session.get(User.class, 3L);
//刪除用戶
session.delete(user);
tx.commit();
session.close();
}
/**
* 更新操作
* (僅修改了用戶關聯的身份的信息)
* */
@Test
public void updateTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
//根據id查詢用戶
User user = (User) session.get(User.class, 2L);
//更新用戶關聯的身份證信息
user.getCard().setCardNumber("350000000000000000");
session.update(user);
tx.commit();
session.close();
}
/**
* 更新操作
* (僅修改了用戶的信息)
* */
@Test
public void updateTest2(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
//根據id查詢用戶
User user = (User) session.get(User.class, 2L);
user.setUserName("小楊");
session.update(user);
tx.commit();
session.close();
}
/**
* 查詢操作
* (對象導航查詢)
* */
@Test
public void selectTest(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
// String HQL = "from User where userId= ?";
String HQL = "from User where userId = :userId";
// Query query = session.createQuery(HQL).setLong(0, 2L);
// Query query = session.createQuery(HQL).setLong("userId", 2L);
// Query query = session.createQuery(HQL).setParameter(0, 2L);
Query query = session.createQuery(HQL).setParameter("userId", 2L);
//執行完查詢後,就發起了兩個查詢(把關聯對象也查出來了)
User user = (User) query.uniqueResult();
System.out.println(user);
System.out.println(user.getCard());
tx.commit();
session.close();
}
}