반응형
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

Real Vectorism. 훨씬 더 입체적으로...

슬슬 내 버릇을 남에게 강요하고싶어진다 본문

HTML5 and Spring MVC

슬슬 내 버릇을 남에게 강요하고싶어진다

grast 2020. 3. 6. 21:49
반응형

 

진짜...... 너무 큰 복병이 2개씩이나 숨어있던 탓에 오늘 하루 회사업무 집에서 한답시고 아무것도 못하고 쉬지도 못하고 하루를 날려먹은것에 너무 분노해서 글을 써본다......

 

어지간하면. 프로그래밍을 하는 사람이 10,000명이 있으면 10,000가지 코딩방법이 존재한다고는 하지만. 표준제정 싸움을 하려고 해도 자기만의 방식을 고집처럼 드러내서 싸우던가 말던가 하지 아무말도 안하고 진짜 남에게 강요같은건 못하겠다 이딴거 해봤자 좋아지는거 없다는걸 각성하고 진짜 이렇게 글 쓴다......

 

(이하 별도의 표기법 언급이 없으면 무조건 Grast 표기법으로 명명한다.)


 

SQL 레벨 (MyBatis 기준. iBatis는 써본 적 없으니 사용자가 알아서 커스터마이징하거나 그냥 쓰던대로 쓸 것)

 

1) 쿼리 실행 전 반드시 /* {네임스페이스}.{쿼리ID} */ 주석을 포함해서 쿼리실행할것
2) preparedStatement가 아닌 바인딩( ${}으로 사용하는 쿼리생성 )은 사용금지
   어쩔 수 없이 사용해야한다면 Class.forName("")으로 시작하는 방식으로 
   클래스에서 시작해서 클래스에서 끝장을 볼 것. xml으로 넘어올 생각은 죽어도 하지 말 것.
3) 예약어 등장 시 반드시 줄바꿈, 예약어가 끝나면 줄바꿈 후 Tab x1 들여쓰기
4) 쿼리는 무조건 좌측정렬, 들여쓰기는 모두 \t 키를 이용해서만 정렬
   첫번째 띄어쓰기 정렬같은 이상한 정렬법 절대사용금지
   (사용 시 프로젝트 참여 퇴출 경고)
   어떤 에디터에 복붙해도 망가지지 않는 부끄럽지 않은 쿼리를 작성할 것.
5) 다수의 값을 쿼리에 포함시킬 때 쉼표(콜론)는 반드시 끝에 붙일 것.
   줄바꾸고 줄의 맨 앞에 붙이는 표기법은 사용금지. 
   문법 가독성에 도움 안되는 where 구절의 1 = 1 표현법 사용금지

<mapper namespace="grastNamespace">
    <insert id="insertScheme" parameterType="아무거나" useGeneratedKeys="true">
        /* grastNamespace.insertScheme */
        insert into 
            schemeTableName(key1, key2, key3, key4, regdate)
        set 
            (value11, value12, 'value13', 'value14', now()), 
            (value21, value22, 'value23', 'value24', now()), 
            (value31, value32, 'value33', 'value34', now()), 
            (value41, value42, 'value43', 'value44', now()), 
            (value51, value52, 'value53', 'value54', now())
        <selectKey keyProperty="idx" resultType="int" order="AFTER">
            select last_insert_key()
        </selectKey>
    </insert>
</mapper>
1) 단일 데이터를 조회하는 쿼리는 반드시 idx값만을 이용한 where조건절 구성
2) is_public, is_delete, is_usable 등의 별도조건이 포함된 경우 where조건절 수정 가능
3) auto_increment 또는 sequence 값이 아닌 다른 조건으로 단일 데이터를 조회해야 할 경우
   select 명명 금지, search로 명명할 것.
4) 테이블 컬럼은 처음부터 소문자로 구성하거나 
   카멜표기법으로 바꾸는 유틸클래스를 직접 구현해서 사용할 것.
   권장사항은 jsp에서 jstl표기법 사용 시 문법일관성을 위해 소문자로 사용하는것이 권장.
5) search 매핑 sql과 select, from 구절은 완전하게 일치해야함
6) select와 search 한정 공통으로 date_format(), to_char()와 to_date() 절대사용금지
   데이터의 타입은 반드시 데이터 삽입과 조회 시의 유형이 모두 일치해야함

<select id="selectScheme" parameterType="java.util.Map" resultMap="java.util.Map">
    /* grastNamespace.selectScheme */
    select key1, key2, key3, key4, regdate 
    from schemeTableName 
    where idx = #{idx}
</select>



1) select(오브젝트명)List 표기 명명금지, search로 사용할 것. retrieve 역시 명명금지.
2) select(오브젝트명)의 매핑 sql과 select, from 구절은 완전하게 일치해야할 것.
3) <where> 조건을 이용함으로써, 다중조건문 포함 시 각 줄 and(또는 or)로 시작할 것.
4) 클래스레벨 또는 데이터베이스 레벨에서 생성된 값을 조회할 경우 = 사용
5) 사용자입력값은 반드시 정규표현식 검색 또는 like 검색으로 사용할 것.
   엄격한 조건지정은 검색 후 클래스레벨에서 분류하거나 매핑sql을 별도로 작성하여 추가할 것.
