首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Hibernate 映射 MySQL YEAR 類型字段的賦值方法

     編輯:程式設計綜合問答

問題場景

MySQL 表中有 YEAR(4) 類型字段 (如 birth_year),Java 實體類對應屬性為 java.sql.Date,需將字符串 "1990" 正確保存。

映射關鍵點

  1. 數據庫類型:YEAR 存儲 1901-2155 年份,1 字節。
  2. Java 類型選擇:
    • Integer / int (最推薦,直接對應年份數值)
    • Short / short
    • java.sql.Date (需設置具體日期, 如 1990-01-01, 但僅年份有效)
    • java.time.Year (Java 8+, 需自定義類型映射)
  3. Hibernate 映射:正確配置列類型與 Java 類型轉換。

方案一:實體屬性用 Integer (最簡單、推薦)


// 實體類
@Entity
@Table(name = "user")
public class User {
    @Id @GeneratedValue
    private Long id;
    
    @Column(name = "birth_year", columnDefinition = "YEAR")
    private Integer birthYear; // 對應 YEAR 類型
    
    // getter/setter
    public Integer getBirthYear() { return birthYear; }
    public void setBirthYear(Integer birthYear) { this.birthYear = birthYear; }
}

// Service 中賦值保存
String s = "1990";
User user = new User();
user.setBirthYear(Integer.parseInt(s)); // 字符串轉 Integer
session.save(user); // 或 hibernateTemplate.save(user)

方案二:實體屬性用 java.sql.Date (需轉換)


// 實體類
@Column(name = "birth_year")
@Type(type = "java.sql.Date") // 或依賴默認映射
private Date birthYear; // java.sql.Date

// 賦值邏輯
String s = "1990";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
try {
    java.util.Date utilDate = sdf.parse(s); // 解析為 1990-01-01 00:00:00
    user.setBirthYear(new java.sql.Date(utilDate.getTime())); // 轉 sql.Date
} catch (ParseException e) { /* 處理異常 */ }
session.save(user);

注意:數據庫存儲時僅保留年份部分,讀出時日期會變為該年的 1 月 1 日。

方案三:自定義 UserType 映射 java.time.Year (Java 8+)


// 實現 UserType
public class YearUserType implements UserType {
    @Override public int[] sqlTypes() { return new int[]{Types.SMALLINT}; } // YEAR 映射為 SMALLINT
    @Override public Class returnedClass() { return Year.class; }
    @Override public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
        int year = rs.getInt(names[0]);
        return year != 0 ? Year.of(year) : null;
    }
    @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
        if (value == null) st.setNull(index, Types.SMALLINT);
        else st.setInt(index, ((Year)value).getValue());
    }
    // ... 其他方法按規範實現 ...
}

// 實體類使用
@Type(type = "com.example.type.YearUserType")
@Column(name = "birth_year")
private Year birthYear;

// 賦值
user.setBirthYear(Year.parse("1990")); // Year.of(1990)

總結建議

方案優點缺點適用場景
Integer簡單、高效、無轉換損失、類型安全無絕大多數業務場景 首選
java.sql.Date兼容舊代碼/日期 API需解析格式化、存讀不對稱 (日期變 1月1日)歷史項目維護
java.time.Year + UserType語義豐富、類型安全、現代 API需編寫樣板代碼、增加複雜度領域模型驅動設計、嚴格類型要求

核心提示:確保實體屬性類型與數據庫列類型在 Hibernate 映射中兼容,Integer 是處理 MySQL YEAR 最自然的選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved