使用反射封裝ORM框架,真香!

在前幾篇文章中,我對反射機制進行了詳細的介紹,並且使用反射手寫了一個SpringIOC框架。爲了鞏固和加深對反射機制的理解,本篇文章將使用反射封裝一個簡單的ORM框架。如果對反射不太熟悉的小夥伴,可以看我之前寫的幾篇文章【反射詳解】【使用反射手寫SpringIOC】,知識點非常齊全,相信看完以後,你一定會有所收穫,並且可以更好的理解本篇文章。

我們在做開發的過程中,需要經常對數據庫進行操作,這時我們就需要使用到ORM框架,例如比較常用的MyBatis和Hibernate。下面我將對ORM框架進行詳細的介紹並且封裝一個簡單的ORM框架。

1.什麼是ORM框架?

ORM,即0bject Relational Mapping (對象關係映射),它的作用是在關係型數據庫和業務實體對象之間作一個映射,這樣我們在具體的操作業務對象的時候,就不需要再去和複雜的SQL語句打交道,只需簡單的操作對象的屬性和方法即可。
簡單來講,就是通過類與數據庫表的映射關係,將對象持久化到數據庫中。
在這裏插入圖片描述

2.ORM框架的優點

當我們不使用ORM框架開發一個應用程序時,需要寫很多sql語句,每一次執行,都要打開/關閉數據連接,這樣在開發的過程是很麻煩的,而且開發效率低。並且像讀取、保存和刪除對象信息這些代碼都是重複的,會造成代碼冗餘。而使用ORM框架可以很好的解決這些問題,使我們減少很多繁瑣重複的工作量,讓我們的注意力集中在實現業務上。

ORM框架優點如下:

  1. 操作簡單,提高了開發效率;
  2. 減少重複代碼,消除冗餘;
  3. 數據訪問更抽象,更輕便;
  4. 支持面向對象封裝。

3.使用反射封裝ORM框架

下面我將使用反射機制封裝一個簡單的ORM框架來實現插入功能。

3.1創建數據庫表

首先需要創建一個數據庫表,下面我們就使用user表進行演示。

create table user(
userId varchar(20) PRIMARY KEY not null,
userName varchar(20) not null,
password varchar(20) not null,
emil varchar(20) not null
);

3.2創建實體類

接着我們需要創建user表所對應的實體類。

public class User {
    public String userId;
    public String userName;
    public String password;
    public String emil;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String 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 String getEmil() {
        return emil;
    }

    public void setEmil(String emil) {
        this.emil = emil;
    }
}

3.3使用反射進行封裝

使用反射把獲取屬性和屬性值的功能進行封裝,更有利於擴展。

public class DBUtils {
    static final String  JDBC_DRIVER="com.mysql.jdbc.Driver";
    //數據庫連接地址,根據自己的實際情況就行修改
    static final String DB_URL="jdbc:mysql://127.0.0.1:3306/orm?useUnicode=true&characterEncoding=utf-8&useSSL=false";
    //用戶名和密碼,根據自己的實際情況就行修改
    static final String USER="root";
    static final String PASSWORD="root";

    /**
     * 連接數據庫
     * @return
     * @throws Exception
     */
    public static Connection getConnection() throws Exception {
        Connection connection=null;
        try{
            //1.加載驅動程序
            Class.forName(JDBC_DRIVER);
            //2.獲得數據庫鏈接
            connection= DriverManager.getConnection(DB_URL, USER, PASSWORD);
            System.out.println("數據庫連接成功!");
        }catch (Exception e){
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 插入數據
     * @return
     * @param obj
     */
    public static boolean insert(Object obj) throws Exception {
        //1.獲取數據庫連接
        Connection conn=getConnection();
        //2.通過反射獲取類對象
        Class cls = obj.getClass();
        //3.獲取表名
        String tableName=cls.getSimpleName();
        //4.拼接sql語句
        SQL sql = new SQL();
        sql.INSERT_INTO(tableName);
        sql.VALUES(Field(obj), FieldValue(obj));
        String s=sql.toString();
        //5.執行
        Statement statement=conn.createStatement();
        int result=statement.executeUpdate(s);
        if(result!=0){
            System.out.println("插入數據成功!");
            return true;
        }

        return false;
    }

    /**
     * 封裝當前類的所有屬性,拼接屬性sql
     * @param obj
     * @return
     */
    public static String Field(Object obj) {
        if (obj == null) {
            return null;
        }
        // 獲取class文件
        Class cls = obj.getClass();
        // 獲取當前類所有屬性
        Field[] Fields = cls.getDeclaredFields();
        String fieldSql = getField(Fields);
        return fieldSql ;
    }

    /**
     * 獲取所有屬性並拼接成sql
     * @param declaredFields
     * @return
     */
    public static String getField(Field[] declaredFields) {
        StringBuffer sf = new StringBuffer();
        for (int i = 0; i < declaredFields.length; i++) {
            sf.append(declaredFields[i].getName());
            if (i < declaredFields.length - 1) {
                sf.append(",");
            }
        }
        return sf.toString();
    }

    /**
     * 封裝當前類的所有屬性值,拼接屬性值sql
     * @param obj
     * @return
     */
    public static String FieldValue(Object obj) {
        if (obj == null) {
            return null;
        }
        // 獲取class文件
        Class cls = obj.getClass();
        // 獲取當前類的屬性值
        Field[] Fields = cls.getDeclaredFields();
        String fieldValueSql = getFieldValue(obj, Fields);
        return fieldValueSql ;
    }

    /**
     * 獲取所有屬性值並拼接成sql
     * @param obj
     * @param declaredFields
     * @return
     */
    public static String getFieldValue(Object obj, Field[] declaredFields) {
        StringBuffer sf = new StringBuffer();
        for (int i = 0; i < declaredFields.length; i++) {
            // 獲取到屬性值
            try {
                Field field = declaredFields[i];
                // 允許操作私有屬性
                field.setAccessible(true);
                // 獲取當前屬性的值
                Object value = field.get(obj);
                // 標識類型是否爲string類型
                boolean flag = false;
                if (value != null && (value instanceof String || value instanceof Timestamp)) {
                    flag = true;
                }
                //如果是String類型,則加上'',不是則不加
                if (flag) {
                    sf.append("'"+value+"'");
                } else {
                    sf.append(value);
                }
                if (i < declaredFields.length - 1) {
                    sf.append(",");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sf.toString();
    }
}

3.4效果演示

public class Test {
    public static void main(String[] args) throws Exception {
        User user=new User();
        user.setUserId("000001");
        user.setUserName("zhangsan");
        user.setPassword("123456");
        user.setEmil("[email protected]");
        DBUtils.insert(user);
    }
}

運行結果
在這裏插入圖片描述
數據庫user表
在這裏插入圖片描述
由運行結果可以看出,使用ORM框架插入數據成功。

我把源碼打包放在了百度雲網盤裏面,如果有需要的請自取【源碼地址】提取碼【c3at】
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章