高級特性—多表查詢及自定義結(jié)果集數(shù)據(jù)處理

2018-12-24 22:23 更新
多表查詢及自定義結(jié)果集數(shù)據(jù)處理

JDBC模塊提供的ORM主要是針對單實體操作,實際業(yè)務(wù)中往往會涉及到多表關(guān)聯(lián)查詢以及返回多個表字段,在單實體ORM中是無法將JDBC結(jié)果集記錄自動轉(zhuǎn)換為實體對象的,這時就需要對結(jié)果集數(shù)據(jù)自定義處理來滿足業(yè)務(wù)需求。

若想實現(xiàn)結(jié)果集數(shù)據(jù)的自定義處理,需要了解以下相關(guān)接口和類:

  • IResultSetHandler接口:結(jié)果集數(shù)據(jù)處理接口,用于完成將JDBC結(jié)果集原始數(shù)據(jù)的每一行記錄進(jìn)行轉(zhuǎn)換為目標(biāo)對象,JDBC模塊默認(rèn)提供了該接口的三種實現(xiàn):

    EntityResultSetHandler:采用實體類存儲結(jié)果集數(shù)據(jù)的接口實現(xiàn),此類已經(jīng)集成在ISession會話接口業(yè)務(wù)邏輯中,僅用于處理單實體的數(shù)據(jù)轉(zhuǎn)換;

    MapResultSetHandler:采用Map存儲結(jié)果集數(shù)據(jù)的接口實現(xiàn);

    ArrayResultSetHandler:采用Object[]數(shù)組存儲結(jié)果集數(shù)據(jù)的接口實現(xiàn);

  • ResultSetHelper類:數(shù)據(jù)結(jié)果集輔助處理工具,用于幫助開發(fā)人員便捷的讀取和遍歷結(jié)果集中數(shù)據(jù)內(nèi)容,僅支持由 ArrayResultSetHandler 和 MapResultSetHandler 產(chǎn)生的結(jié)果集數(shù)據(jù)類型;

下面通過簡單的多表關(guān)聯(lián)查詢來介紹IResultSetHandler接口和ResultSetHelper類如何配合使用:

示例代碼一:使用ArrayResultSetHandler或MapResultSetHandler處理結(jié)果集數(shù)據(jù);

    IResultSet<Object[]> _results = JDBC.get().openSession(new ISessionExecutor<IResultSet<Object[]>>() {
        public IResultSet<Object[]> execute(ISession session) throws Exception {
            // 通過查詢對象創(chuàng)建SQL語句:
            //
            // SELECT u.id id, u.username username, ue.money money 
            //          FROM user u LEFT JOIN user_ext ue ON u.id = ue.uid
            //
            Select _uSelect = Select.create(User.class, "u")
                    .join(Join.left(UserExt.TABLE_NAME).alias("ue")
                            .on(Cond.create()
                                    .opt("u", User.FIELDS.ID, Cond.OPT.EQ, "ue", UserExt.FIELDS.UID)))
                    .field(Fields.create()
                            .add("u", User.FIELDS.ID, "id")
                            .add("u", User.FIELDS.USER_NAME, "username")
                            .add("ue", UserExt.FIELDS.MONEY, "money"));

            // 執(zhí)行查詢并指定采用Object[]數(shù)組存儲結(jié)果集數(shù)據(jù),若采用Map存儲請使用:IResultSetHandler.MAP
            return session.find(SQL.create(_uSelect), IResultSetHandler.ARRAY);
        }
    });

    // 采用默認(rèn)步長(step=1)逐行遍歷
    ResultSetHelper.bind(_results).forEach(new ResultSetHelper.ItemHandler() {
        public boolean handle(ResultSetHelper.ItemWrapper wrapper, int row) throws Exception {
            System.out.println("當(dāng)前記錄行數(shù): " + row);

            // 通過返回的結(jié)果集字段名取值
            String _id = wrapper.getAsString("id");
            String _uname = wrapper.getAsString("username");

            // 也可以通過索引下標(biāo)取值
            Double _money = wrapper.getAsDouble(2);

            // 也可以直接將當(dāng)前行數(shù)據(jù)賦值給實體對象或自定義JavaBean對象
            wrapper.toEntity(new User());

            // 當(dāng)賦值給自定義的JavaBean對象時需要注意返回的字段名稱與對象成員屬性名稱要一一對應(yīng)并且要符合命名規(guī)范
            // 例如:對象成員名稱為"userName",將與名稱為"user_name"的字段對應(yīng)
            wrapper.toObject(new User());

            // 返回值將決定遍歷是否繼續(xù)執(zhí)行
            return true;
        }
    });

    // 采用指定的步長進(jìn)行數(shù)據(jù)遍歷,此處step=2
    ResultSetHelper.bind(_results).forEach(2, new ResultSetHelper.ItemHandler() {
        public boolean handle(ResultSetHelper.ItemWrapper wrapper, int row) throws Exception {
            // 代碼略......
            return true;
        }
    });

示例代碼二:使用自定義IResultSetHandler處理結(jié)果集數(shù)據(jù);

    // 自定義JavaBean對象,用于封裝多表關(guān)聯(lián)的結(jié)果集的記錄
    public class CustomUser {

        private String id;

        private String username;

        private Double money;

        // 忽略Getter和Setter方法
    }

    // 修改示例一的代碼,將結(jié)果集中的每一條記錄轉(zhuǎn)換成自定義的CustomUser對象
    IResultSet<CustomUser> _results = JDBC.get().openSession(new ISessionExecutor<IResultSet<CustomUser>>() {
        public IResultSet<CustomUser> execute(ISession session) throws Exception {
            Select _uSelect = Select.create(User.class, "u")
                    .join(Join.left(UserExt.TABLE_NAME).alias("ue")
                            .on(Cond.create()
                                    .opt("u", User.FIELDS.ID, Cond.OPT.EQ, "ue", UserExt.FIELDS.UID)))
                    .field(Fields.create()
                            .add("u", User.FIELDS.ID, "id")
                            .add("u", User.FIELDS.USER_NAME, "username")
                            .add("ue", UserExt.FIELDS.MONEY, "money"));

            // 通過實現(xiàn)IResultSetHandler接口實現(xiàn)結(jié)果集的自定義處理
            return session.find(SQL.create(_uSelect), new IResultSetHandler<CustomUser>() {
                public List<CustomUser> handle(ResultSet resultSet) throws Exception {
                    List<CustomUser> _results = new ArrayList<CustomUser>();
                    while (resultSet.next()) {
                        CustomUser _cUser = new CustomUser();
                        _cUser.setId(resultSet.getString("id"));
                        _cUser.setUsername(resultSet.getString("username"));
                        _cUser.setMoney(resultSet.getDouble("money"));
                        //
                        _results.add(_cUser);
                    }
                    return _results;
                }
            });
        }
    });

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號