6) order by 는 선택사항
7) offset과 length가 모두 유효한 값이 확인되었을 때 limit 구절을 사용할 것.

<select id="searchScheme" parameterType="java.util.Map" resultMap="java.util.Map">
    /* grastNamespace.searchScheme */
    select key1, key2, key3, key4, regdate 
    from schemeTableName 
    <where>
        <if test="key1 != null">key1 = #{key1} </if>
        <if test="key3 != null">and key3 regexp concat('(', #{key3}, ')+') </if>
    </where>
    order by idx desc 
    <if test="offset != null and offset >= 0 and length != null and length > 0">
        limit #{offset}, #{length}
    </if>
</select>



1) count(오브젝트명)으로 명명할 것. 다른 표기는 일체 명명금지.
2) select count(개인키 컬럼명) from 테이블이름 형식으로 반드시 사용할것.
3) where 조건절은 search 매핑sql의 것을 반드시 그대로 사용할것.
4) group by, order by, limit 구절은 일체 사용금지. 부분적인 사용 또한 금지

<select id="countScheme" parameterType="java.util.Map" resultType="int">
    /* grastNamespace.countScheme */
    select count(idx) 
    from schemeTableName 
    <where>
        <if test="key1 != null">key1 = #{key1} </if>
        <if test="key3 != null">and key3 regexp concat('(', #{key3}, ')+') </if>
    </where>
</select>

 


 

클래스 레벨

 

@Controller
@RequestMapping(value="")
public class Controller {
    1) 사용하지 않더라도 logger 인스턴스 객체는 반드시 생성해야함
    2) 최소 slf4j 권장
    private final Logger logger = LoggerFactory.getLogger(Controller.class);
    


    1) DAO 객체 생성시 반드시 1줄에서 생성을 모두 마칠 것
    2) 가독성을 위한 private 맞춤정렬 혹은 일반적인 좌측정렬
    3) Autowired 사용 시 동일적용
    @Resource(name="appleDao")     private AppleDao appleDao;
    @Resource(name="pineappleDao") private PineappleDAO pineappleDao;



    1) 다중매핑 시 대괄호 내부에 1칸씩 여백을 둘 것, 불필요한 띄어쓰기는 자제
    2) method=RequestMethod.POST 와 같이 붙여쓰기 권장
    3) 기타 옵션도 동일하게 적용(Consumes, Produces 등)
    @RequestMapping({ "/", "/home", "/index" })



    1) Model, HttpServletRequest, HttpServletResponse는 자유선언
    2) Model, HttpServletRequest, HttpServletResponse 가 아닌 경우는 줄바꾸고
       다음줄에서 아규먼트 열거 시작,
    public String main(Model model, HttpServletRequest request, HttpServletResponse response, 
            @RequestParam Map<String, String> param) {



        1) 모든 메소드의 시작에 logger를 이용한 로깅 필수 (aop 로깅처리와는 별개)
        2) 표기법은 "{메소드 이름}: " + {requestParam 객체의 toString() 리턴값}
        3) error등급 사용금지, debug, info, warn 중에서 취사선택 후 전 메소드에서 통일사용
        4) RequestParam이 없을 경우 메소드명만 표기, GET과 POST에 의한 구분이 필요할 경우
           적절한 방법으로 커스터마이징 후 로그 사용
        logger.warn("main: " + param.toString());
        


        1) 가능한 View로 변수 전달 시 메소드 체이닝으로 정리할 것.
        2) Model 타입 사용 시 권장, ModelAndView 타입 사용 시 필수
        3) ModelAndView 타입 사용 시 return new ModelAndView().어쩌구.저쩌구 형식으로 사용
        model.addAttribute("key1", "value1")
             .addAttribute("key2", "value2")
             .addAttribute("key3", "value3");
        return "home";
    }
}
1) CRUD 기능을 담당하는 인터페이스는 해당 인터페이스를 반드시 작성할 것.
2) CRUD 인터페이스 제작 후 바로 해당 인터페이스를 구현하는 것이 아닌
   각 오브젝트별 DAO 객체 생성 시 해당 인터페이스를 구현하도록 할 것.
3) Service 인터페이스 객체에 상속(extends)하여 사용하여 crud 관련 메소드 정의 생략 가능
4) ServiceImpl 객체에서는 insert, update, delete, select, search, count 이름으로 구현 필수
public interface CRUDInterface<T> {
    int insert(T param);
    int update(T param);
    int delete(T param);

    Map<String, Object> select(T param);
    List<Map<String, Object>> search(T param);

    int count(T param);
}
/* Model 객체를 VO로 사용할 경우 */
public class ObjectVO {
    private int idx;
    private int key1;
    private int key2;
    private String key3;
    private String key4;
    private Date regdate;

    public ObjectVO() {}
    public ObjectVO(int idx) {
        this.idx = idx;
    }

