고급 기능 - 다중 테이블 쿼리 및 사용자 정의 결과 세트 데이터 처리


다중 테이블 쿼리 및 사용자 정의 결과 집합 데이터 처리

JDBC 모듈에서 제공하는 ORM은 주로 단일 엔터티 작업을 위한 것입니다. 실제 비즈니스에는 다중 테이블 관련 쿼리와 단일 엔터티 ORM의 반환이 포함되는 경우가 많습니다. JDBC 결과 집합 레코드는 자동으로 엔터티 개체로 변환될 수 없습니다. 이 경우 비즈니스 요구 사항을 충족하려면 결과 집합 데이터의 사용자 지정 처리가 필요합니다.

결과 세트 데이터의 사용자 정의 처리를 구현하려면 다음과 같은 관련 인터페이스 및 클래스를 알아야 합니다.

  • IResultSetHandler 인터페이스: JDBC 결과 세트의 각 행 변환을 완료하는 데 사용되는 결과 세트 데이터 처리 인터페이스 원본 데이터를 Target 개체에 추가하면 JDBC 모듈은 기본적으로 이 인터페이스의 세 가지 구현을 제공합니다.

    EntityResultSetHandler: 엔터티 클래스를 사용하여 결과 집합 데이터를 저장하는 인터페이스 구현입니다. 이 클래스는 ISession 세션 인터페이스 비즈니스 논리에 통합되었습니다. 단일 엔터티를 처리하는 데만 사용됩니다.

    MapResultSetHandler: 결과 집합 데이터를 저장하기 위해 Map을 사용하는 인터페이스 구현

    ArrayResultSetHandler: 결과 집합 데이터를 저장하기 위해 Object[] 배열을 사용하는 인터페이스 구현.

    ResultSetHelper 클래스: 데이터 결과 세트를 위한 보조 처리 도구로, 개발자가 결과 세트의 데이터 내용을 쉽게 읽고 탐색할 수 있도록 ArrayResultSetHandler 및 MapResultSetHandler에서 생성된 결과 세트 데이터 유형만 지원됩니다.
  • 다음은 다음과 같습니다. 간단한 다중 테이블 연관 쿼리를 통해 IResultSetHandler 인터페이스와 ResultSetHelper 클래스를 함께 사용하는 방법:

  • 샘플 코드 1: ArrayResultSetHandler 또는 MapResultSetHandler를 사용하여 결과 세트 데이터 처리

    IResultSet<Object[]> _results = JDBC.get().openSession(new ISessionExecutor<IResultSet<Object[]>>() {
        public IResultSet<Object[]> execute(ISession session) throws Exception {
            // 通过查询对象创建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"));

            // 执行查询并指定采用Object[]数组存储结果集数据,若采用Map存储请使用:IResultSetHandler.MAP
            return session.find(SQL.create(_uSelect), IResultSetHandler.ARRAY);
        }
    });

    // 采用默认步长(step=1)逐行遍历
    ResultSetHelper.bind(_results).forEach(new ResultSetHelper.ItemHandler() {
        public boolean handle(ResultSetHelper.ItemWrapper wrapper, int row) throws Exception {
            System.out.println("当前记录行数: " + row);

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

            // 也可以通过索引下标取值
            Double _money = wrapper.getAsDouble(2);

            // 也可以直接将当前行数据赋值给实体对象或自定义JavaBean对象
            wrapper.toEntity(new User());

            // 当赋值给自定义的JavaBean对象时需要注意返回的字段名称与对象成员属性名称要一一对应并且要符合命名规范
            // 例如:对象成员名称为"userName",将与名称为"user_name"的字段对应
            wrapper.toObject(new User());

            // 返回值将决定遍历是否继续执行
            return true;
        }
    });

    // 采用指定的步长进行数据遍历,此处step=2
    ResultSetHelper.bind(_results).forEach(2, new ResultSetHelper.ItemHandler() {
        public boolean handle(ResultSetHelper.ItemWrapper wrapper, int row) throws Exception {
            // 代码略......
            return true;
        }
    });

샘플 코드 2: 사용자 정의 IResultSetHandler를 사용하여 결과 집합 데이터 처리
    // 自定义JavaBean对象,用于封装多表关联的结果集的记录
    public class CustomUser {

        private String id;

        private String username;

        private Double money;

        // 忽略Getter和Setter方法
    }

    // 修改示例一的代码,将结果集中的每一条记录转换成自定义的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"));

            // 通过实现IResultSetHandler接口实现结果集的自定义处理
            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;
                }
            });
        }
    });