# ProductAttributeItemDaoImpl.java

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

    import com.mycim.framework.jdbc.JdbcTemplate;
    import com.mycim.framework.utils.lang.StringUtils;
    import com.mycim.server.spec.dao.ProductAttributeItemDao;
    import com.mycim.server.spec.dao.mapper.ProductAttributeItemMapper;
    import com.mycim.valueobject.consts.VersionStatus;
    import com.mycim.valueobject.prp.ProductAttributeItem;
    import com.mycim.valueobject.prp.ProductAttributeFormDto;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Repository;

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    @Repository
    public class ProductAttributeItemDaoImpl implements ProductAttributeItemDao {

        @Autowired
        JdbcTemplate jdbcTemplate;

        @Override
        public void insertProductAttributeItems(List<ProductAttributeItem> productAttributeItems) {
            StringBuilder sql = new StringBuilder("insert into ");

            sql.append(" PROD_ATTRIBUTE_DETAIL_INFO ");
            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, STATUS, ");
            sql.append(" EFFECTIVE_TIME, TERMINATED_TIME, CREATED_USER, CREATED_TIME, UPDATED_USER, UPDATED_TIME) ");
            sql.append(" values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ");

            List<Object[]> batchArgs = new ArrayList<>();
            for (ProductAttributeItem attributeItem : productAttributeItems) {
                batchArgs
                        .add(new Object[]{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()});
            }

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

        @Override
        public void deleteProductAttributeItems(List<ProductAttributeItem> productAttributeItems) {
            StringBuilder sql = new StringBuilder("delete from ");

            sql.append(" PROD_ATTRIBUTE_DETAIL_INFO ");
            sql.append(" where PRODUCT_RRN = ? and PRODUCT_VERSION = ? and PROCESS_RRN = ? and PROCESS_VERSION = ? ");
            sql.append(" and ROUTE_RRN = ? and OPERATION_RRN = ? and ATTRIBUTE_NAME_RRN = ? ");

            List<Object[]> batchArgs = new ArrayList<>();
            for (ProductAttributeItem attributeItem : productAttributeItems) {
                batchArgs
                        .add(new Object[]{attributeItem.getProductRrn(), attributeItem.getProductVersion(),
                                          attributeItem.getProcessRrn(), attributeItem.getProcessVersion(),
                                          attributeItem.getRouteRrn(), attributeItem.getOperationRrn(),
                                          attributeItem.getAttributeNameRrn()});
            }

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

        @Override
        public void updateProductAttributeItems(List<ProductAttributeItem> productAttributeItems) {
            StringBuilder sql = new StringBuilder("update PROD_ATTRIBUTE_DETAIL_INFO ");

            sql.append(" set ATTRIBUTE_VALUE = ?, ATTRIBUTE_VALUE_RRN = ?, UPDATED_USER = ?, UPDATED_TIME = ? ");
            sql.append(" where PRODUCT_RRN = ? and PRODUCT_VERSION = ? and PROCESS_RRN = ? and PROCESS_VERSION = ? ");
            sql.append(" and ROUTE_RRN = ? and OPERATION_RRN = ? and ATTRIBUTE_NAME_RRN = ? ");

            List<Object[]> batchArgs = new ArrayList<>();
            for (ProductAttributeItem attributeItem : productAttributeItems) {
                batchArgs
                        .add(new Object[]{attributeItem.getAttributeValue(), attributeItem.getAttributeValueRrn(),
                                          attributeItem.getUpdatedUser(), attributeItem.getUpdatedTime(),
                                          attributeItem.getProductRrn(), attributeItem.getProductVersion(),
                                          attributeItem.getProcessRrn(), attributeItem.getProcessVersion(),
                                          attributeItem.getRouteRrn(), attributeItem.getOperationRrn(),
                                          attributeItem.getAttributeNameRrn()});
            }

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

        @Override
        public void updateStatusOfProductAttributeItems(List<ProductAttributeItem> productAttributeItems) {
            StringBuilder sql = new StringBuilder("update PROD_ATTRIBUTE_DETAIL_INFO ");

            sql.append(" set STATUS = ?, EFFECTIVE_TIME = ?, TERMINATED_TIME = ?, UPDATED_USER = ?, UPDATED_TIME = ? ");
            sql.append(" where PRODUCT_RRN = ? and PRODUCT_VERSION = ? and PROCESS_RRN = ? and PROCESS_VERSION = ? ");
            sql.append(" and ROUTE_RRN = ? and OPERATION_RRN = ? and ATTRIBUTE_NAME_RRN = ? ");

            List<Object[]> batchArgs = new ArrayList<>();
            for (ProductAttributeItem attributeItem : productAttributeItems) {
                batchArgs
                        .add(new Object[]{attributeItem.getStatus(), attributeItem.getEffectiveTime(),
                                          attributeItem.getTerminatedTime(), attributeItem.getUpdatedUser(),
                                          attributeItem.getUpdatedTime(), attributeItem.getProductRrn(),
                                          attributeItem.getProductVersion(), attributeItem.getProcessRrn(),
                                          attributeItem.getProcessVersion(), attributeItem.getRouteRrn(),
                                          attributeItem.getOperationRrn(), attributeItem.getAttributeNameRrn()});
            }

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

        @Override
        public List<ProductAttributeItem> getProductAttributeItemsWithPrimaryKey(
                ProductAttributeItem attributeItemQueryTemp) {
            StringBuilder sql = new StringBuilder("select ");

            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, STATUS, ");
            sql.append(" EFFECTIVE_TIME, TERMINATED_TIME, CREATED_USER, CREATED_TIME, UPDATED_USER, UPDATED_TIME ");
            sql.append(" from PROD_ATTRIBUTE_DETAIL_INFO where 1 = 1 ");

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

            if (attributeItemQueryTemp.getProductRrn() != null && attributeItemQueryTemp.getProductRrn() > 0) {
                sql.append(" and PRODUCT_RRN = ?");
                args.add(attributeItemQueryTemp.getProductRrn());
            }

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

            if (attributeItemQueryTemp.getProcessRrn() != null && attributeItemQueryTemp.getProcessRrn() > 0) {
                sql.append(" and PROCESS_RRN = ?");
                args.add(attributeItemQueryTemp.getProcessRrn());
            }

            if (attributeItemQueryTemp.getProcessVersion() != null && attributeItemQueryTemp.getProcessVersion() > 0) {
                sql.append(" and PROCESS_VERSION = ?");
                args.add(attributeItemQueryTemp.getProcessVersion());
            }

            if (attributeItemQueryTemp.getRouteRrn() != null && attributeItemQueryTemp.getRouteRrn() > 0) {
                sql.append(" and ROUTE_RRN = ?");
                args.add(attributeItemQueryTemp.getRouteRrn());
            }

            if (attributeItemQueryTemp.getOperationRrn() != null && attributeItemQueryTemp.getOperationRrn() > 0) {
                sql.append(" and OPERATION_RRN = ?");
                args.add(attributeItemQueryTemp.getOperationRrn());
            }

            if (attributeItemQueryTemp.getAttributeNameRrn() != null && attributeItemQueryTemp.getAttributeNameRrn() > 0) {
                sql.append(" and ATTRIBUTE_NAME_RRN = ?");
                args.add(attributeItemQueryTemp.getAttributeNameRrn());
            }

            return jdbcTemplate.query(sql.toString(), new ProductAttributeItemMapper(), args.toArray());
        }

        @Override
        public List<ProductAttributeItem> queryProductAttributeItems(ProductAttributeFormDto queryInfo) {
            StringBuilder sql = new StringBuilder("select ");

            sql.append(" PRODUCT_RRN, PRODUCT_ID, PRODUCT_VERSION, PROCESS_RRN, PROCESS_ID, PROCESS_VERSION, ");
            sql.append(" ROUTE_SEQ, ROUTE_RRN, ROUTE_VERSION, ROUTE_ID, ");
            sql.append(" OPERATION_SEQ, OPERATION_RRN, OPERATION_ID, FLOW_SEQ, ");
            sql.append(" ATTRIBUTE_NAME, ATTRIBUTE_NAME_RRN, ATTRIBUTE_VALUE, ATTRIBUTE_VALUE_RRN, ");
            sql.append(" STATUS, EFFECTIVE_TIME, TERMINATED_TIME, CREATED_USER, CREATED_TIME, ");
            sql.append(" UPDATED_USER, UPDATED_TIME ");
            sql.append(" from PROD_ATTRIBUTE_DETAIL_INFO P ");
            sql.append(" where PROCESS_RRN = :processRrn AND PROCESS_VERSION = :processVersion ");

            Map<String, Object> paramMap = new HashMap<>();

            paramMap.put("processRrn", queryInfo.getProcessRrn());
            paramMap.put("processVersion", queryInfo.getProcessVersion());

            if (CollectionUtils.isNotEmpty(queryInfo.getFlowSeqs())) {
                sql.append(" and FLOW_SEQ in (:flowSeqs) ");
                paramMap.put("flowSeqs", queryInfo.getFlowSeqs());
            }

            if (CollectionUtils.isNotEmpty(queryInfo.getAttributeNameRrns())) {
                sql.append(" and ATTRIBUTE_NAME_RRN in (:attributeNameRrns) ");
                paramMap.put("attributeNameRrns", queryInfo.getAttributeNameRrns());
            }

            if (CollectionUtils.isNotEmpty(queryInfo.getProductRrns())) {
                sql.append(" and PRODUCT_RRN in (:productRrns) ");
                paramMap.put("productRrns", queryInfo.getProductRrns());
            }

            if (CollectionUtils.isNotEmpty(queryInfo.getProductVersions())) {
                sql.append(" and PRODUCT_VERSION in (:productVersions) ");
                paramMap.put("productVersions", queryInfo.getProductVersions());
            }

            sql.append(" ORDER BY PRODUCT_ID, PROCESS_VERSION DESC, PRODUCT_VERSION DESC ");

            return jdbcTemplate.query(sql.toString(), paramMap, new ProductAttributeItemMapper());
        }

    }