91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java如何使用反射把對象轉換成MongoDb的結構

發布時間:2020-12-17 10:12:29 來源:億速云 閱讀:289 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關Java如何使用反射把對象轉換成MongoDb的結構的內容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

反射是 Java 的一個高級技巧,大量地用在各種開源項目上。比如,Spring、Tomcat、Jetty 等等項目中,都大量地用到了反射。

作為 Java 程序員,我們如果用好反射,不但能提高自己的技術水平,還能開發出更好的項目。

然而,雖然很多人聽說過反射,但卻不知道應該用在哪里。

那么,我們就從實際工作出發,使用反射,把對象轉換成 MongoDb 的數據結構。當你在搞懂這個例子后,就能明白反射是怎么個用法。

需求分析

在電商系統中,一些數據要保存到 MongoDb 中,以此來提高查詢的性能。但在此之前,我們必須把數據先轉換成 MongoDb 的結構,也就是把 Java 對象轉換成 Document。

比如,訂單信息要存到 MongoDb 中,就得把訂單對象轉換成 Document。

可這樣一來,每個實體類都得開發一個 2Doc() 方法。這個方法毫無技術含量,就是把各種字段 put 到 Document 里面。而且一旦字段多了,一不留神就會寫錯代碼,你感受一下。

public class Order {
    private Long id;
    private Long userId;
    private String orderNo;
    private BigDecimal amount;
    private String createTime;
    private String updateTime;
    // 省略無數字段
    
    // 轉換方法:訂單轉doc
    public Document order2Doc(Order order) {
        Document doc = new Document();

        doc.put("id", order.getId());
        doc.put("userId", order.getUserId());
        doc.put("orderNo", order.getOrderNo());
        doc.put("amount", order.getAmount());
        doc.put("createTime", order.getCreateTime());
        doc.put("updateTime", order.getUpdateTime());
        // 省略無數put...

        return doc;
    }
}

除此之外,我們還得從 MongoDb 中取數據,把 Document 轉換回 Java 對象,你再感受一下。

public class Order {
    private Long id;
    private Long userId;
    private String orderNo;
    private BigDecimal amount;
    private String createTime;
    private String updateTime;
    // 省略無數字段
    
    // 轉換方法:doc轉訂單
    public Order doc2Order(Document doc) {
        Order order = new Order();
        
        order.setId((Long) doc.get("id"));
        order.setUserId((Long) doc.get("userId"));
        order.setOrderNo((String) doc.get("orderNo"));
        order.setAmount((BigDecimal) doc.get("amount"));
        order.setCreateTime((String) doc.get("createTime"));
        order.setUpdateTime((String) doc.get("updateTime"));
        // 省略無數set...

        return order;
    }
}

光是一個訂單類都這么麻煩了,何況這樣的類不止一個,而且項目總有新需求,如果一個字段改了,那你麻煩大了,說不定要把整個項目翻一遍。

因此,為了少出錯,必須優化這兩個轉換方法,而這次優化用到了 Java 的兩個高級特性:反射、泛型。為了讓大家更直觀的了解,我將分成兩個版本迭代。

第一版,利用反射,簡化實體類的轉換方法;

第二版,利用泛型、反射,提取 MongoDb 工具類;

接下來,我們就一步步迭代吧~

利用反射,簡化實體類的轉換方法

在第一版的迭代中,我們要簡化實體類的兩個轉換方法。

我們先從 Java 對象轉 Document 開始,還是以 Order 類為例。

首先,我們通過反射,獲取到訂單類的所有字段信息;然后,使用循環遍歷這些字段;最后,在循環中,我們放開字段的訪問權限,把字段 put 到 Document 里面。

public class Order {
    // ...省略無數字段

    public Document order2Doc(Order order) throws Exception {
        Document doc = new Document();

        // 獲取所有字段:通過 getClass() 方法獲取 Class 對象,然后獲取這個類所有字段
        Field[] fields = order.getClass().getDeclaredFields();
        for (Field field : fields) {
            // 開放字段操作權限
            field.setAccessible(true);
            // 設置值
            doc.put(field.getName(), field.get(order));
        }

        return doc;
    }
}

你可以看到,經過反射改造后,代碼簡單了很多。一個對象無論有多少個字段,要寫多少 put 操作,只要這幾行代碼就能搞定。Java 對象轉成 MongoDb 的結構,看起來也不那么麻煩了。

照著這個思路,我們再來改造第二個方法,Document 轉 Java 對象。

public class Order {
    // ...省略無數字段

    public Order doc2Order(Document doc) throws Exception {
        Order order = new Order();

        for (String key : doc.keySet()) {
            // 獲取字段
            Field field = order.getClass().getDeclaredField(key);
            // 開放字段操作權限
            field.setAccessible(true);
            // 設置值
            field.set(order, doc.get(key));
        }

        return order;
    }
}

首先,我們使用循環遍歷 Document;在循環中,使用反射獲取相應的字段,再放開字段的訪問權限,把 Document 的值設置到對象的字段里。