    public int getIdx() { return this.idx; }
    public int getKey1() { return this.key1; }
    public int getKey2() { return this.key2; }
    public String getKey3() { return this.key3; }
    public String getKey4() { return this.key4; }
    public Date getRegdate() { return this.regdate; }

    1) 반드시 메소드 체이닝으로 구현. void타입이 아닌 셀프객체반환 필수
    2) return this 반드시 명시.
    public ObjectVO setIdx(int idx) { this.idx = idx; return this; }
    public ObjectVO setKey1(int key1) { this.key1 = key1; return this; }
    public ObjectVO setKey2(int key2) { this.key2 = key2; return this; }
    public ObjectVO setKey3(String key3) { this.key3 = key3; return this; }
    public ObjectVO setKey4(String key4) { this.key4 = key4; return this; }
    public ObjectVO setRegdate(Date regdate) { this.regdate = regdate; return this; }

    public String toString() { 알아서 구현 }
}
/* Model 객체를 Map으로 사용할 경우 연쇄적 변수삽입이 가능한 별도의 Map구현체 생성 */
public class ChainMap<K, V> implements Map<K, V> {
    public ChainMap<K, V> 이름은_마음대로(K k, V v) {
        this.add(k, v);
        return this;
    }
}
/* 공식적인 명칭이 필요할 경우 chain 권장, 왼손 타이핑이 편할 경우 eat 권장 */

 


 

JSP 레벨

 

<table>
    <thead>
        <tr>
            <th>idx</th>
            <th>key1</th>
            <th>key2</th>
            <th>key3</th>
            <th>key4</th>
            <th>regdate</th>
        </tr>
    </thead>
    <tbody>
        1) List 타입으로 변수를 전달할 경우 반드시 (Object 이름)List 유형으로 전달할것
        2) c:forEach 태그 등으로 순회 시 개별변수명을 (Object 이름)Item으로 사용할 것
        3) Date 객체의 표시는 
           http://java.sum.com/jsp/jstl/fmt 태그라이브러리를 반드시 fmt으로 사용할것
        4) 날짜의 표시는 <fmt:formatDate value="" pattern="" /> 으로 표시 필수
        <c:forEach item="${keyList}" var="keyItem">
            <tr>
                <td>${keyItem.idx }</td>
                <td>${keyItem.key1 }</td>
                <td>${keyItem.key2 }</td>
                <td>${keyItem.key3 }</td>
                <td>${keyItem.key4 }</td>
                <td><fmt:formatDate value="${keyItem.regdate }" pattern="yyyy-MM-dd HH:mm:ss" /></td>
            </tr>
        </c:forEach>
    </tbody>
</table>
1) model.addAttribute(name, value) 통해 자바스크립트 구문 전달금지
2) 값 전달은 무조건 "${key }" 형식으로 반드시 String 타입으로만 받을것
3) "" 없이 변수에 값을 직접 할당 시 프로젝트 퇴출 경고
4) json 객체를 변수에 할당하고자 할 경우 XMLHttpRequest 또는 $.ajax 를 통해서만 직접 할당할것
5) jstl 등으로 변수에 json을 직접 할당할 경우 문법오류로 인한 페이지오류 발생위험 경고
6) if구문을 통해 실행해야할지를 결정해야할 경우 자바스크립트 내에서 jstl 분기 금지
<script>
    /* 금지사항 01 */
    var key01 = ${value01};
    /* 허용사항 01 */
    var key01 = "${value01}";

    /* 금지사항 02 */
    var json01 = ${jsondata01};
    /* 허용사항 02-1 */
    var json01 = "${jsondata01를 호출하기 위한 idx 등의 개인키}";
    $.ajax({
        ...
        data: { key: json01 }
        ...
    }).done(function(data) {
        json01 = data.jsondata01;
    });
    /* done은 jQuery3 버전대 문법. jQuery1 버전대는 success 문법 사용 */
    /* 허용사항 02-2 */
    var json01 = JSON.parse("${jsondata01 }");

    /* 금지사항 03 */
    /* jsprint 변수값이 console.log("own xss test"); 와 같은 자바스크립트 구문인 경우 */
    /* 해당 값을 절대로 스크립트 영역에서 실행하지 말 것 */
    /* 적발 시 확정퇴출 경고 */
    ${jsprint}
</script>

어지간해선 프로그래밍하는 사람들마다 모두 스타일이 달라서 이런건 절대로 타인을 틀에 박히게 만들면 안되는건데 규모가 큰 프로젝트가 신규 투입자에게 교육도 시키지 않고 대뜸 알아서 찾아서 적용하라고 할꺼라면 차라리 저런식으로 우덜식 표준이라도 만들어라 제발 좀 ㅡㅡ

 
반응형

'HTML5 and Spring MVC' 카테고리의 다른 글

일단 SCSS는 완성  (0) 2021.03.03
PiuMossoLog4jdbcCustomFormatter 배포  (0) 2020.03.06
PIU Mosso  (0) 2019.04.19
Comments