rawquery정리

김승수·2023년 2월 5일
0

2차프로젝트 중 상품 메인페이지, 상세페이지, 필터링, 정렬, 페이지네이션 등
기능을 한 api에 정리하고싶어서 처음에 한번에 쭈루루루루룩 다 썼다.

그러다보니 레이어드 패턴 중 api 는 하나지만 코드 양이 어마어마했다.

그래서 줄여보기로 했다.

1차

const { appDataSource } = require("./appDataSource");
const {
  whereClause,
  andClause,
  betweenClause,
} = require("../utils/queryModules");

const getProductList = async (
  oil,
  year,
  sunroof,
  color,
  parkingSensor,
  backCamera,
  navi,
  heatingSeat,
  coolingSeat,
  smartKey,
  leatherSeat,
  size,
  type,
  listType,
  brand,
  minMileage,
  maxMileage,
  minPrice,
  maxPrice,
  offset,
  limit,
  sort
) => {
  const sortMethod = Object.freeze({
    cheap: "p.price ASC",
    expensive: "p.price DESC",
    lastest: "p.created_at DESC",
    oldest: "p.created_at ASC",
  });
  const whereClauseBrand = brand ? `WHERE c.brand_id = ${brand}` : "";
  const whereClauseType = type ? `WHERE c.type_id = ${type}` : "";
  const andType = type ? `AND c.type= ${type}` : "";
  const andListType = listType ? `WHERE c.type= ${listType}` : "";
  const andSize = size ? `AND c.size_id = ${size}` : "";
  const andOil = oil ? `AND p.oil = ${oil}` : "";
  const andYear = year ? `AND p.year = ${year}` : "";
  const andSunroof = sunroof ? `AND po.sunroof = ${sunroof}` : "";
  const andColor = color ? `AND po.color = ${color}` : "";
  const andParkingSensor = parkingSensor
    ? `AND po.parkingsensor = ${parkingSensor}`
    : "";
  const andBackCamera = backCamera ? `AND po.backcamera = ${backCamera}` : "";
  const andNavi = navi ? `AND po.heatingseat = ${heatingSeat}` : "";
  const andCoolingSeat = coolingSeat
    ? `AND po.coolingseat =${coolingSeat}`
    : "";
  const andSmartKey = smartKey ? `AND po.smartkey = ${smartKey}` : "";
  const andLeatherSeat = leatherSeat
    ? `AND po.leatherseat = ${leatherSeat}`
    : "";
  const andMileage = maxMileage
    ? `AND p.mileage BETWEEN ${minMileage} AND ${maxMileage}`
    : "";
  const andPrice = maxPrice
    ? `AND p.price BETWEEN ${minPrice} AND ${maxPrice}`
    : "";

  return await appDataSource.query(
    `SELECT 
        c.id        AS carId,
        c.name      AS carName,
        c.thumbnail AS mainThumbnailImage,
        c.type      AS type,
        p.price     AS price,
        p.thumbnail AS listThumbnailImage,
        b.name      AS brandName
      FROM 
        cars c
      JOIN brands b           ON c.brand_id = b.id
      JOIN products p         ON p.car_id = c.id
      JOIN product_options po ON po.product_id = p.id
      ${whereClauseBrand}
      ${whereClauseType}
      ${andType}
      ${andListType}
      ${andSize}
      ${andOil}
      ${andYear}
      ${andSunroof}
      ${andColor}
      ${andParkingSensor}
      ${andBackCamera}
      ${andNavi}
      ${andCoolingSeat}
      ${andSmartKey}
      ${andLeatherSeat}
      ${andMileage}
      ${andPrice}
      ORDER BY ${sortMethod[sort]}
      LIMIT ${limit} OFFSET ${offset} 
      `
  );
};

module.exports = { getProductList };

뭐가 디게 많다.

그래서 2차로 조금 줄였다.

const { appDataSource } = require("./appDataSource");
const {
  whereClause,
  andClause,
  betweenClause,
  forClause,
} = require("../utils/queryModules");

