手把手教你寫一個Java的orm框架(2)

何白白發表於2019-02-20

建立對映關係

​ 想要實現一個orm的功能,我覺得就是要將class和資料庫中的表建立對映關係。把class的名稱和表的名稱,class屬性名稱和表的欄位名稱,屬性型別與表的欄位型別一一對應起來。可以通過配置檔案,註解等等各種方式實現這個對映關係。

需要的依賴

​ 因為編寫配置檔案總是一件十分繁瑣的事情,所以我決定使用註解的方式來實現這個對映。在專案剛開始寫的時候我用的是自定義註解的方法。自己規定一套註解,後來覺得這樣沒有太大的必要,因為已經有jpa裡的一套註解。所以直接用就好了。所以新增依賴:

<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0</version>
</dependency>複製程式碼

這裡主要使用裡面的三個註解:

  1. @Id新增在作為id 的欄位上,標示為一個id,一個表中只能有一個id
  2. @Column新增在作為屬性的欄位上,name裡填寫表中的欄位名稱。
  3. @Table新增在作為屬性的欄位上,name裡填寫表的名稱。

其他的一些註解暫時不需要,因為我不需要完整的實現jpa裡面功能。

這樣就可以將一個class和一個表對映起來了。完成之後一個class大致上是這樣的:

sql:

CREATE TABLE `user` (                                                          
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者id',                         
  `name` varchar(225) DEFAULT NULL COMMENT '使用者名稱',                              
  `create_date` datetime DEFAULT NULL,                                         
  `status` int(11) DEFAULT NULL,                                               
  `age` int(11) DEFAULT NULL COMMENT '年齡',                                     
  `mark` varchar(225) DEFAULT NULL,                                            
  PRIMARY KEY (`id`)                                                           
) ENGINE=InnoDB AUTO_INCREMENT=2104778081 DEFAULT CHARSET=latin1 COMMENT='使用者表'複製程式碼

class:

import java.util.Date;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Id;

/**
 * 使用者表
 *
 * @author hejiaxuan
 */
@Table(name = "user")
public class User {

    /**
     * 使用者名稱
     */
    @Column(name = "name")
    private String name;

    /**
     * 使用者id
     */
    @Id
    @Column(name = "id")
    private int id;

    /**
     * 年齡
     */
    @Column(name = "age")
    private int age;

    /**
     * mark
     */
    @Column(name = "mark")
    private String mark;

    /**
     * create_date
     */
    @Column(name = "create_date")
    private Date createDate;

    /**
     * status
     */
    @Column(name = "status")
    private int status;

    //getter and setter and toString
}複製程式碼

資料型別

​ 上面在將各種名稱做了對映之後,還要根據java中的資料型別和sql中的資料型別新增一下對映關係,因為class中的資料型別和sql中的並不通用。

​ 這個東西簡單做的話其實不需要開發,在jdbc的ResultSet類中提供了一系列的方法:

String ResultSet.getString;
boolean ResultSet.getBoolean;
byte ResultSet.getByte;
short ResultSet.getShort;
int ResultSet.getInt;
long ResultSet.getLong;
float ResultSet.getFloat;
double ResultSet.getDouble;
BigDecimal ResultSet.getBigDecimal;
Bytes ResultSet.getBytes;
Date ResultSet.getDate;
Time ResultSet.getTime;複製程式碼

這裡可以根據class的屬性型別來分別的呼叫,也可以直接呼叫:Object ResultSet.getObject;這個方法,讓資料進行強制型別轉換。但是這裡有一定的規則,有些型別並不能轉換成功,下面是我在寫的時候遇到的可以轉換成功的資料關係:

sql資料型別java資料型別
VARCHARString.class
CHARString.class
TEXTString.class
MEDIUMTEXTString.class
LONGTEXTString.class
TINYTEXTString.class
BITBoolean.class
INTint.class
BIGINTlong.class
DOUBLEdouble.class
TINYINTint.class
FLOATfloat.class
DECIMALBigDecimal.class
INTint.class
BIGINTint.class
DECIMALBigDecimal.class
DATETIMEDate.class
TIMEDate.class
DATEDate.class
TIMESTAMPDate.class

按照這種關係建立class後,一般是不會碰到什麼很奇怪的錯誤的:-D

​ 如果想做的複雜一點,可以做一個資料型別轉換的工具,可以隨心所欲的轉換各種資料型別。但是這裡就不做了,其實也很簡單的,稍微想一想就能寫出來啦~~~。

這裡,class和表的對映就已經結束了,已經滿足了我對一個orm的需要,下一步就是要通過反射分析class並生成sql了~

閱讀原文


相關文章