到了這兒,我們利用反射,簡化了兩個實體類的轉換方法,第一版的迭代基本完成了。剩下的工作,就是復制粘貼,把各個類重新改造一遍。

然而,經過這一版迭代,雖然減少了很多工作,但依然有很多不合理的地方。

首先,重復代碼還是很多。每個實體類都有兩個轉換方法,但這兩個方法的核心邏輯是一樣的,完全沒必要到處復制。

然后,這不是實體類應該承擔的功能。實體類只負責短暫保留數據,不負責任何持久化功能。你把數據存到哪里,該轉換成什么數據結構,這和實體類沒什么關系。

換句話說,我們還得做第二次迭代。

利用泛型、反射,提取 MongoDb 工具類

簡單來說,泛型是一種風格或范式,你不用一開始就指明具體的參數類型,而是在使用的時候再確定參數類型。

如果把泛型、反射結合在一起,能幫我們減少很多重復代碼。

我們來看看,該怎么做第二次迭代?

先從 Java 對象轉 Document 開始。我們先聲明一個泛型方法;然后,通過反射,獲取泛型類的所有字段信息,再使用循環遍歷這些字段;最后,在循環中,把字段 put 到 Document 里面。

public class MongoDbUtils {

    // 定義泛型方法:
    // 1. 在返回值前,聲明泛型參數 <參數名>;
    // 2. 傳入參數時,指定一個泛型參數
    public static <T> Document obj2Doc(T obj) throws Exception {
        Document doc = new Document();

        // 獲取所有字段:通過 getClass() 方法獲取 Class 對象,然后獲取這個類所有字段
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            // 開放字段操作權限
            field.setAccessible(true);
            // 設置值
            doc.put(field.getName(), field.get(obj));
        }

        return doc;
    }
}

在加入泛型后,重復代碼大量減少了,實體類不用再單獨寫 2Doc()方法了。在使用的時候,只要調用 MongoDbUtils.obj2Doc() 就行。

按照同樣的思路,我們繼續來改造第二個方法,Document 轉 Java 對象。

public class MongoDbUtils {

    // 定義泛型方法:
    // 1. 在返回值前,聲明泛型參數 <參數名>;
    // 2. 傳入參數必須是 Class,但這個 Class 是泛型參數,不限制類型
    public static <T> T doc2Obj(Document doc, Class<T> clazz) throws Exception {
        // 實例化泛型對象
        T obj = clazz.newInstance();

        for (String key : doc.keySet()) {
            // 獲取字段
            Field field = clazz.getDeclaredField(key);
            // 開放字段操作權限
            field.setAccessible(true);
            // 設置值
            field.set(obj, doc.get(key));
        }

        return obj;
    }
}

首先,我們定義實例化一個泛型對象;然后,我們使用循環遍歷 Document;最后,在循環中,使用反射獲取相應的字段,把 Document 的值設置到泛型對象的字段里。

第二版的迭代就基本完成了。我們在第一版迭代的基礎上,加入了泛型,得到了一個工具類 MongoDbUtils,這個工具類得到結果和以前完全一樣,你可以看下測試代碼。

public static void main(String[] args) throws Exception {
    Order order = new Order();
    order.setId(0L);
    order.setUserId(0L);
    order.setOrderNo("1");
    order.setAmount(new BigDecimal("0"));
    order.setCreateTime("2");
    order.setUpdateTime("3");
    System.out.println("原始數據:" + order);

    Document document = MongoDbUtils.obj2Doc(order);
    System.out.println("轉換doc數據:" + document);

    Order order1 = MongoDbUtils.doc2Obj(document, Order.class);
    System.out.println("轉換java數據:" + order1);
}

運行結果:
原始數據:Order(id=0, userId=0, orderNo=1, amount=0, createTime=2, updateTime=3)
轉換doc數據:Document{{id=0, userId=0, orderNo=1, amount=0, createTime=2, updateTime=3}}
轉換java數據:Order(id=0, userId=0, orderNo=1, amount=0, createTime=2, updateTime=3)

這樣一來,我們就不用保留實體類上的轉換方法了,剩下的工作就是刪代碼。

MongoDb 和 Java 對象的互相轉換就完成了。我們做了兩次迭代,第一次迭代利用了反射,把大量手動 set/get 操作給去掉了;第二次迭代在原來的基礎上,加入了泛型的應用,又去掉了一堆重復代碼。

感謝各位的閱讀!關于Java如何使用反射把對象轉換成MongoDb的結構就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泰宁县| 乐山市| 保靖县| 葫芦岛市| 延寿县| 镇坪县| 仁怀市| 隆回县| 静乐县| 金阳县| 平阳县| 昭平县| 佳木斯市| 白玉县| 东乌| 东乡县| 弥勒县| 西青区| 周宁县| 梓潼县| 定边县| 万山特区| 哈密市| 浙江省| 伊川县| 鸡东县| 阳信县| 嘉祥县| 桐庐县| 怀来县| 南通市| 宁强县| 北碚区| 东乌珠穆沁旗| 文水县| 罗定市| 潞城市| 衡东县| 彭阳县| 苏州市| 潞西市|