const getProductList = async (
  oil,
  minYear,
  maxYear,
  sunroof,
  color,
  parkingSensor,
  backCamera,
  navi,
  heatingSeat,
  coolingSeat,
  smartKey,
  leatherSeat,
  size,
  type,
  brand,
  minMileage,
  maxMileage,
  minPrice,
  maxPrice,
  offset,
  limit,
  sort
) => {
  const sortMethod = Object.freeze({
    cheap: "p.price ASC",
    expensive: "p.price DESC",
    lastest: "p.created_at DESC",
    oldest: "p.created_at ASC",
  });
  const whereBrand = whereClause(brand, "c.brand_id");
  const andType = forClause([type, size], ["c.type", "c.size"]);
  const andType = andClause(type, "c.type");
  const andSize = andClause(size, "c.size_id");
  const andOil = andClause(oil, "p.oil");
  const andSunroof = andClause(sunroof, "po.sunroof");
  const andColor = andClause(color, "po.color");
  const andParkingSensor = andClause(parkingSensor, "po.parkingsensor");
  const andBackCamera = andClause(backCamera, "po.backcamera");
  const andNavi = andClause(navi, "po.heatingseat");
  const andHeatingSeat = andClause(heatingSeat, "po.heatingseat");
  const andCoolingSeat = andClause(coolingSeat, "po.coolingseat");
  const andSmartKey = andClause(smartKey, "po.smartkey");
  const andLeatherSeat = andClause(leatherSeat, "po.leatherseat");
  const andMileage = betweenClause(minMileage, maxMileage, "p.mileage");
  const andPrice = betweenClause(minPrice, maxPrice, "p.price");
  const andYear = betweenClause(minYear, maxYear, "p.year");

  return await appDataSource.query(
    `SELECT
        c.id        AS carId,
        c.name      AS carName,
        c.thumbnail AS mainThumbnailImage,
        c.type      AS type,
        p.price     AS price,
        p.thumbnail AS listThumbnailImage,
        b.name      AS brandName
      FROM 
        cars c
      JOIN brands b           ON c.brand_id = b.id
      JOIN products p         ON p.car_id = c.id
      JOIN product_options po ON po.product_id = p.id
      ${whereBrand}
      ${andType}
      ${andOil}
      ${andYear}
      ${andSunroof}
      ${andColor}
      ${andParkingSensor}
      ${andBackCamera}
      ${andHeatingSeat}
      ${andNavi}
      ${andCoolingSeat}
      ${andSmartKey}
      ${andLeatherSeat}
      ${andMileage}
      ${andPrice}
      ORDER BY ${sortMethod[sort]}
      LIMIT ${limit} OFFSET ${offset} 
      `
  );
};

module.exports = { getProductList };

그런데도 많다

그래서 반복되는걸 없앴고 따로 뺐다.

querymodule.js

const forClause = (a, b) => {
  let aList = [];
  let bList = [];
  let result = "";
  let arr = [];

  for (i = 0; i < a.length; i++) {
    if (!a[i]) arr.push(a[i]);

    aList.push(a[i]);
  }
  for (j = 0; j < b.length; j++) {
    if (!b[j]) arr.push(b[j]);

    bList.push(b[j]);
  }
  for (k = 0; k < aList.length; k++) {
    result += andClause(aList[k], bList[k]);
  }
  return result;
};

const andClause = (params, params2) => {
  return params ? `AND ${params2} = ${params} ` : "";
};

const betweenClause = (params, params2, params3) => {
  return params2 ? `AND ${params3} BETWEEN ${params} AND ${params2} ` : "";
};

module.exports = { betweenClause, forClause };
productDao.js
const { appDataSource } = require("./appDataSource");
const { betweenClause, forClause } = require("../utils/queryModules");

const getProductList = async (offset, limit, sort, filterOptions) => {
  const sortMethod = Object.freeze({
    cheap: "p.price ASC",
    expensive: "p.price DESC",
    lastest: "p.created_at DESC",
    oldest: "p.created_at ASC",
  });

  const andType = forClause(
    [
      filterOptions.brand,
      filterOptions.oil,
      filterOptions.sunroof,
      filterOptions.color,
      filterOptions.parkingsensor,
      filterOptions.backcamera,
      filterOptions.navi,
      filterOptions.heatingseat,
      filterOptions.coolingseat,
      filterOptions.smartkey,
      filterOptions.leatherseat,
      filterOptions.size,
      filterOptions.type,
    ],
    [
      "c.brand_id",
      "p.oil",
      "po.sunroof",
      "po.color",
      "po.parkingsensor",
      "po.backcamera",
      "po.navi",
      "po.heatingseat",
      "po.coolingseat",
      "po.smartkey",
      "po.leatherseat",
      "c.size",
      "c.type",
    ]
  );
  const andBetweenMileage = betweenClause(
    filterOptions.minMileage,
    filterOptions.maxMileage,
    "p.mileage"
  );
  const andBetweenPrice = betweenClause(
    filterOptions.minPrice,
    filterOptions.maxPrice,
    "p.price"
  );
  const andBetweenYear = betweenClause(
    filterOptions.minYear,
    filterOptions.maxYear,
    "p.year"
  );

  return await appDataSource.query(
    `SELECT
        c.id        AS carId,
        c.name      AS carName,
        c.thumbnail AS mainThumbnailImage,
        c.type      AS type,
        p.price     AS price,
        p.thumbnail AS listThumbnailImage,
        b.name      AS brandName
      FROM 
        cars c
      JOIN brands b           ON c.brand_id = b.id
      JOIN products p         ON p.car_id = c.id
      JOIN product_options po ON po.product_id = p.id
      LEFT JOIN biddings bd        ON bd.product_id = p.id
      LEFT JOIN orders o           ON o.bidding_id = bd.id
      WHERE o.order_status_id IS NULL
      ${andType}
      ${andBetweenYear}
      ${andBetweenMileage}
      ${andBetweenPrice}
      ORDER BY ${sortMethod[sort]}
      LIMIT ${limit} OFFSET ${offset} 
      `
  );
};

module.exports = { getProductList };

더줄일수있지만, 일단 남은 프로젝트를 위해 킵해놓고 다른 api를 시작했다.

나중에 디벨롭 더 시켜서 더 줄여보자

profile
외부형 확장뇌

0개의 댓글