# ProductAttributeItemHistoryDaoImpl.java

    package com.mycim.server.spec.dao.impl;

    import com.mycim.framework.jdbc.JdbcTemplate;
    import com.mycim.framework.jdbc.Page;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.server.spec.dao.ProductAttributeItemHistoryDao;
    import com.mycim.server.spec.dao.mapper.ProductAttributeHistoryRowMapper;
    import com.mycim.valueobject.bas.TransactionLog;
    import com.mycim.valueobject.prp.ProductAttributeHistoryQueryDto;
    import com.mycim.valueobject.prp.ProductAttributeItem;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Repository;

    import java.util.ArrayList;
    import java.util.List;

    @Repository
    public class ProductAttributeItemHistoryDaoImpl implements ProductAttributeItemHistoryDao {

        @Autowired
        JdbcTemplate jdbcTemplate;

        @Override
        public void insertProductAttributeItemHistories(TransactionLog transactionLog,
                                                        List<ProductAttributeItem> productAttributeItems) {
            StringBuilder sql = new StringBuilder("INSERT INTO PROD_ATTRIBUTE_DETAIL_HIST  ");

            sql.append(" (TRANS_RRN, TRANS_ID, TRANS_SEQUENCE, TRANS_TIMESTAMP, TRANS_PERFORMED_BY, ");
            sql.append(" PRODUCT_RRN, PRODUCT_ID, PRODUCT_VERSION, PROCESS_RRN, PROCESS_ID, ");
            sql.append(" PROCESS_VERSION, ROUTE_SEQ, ROUTE_RRN, ROUTE_VERSION, ROUTE_ID, ");
            sql.append(" OPERATION_SEQ, OPERATION_RRN, OPERATION_ID, FLOW_SEQ, ATTRIBUTE_NAME, ATTRIBUTE_NAME_RRN, ");
            sql.append(" ATTRIBUTE_VALUE, ATTRIBUTE_VALUE_RRN, STATUS, EFFECTIVE_TIME, TERMINATED_TIME, CREATED_USER, ");
            sql.append(" CREATED_TIME, UPDATED_USER, UPDATED_TIME) ");
            sql.append(" VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

            List<Object[]> batchArgs = new ArrayList<>();
            Long i = transactionLog.getTransSequence() == null ? 0L : transactionLog.getTransSequence();
            for (ProductAttributeItem attributeItem : productAttributeItems) {
                batchArgs
                        .add(new Object[]{transactionLog.getTransRrn(), transactionLog.getTransId(), i++,
                                          transactionLog.getTransStartTimestamp(), transactionLog.getTransPerformedBy(),
                                          attributeItem.getProductRrn(), attributeItem.getProductId(),
                                          attributeItem.getProductVersion(), attributeItem.getProcessRrn(),
                                          attributeItem.getProcessId(), attributeItem.getProcessVersion(),
                                          attributeItem.getRouteSeq(), attributeItem.getRouteRrn(),
                                          attributeItem.getRouteVersion(), attributeItem.getRouteId(),
                                          attributeItem.getOperationSeq(), attributeItem.getOperationRrn(),
                                          attributeItem.getOperationId(), attributeItem.getFlowSeq(),
                                          attributeItem.getAttributeName(), attributeItem.getAttributeNameRrn(),
                                          attributeItem.getAttributeValue(), attributeItem.getAttributeValueRrn(),
                                          attributeItem.getStatus(), attributeItem.getEffectiveTime(),
                                          attributeItem.getTerminatedTime(), attributeItem.getCreatedUser(),
                                          attributeItem.getCreatedTime(), attributeItem.getUpdatedUser(),
                                          attributeItem.getUpdatedTime()});

            }
            transactionLog.setTransSequence(i);

            jdbcTemplate.batchUpdate(sql.toString(), batchArgs);
        }

        @Override
        public Page queryProductAttributeHistories(Page page, ProductAttributeHistoryQueryDto historyQuery) {
            StringBuilder sql = new StringBuilder("select ");

            sql.append(" TRANS_RRN, TRANS_ID, TRANS_SEQUENCE, TRANS_TIMESTAMP, TRANS_PERFORMED_BY, ");
            sql.append(" PRODUCT_RRN, PRODUCT_ID, PRODUCT_VERSION, PROCESS_RRN, PROCESS_ID, PROCESS_VERSION, ");
            sql.append(" ROUTE_SEQ, ROUTE_RRN, ROUTE_VERSION, ROUTE_ID, OPERATION_SEQ, OPERATION_RRN, OPERATION_ID, ");
            sql.append(" FLOW_SEQ, ATTRIBUTE_NAME, ATTRIBUTE_NAME_RRN, ATTRIBUTE_VALUE, ATTRIBUTE_VALUE_RRN, ");
            sql.append(" STATUS, EFFECTIVE_TIME, TERMINATED_TIME, CREATED_USER, CREATED_TIME, UPDATED_USER, UPDATED_TIME ");
            sql.append(" from PROD_ATTRIBUTE_DETAIL_HIST ");
            sql.append(" where 1 = 1 ");

            List<Object> args = new ArrayList<>();

            if (StringUtils.isNotEmpty(historyQuery.getProcessId())) {
                sql.append(" and PROCESS_ID = ? ");
                args.add(historyQuery.getProcessId());
            }

            if (historyQuery.getProcessVersion() != null && historyQuery.getProcessVersion() > 0) {
                sql.append(" and PROCESS_VERSION = ? ");
                args.add(historyQuery.getProcessVersion());
            }
            if (StringUtils.isNotEmpty(historyQuery.getProductId())) {
                sql.append(" and PRODUCT_ID = ? ");
                args.add(historyQuery.getProductId());
            }

            if (historyQuery.getProductVersion() != null && historyQuery.getProductVersion() > 0) {
                sql.append(" and PRODUCT_VERSION = ? ");
                args.add(historyQuery.getProductVersion());
            }

            if (historyQuery.getQueryStartTime() != null) {
                sql.append(" and TRANS_TIMESTAMP >= ? ");
                args.add(historyQuery.getQueryStartTime());
            }

            if (historyQuery.getQueryEndTime() != null) {
                sql.append(" and TRANS_TIMESTAMP <= ? ");
                args.add(historyQuery.getQueryEndTime());
            }

            sql.append(" ORDER BY TRANS_TIMESTAMP DESC, TRANS_SEQUENCE ASC ");

            return jdbcTemplate.queryForPage(page, sql.toString(), args.toArray(), new ProductAttributeHistoryRowMapper());
        }

    }