Java Coding Conventions
2019-05-17 00:00:00 +0000Java Coding Conventions
- 프로젝트 란에 노란 느낌표 있는지 확인(ctrl+o로 정리)
- Java Conding Convertions는 ctrl+f로 정리 가능
- logger.info 삭제(자바 로그 정리)
- System.out.println 삭제
- 사용안하거나 필요 없는 console.log, alert 삭제
- 괄호 다음을 띄운다
- if( 를 if ( 로 수정
- else if( 를 else if ( 로 수정
- }else if 를 } else if 로 수정
- else{ 를 else ( 로 수정
- }else 를 } else 로 수정
- for( 를 for ( 로 수정
- }( 을 ) { 로 수정
-
- 검색해서 안띄워져 있으면 띄위기(xml 에도 적용할 것)
- true, false 는 true는 없애고 false는 ! 로 수정
- private인데 public으로 접근제어자 사용하지 않았는지 체크!
- naming 알맞게 짓기
- 자료형에 기반한 네이밍을 하지 않는다. 예를들어 List
userList 였다가 Map 으로 바뀌면 userMap으로 네이밍을 다시 해줘야한다 - 불필요한 코드나 java대신 xml로 간단하게 처리할 수 있는지 확인하기
Java Long과 long의 차이
2019-05-15 00:00:00 +0000Long과 long의 차이
- Long은 Wrapper Class이다. 크기는 8byte (sizeof 함수가 없어서 인터넷에서 찾아봄)
- long은 순수한 자바 자료형이다. 크기는 8byte
- Long.SIZE 에 대한 설명 The number of bits used to represent a long value in two’s complement binary form.
- Wrapper Class는 클래스로써 변환해야할 때, 인자값으로 Class를 받을 때 등.. 의 상황에서 사용한다.
- 예를들어 클라로부터 a라는 인자를 받을 때도 있고, 받지 않을 때도 있다. 이 때 a의 값이 없을 때는 null이 대입되므로 Wrapper Class를 사용해야한다.
int LongSize = Long.SIZE;
System.out.println("longSize:"+LongSize);
문제 상황
- Long의 값이 null일 때 long에 Long값을 대입하면 형변환이 되지 않아 에러 발생
- Long과 long을 혼용해서 사용하고 있었다.. 주의할 것;;
궁금한 것
- 받는 값이 long 일 때 null을 long으로 변환하지 못해서 형변환 에러가 나서 예외처리가 된다. 이 때 형변환 에러 처리를 하므로 그대로 두는지, WrapperClass로 받은 후 null체크를 한 다음 처리하는지?
- WrapperClass를 사용한다. 컨트롤 밖보다 안에서 처리를 하도록 한다.
Mybatis 객체 안에 객체 매핑
2019-05-14 00:00:00 +0000Mybatis 객체 안에 객체 넣기
- Class 안에 Class를 멤버변수로 가지고 있을 때 Mybatis에서 ResultMap과 association를 사용하여 값을 매핑한다.
- 현재 TitleVO 클래스 안에 PostReplyVO 클래스가 데이터형인 멤버변수를 가지고 있다
TitleVO.java
@Data
public class TitleVO {
private long boardSeq;
private String title;
private String writer;
private Date date;
private String dateString;
private long count;
private String userId; // userId가 아니라 Name아닌가?
private long userSeq;
private boolean boardDel;
private PostReplyVO postReplyVO; // 게시물 화면에서 그릴 때 순서 필요
public PostReplyVO getPostReplyVO() {
return postReplyVO;
}
}
PostReplyVO.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PostReplyVO {
private long boardSeq;
private long parentSeq;
private int boardOrder;
private long boardDepth;
}
postReply ID 지정
- TitleVO를 매핑시키는 resultMap을 선언한다.
- TitleVO의 일반 멤버 변수는 그대로 매핑한다.
- property에는 멤버변수 이름, column 은 필드 이름을 적는다(as를 사용하여 별명을 적음)
- TitleVO의 class변수는 association 을 사용해서 매핑한다.
- association 의 propery는 TitleVO 에서 PostReplyVO 멤버변수 이름, javaType은 매핑할 클래스 이름 PostReplyVO을 적어둔다
<resultMap id="postReply" type="TitleVO">
<id property="boardSeq" column="boardSeq" />
<id property="title" column="title" />
<id property="writer" column="writer" />
<id property="date" column="date" />
<id property="count" column="count" />
<association property="postReplyVO" javaType="PostReplyVO" >
<result property="boardSeq" column="boardSeq" />
<result property="parentSeq" column="parentSeq" />
<result property="boardOrder" column="boardOrder" />
<result property="boardDepth" column="boardDepth" />
</association>
</resultMap>
쿼리문
- resultMap을 추가하고 위에서 정의한 ResultMap ID 를 적어준다.
<select id="getTitleVOList" parameterType="SelectVO" resultMap="postReply">
SELECT board_seq as boardSeq
, title
, writer
, date
, count
, user_id as userId
, user_seq as userSeq
, board_del as boardDel
, parent_seq as parentSeq
, board_order as boardOrder
, board_depth as boardDepth
FROM board
<include refid="searchBoard"></include>
ORDER BY parent_seq DESC, board_order ASC
LIMIT #{start}, #{length}
</select>
JavaConfig mariadb 연결
2019-05-13 00:00:00 +0000JavaConfig mariadb 연결
- pom.xml
- pom.xml에서 mariadb 라이브러리 추가
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.3.0</version>
</dependency>
JDBC 연결
- JDBC는 어떤 DB 드라이버든 동일한 코드로 제어할 수 있다.
- myBatis에 비해 같은 코드 반복이 많고 복잡하다(select 직접 처리) 직접 연결을 열고 닫아줘야 한다
- 많은 사용자들이 db에 원활하게 접속할 수 있게 db 커넥션풀을 미리 만들어놔야 한다.
- getConnection(“jdbc:mariadb://접속ip:포트번호/데이터베이스이름”, id, 비밀번호)
- 아래 코드가 실패하면 비밀번호, db 존재 확인 그 외 1.권한 확인 2. 포트번호 확인 2. 방화벽 확인(ping test)
- 나는 포트가 올라가있음에도 다른 포트번호와 겹쳐서 그런지(mysql?) mariadb에 접속하지 못했다. 그 후 mariadb 포트번호를 변경하고 접속할 수 있었다.
import static org.junit.Assert.fail;
import java.sql.Connection;
import java.sql.DriverManager;
import org.junit.Test;
import lombok.extern.log4j.Log4j;
@Log4j
public class mysqlDBTest {
@Test
public void testConnection() throws ClassNotFoundException {
Class.forName("org.mariadb.jdbc.Driver");
try (Connection con = DriverManager.getConnection("jdbc:mariadb://127.0.0.1:3310/test", "test", "1234"))
{
System.out.println(con);
} catch (Exception e) {
fail(e.getMessage());
}
}
}
MyBatis
- SqlSessionFactory는 DataSource를 참고하여 db와 mybatis를 연결시킴
- JDBC에서는 DB에 접근할 때마다 Session을 가져와서 사용했지만 Spring에서는 bean에 올려두고 mapper를 이용해서 접근
- @Mapper, @Service 어노테이션을 이용하면 스프링 빈으로 주입받아 사용 가능설명
-
자동으로 연결과 종료를 수행한다
- pom.xml ~~~
- 아래는 접속을 확인하기 위해서 유닛테스트를 하기 위해 Connection 직접 호출
- RootConfig.java
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DriverManagerDataSource;
@Configuration @ComponentScan(basePackages= {“base.toy.vo”}) public class RootConfig {
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.mariadb.jdbc.Driver");
dataSource.setUrl("jdbc:mariadb://localhost:3310/test");
dataSource.setUsername("test");
dataSource.setPassword("1234");
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource());
return (SqlSessionFactory) sqlSessionFactory.getObject();
}
}
- test.java
package base.toy.project;
import static org.junit.Assert.*;
import java.sql.Connection;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import base.toy.config.RootConfig; import lombok.Setter; import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {RootConfig.class}) @Log4j public class test {
@Setter(onMethod_ = { @Autowired })
private SqlSessionFactory sqlSessionFactory;
@Test
public void testMyBatis() {
try (SqlSession session = sqlSessionFactory.openSession();
Connection con = session.getConnection();) {
log.info(con);
} catch (Exception e) {
log.info("실패"+e.getMessage());
fail(e.getMessage());
}
} } ~~~
커넥션 풀
- 여러명의 사용자를 동시에 처리해야하므로 커넥션 풀을 사용해 미리 접속을 만들어두는 것이 좋다.
- HikariCP 사용
- pom.xml
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.7.4</version>
</dependency>
- DataSource가 HikariConfig를 사용하는 것으로 변경
- SqlSession Connect 시 성공
@Bean
public DataSource dataSource(){
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("org.mariadb.jdbc.Driver");
hikariConfig.setJdbcUrl("jdbc:mariadb://localhost:3310/test");
hikariConfig.setUsername("test");
hikariConfig.setPassword("1234");
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
return dataSource;
}
DataTable
2019-05-09 00:00:00 +0000DataTable
- Jquery PlugIn으로 테이블과 데이터를 연동만 해주시면 페이징, 검색, 정렬 등 기능을 쉽게 사용할 수 있다.
- DataTable 공식 홈페이지
DataTable 기본 예제
- server를 사용하지 않고 오로지 client에서 처리하는 예제. 그러므로 페이징, order, search가 server 없이 동작한다
- 기본예제
- 아무런 옵션 없이 dataTable을 만들기만 하면 기본테이블이 생성된다
DataTable 주요옵션
- pageLength: 한 페이지에 보이는 게시물 개수
- searching : 검색 기능 사용 여부
- ordering : 게시물 정렬 기능 사용 여부
- select : 한 페이지에 보일 게시물 개수 지정 기능
- serverSide: server와 통신여부
- processing : 서버와 통신 시 응답을 받기 전이라는 ui를 띄울 것인지 여부
데이터 전달
- 서버에서 데이터를 전달할 때 반드시 ‘data’로 전달해야함.
- 데이터에 링크를 걸고 싶거나 class를 주고 싶을 뗀 render:function 함수로 데이터를 수정 후 return
columns : [
{"data":"boardSeq", render:function(data, type, full, meta){
return '<div class="board-list-boardSeq">'+data+'</div>';
}},
{"data":"title", render:function(data, type, full, meta){
return '<div class="board-list-title">'+data+'</div>';
}},
{"data":"writer"},
{"data":"dateString"},
{"data":"count"}
],
ajax 사용 시 주의사항
- dataTable에 대해서 잘 모르고 성공 여부를 알기 위해서 success 함수를 정의했다가 죽는줄 알았다.. dataTable이 적용이 되지 않았는데 이유는 success 함수를 내가 선언했기 때문이었다. dataTable이 성공일 때 테이블을 그려주는 동작을 알아서 한다. 그런데 success 함수를 내가 재정의 해서 그 동작을 지워버린 것이다. 습관대로 success 를 호출하지 말도록 하자.
페이지 무한 없애기
- 처음 페이징을 적용하면 페이지가 최대 페이지에 상관없이 무한히 생성됨
- 전체 게시물 개수가 없어서 생기는 현상. 클라이언트에 값을 전달할 때 iTotalRecords, iTotalDisplayRecords 값 전달값이
result.put("iTotalRecords", totalCount);
result.put("iTotalDisplayRecords", totalCount);
페이지 숫자로만 추가
- …라는 줄임표를 빼고 싶다면 “simple_numbers_no_ellipses” 옵션 사용
- cdn 추가
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/plug-ins/1.10.19/pagination/simple_numbers_no_ellipses.js"></script>
- 옵션추가
pagingType:"simple_numbers_no_ellipses"
검색 구현
- 검색창에 단어를 입력할 때 마다 검색함.
- 버튼을 눌러서 데이터를 검색하고싶다면 custom하게 새로 만들어야 함
- 내가 만든 검색창의 데이터를 서버로 전달하고 싶다면 데이터 전달할 때 id나 class명으로 찾은 요소의 값을 줘야함(찾은 요소와 연결되나봄??)
d.searchValue = selectValue; // x
d.searchType = $('.list-select-form').val(); // o
- 버튼을 누를 때 마다 우의 요소의 값을 새로 넣어줌
- 그리고 reload 함수 호출
$('#searchBoardButton').click(function(){
$('.list-select-form').val( $('.list-select-form').val());
$('.board-list-serach-form').val($('.board-list-serach-form').val());
$('#board1-table').DataTable().ajax.reload();
});
Source Code
table = $('#board1-table').DataTable({
pagingType:"simple_numbers_no_ellipses", // 페이징에서 생략부호 빼기
serverSide: true, // ajax로 서버 데이터 처리
pageLength: pageLen, // 게시물 뒤로가기 시 기존 가지고 있던 페이지 크기를 넣어주므로 변수에 값 저장
searching: true,
ordering: false,
select: true,
ajax : {
"type":"POST",
"url":'/board/list',
"data":function(d, event){ // 서버에 전달할 데이터
d.searchValue = $('.board-list-serach-form').val(); // 검색 버튼을 누르면 .board-list-search-form 의 값을 가져옴.
d.searchType = $('.list-select-form').val();
var info = $('#board-list-select-vo').val();
if(info != undefined){
d.start = ($('#board-list-select-vo .page').val()-1) * 10;
d.length = $('#board-list-select-vo .length').val();
d.searchType = $('#board-list-select-vo .searchType').val();
d.searchValue = $('#board-list-select-vo .searchValue').val();
}
return d;
}
},
columns : [ // 서버에서 받은 값을 넣어주기 전 커스텀마이징 할 수 있다.
{"data":"boardSeq", render:function(data, type, full, meta){
return '<div class="board-list-boardSeq">'+data+'</div>';
}},
{"data":"title", render:function(data, type, full, meta){
return '<div class="board-list-title">'+data+'</div>';
}},
{"data":"writer"},
{"data":"dateString"},
{"data":"count"}
],
"initComplete":function(oSettings){ // 데이터 테이블 초기화
var info = $('#board-list-select-vo').val();
if(info != undefined){
var pageNum = $('#board-list-select-vo .page').val();
pageNum *= 1;
this.fnPageChange( pageNum-1 );
$('#board-list-select-vo').remove();
}
}
,"fnDrawCallback": function(){ // 서버에서 데이터 전달 후 처리
var api = this.api();
var json = api.ajax.json().selectVO;
gLength = json.length;
gPage = table.page.info().page + 1;
gStart = json.start;
gSearchType = json.searchType;
gSearchValue = json.searchValue;
$('#board1-table').on("click", ".board-list-title", function(){
var parent = $(this).parent();
if(undefined == parent){
return;
}
var parent = $(parent).parent();
if(undefined == parent){
return;
}
var boardSeq = $(parent).children('td').children('.board-list-boardSeq').html();
if(undefined == $('#boardSearchForm')){
return;
}
var data = {
"boardSeq" : boardSeq
};
var url = getHrefBoardList('#actionForm', '/board/'+boardSeq);
ajaxRequest("/board/"+boardSeq, JSON.stringify(data), "POST", url);
});
}
});
$('#searchBoardButton').click(function(){ // 검색 버튼 누르기
$('.list-select-form').val( $('.list-select-form').val()); // 값을 전달 할 때 값을 직접참조($('.list-select-form').val();)로 전달하지 않으면 전달값이 갱신이 안됨
$('.board-list-serach-form').val($('.board-list-serach-form').val());
$('#board1-table').DataTable().ajax.reload(); // reload 를 받드시해야한다
});
Posts
Interceptor(인터셉터)
Android Studio Install
계층형 게시판
VirtualBox Ubuntu 18.04.2 LTS
TransactionAwareDataSourceProxy Error
Java Coding Conventions
Java Long과 long의 차이
Mybatis 객체 안에 객체 매핑
JavaConfig mariadb 연결
DataTable
관리자 페이지
MappingJackson2JsonView
Spring Javaconfig
게시판 만들기-제품 등록
게시판 만들기-제품 페이지 제작
게시판 만들기-회원탈퇴 및 게시판 삭제 플래그 추가
footer 하단에 고정시키기
bootstrap4 사용법
Spring 데이터 검증 @Valid, BindingResult
brackets 실시간 미리보기
Spring 기본설정(pom.xml, web.xml, encoding)
Vue.js computed, methods, watch
javascript onkeyup
Maria DB Incorrect string value Error
javascript 암호화(md5, base64)
Vue.js template
Vue.js 소개
Nexacro 설명
ControllerAdvice
Batch
html 페이지 로딩 순서
소수구하기(PrimeNumber)
최소공배수,최대공약수
Stream
Lambda(람다식)
inner class(내부 클래스)
final 키워드
file upload
파이썬 빅 데이터 K-평균(K-means)
아나콘다(Anaconda), 주피터 개발환경 세팅
텐서플로우(TensorFlow) 아키텍쳐 및 Session
텐서플로우(TensorFlow)상수, 변수, 함수
머신러닝 기초
한글 리스트 오름차순, 내림차순
연속된 글자의 갯수 출력
java spring5 프로젝트 설정
restController
spring 세팅 및 기본설정
mybatis trim
jquery datepicker
ajax로 데이터 전달/응답 받는법
mybatis error
mybatis 게시판 만들기 순서
Java Jsp Mybatis Dynamic Query
mybatis
git 소개
node.js 개발환경 구축
node.js 기본 내장 모듈
node.js의 전역 객체
node.js http module
node.js event
jdbc
자바빈
jsp, servlet 정리
java null object pattern
다음지도 key 등록(kakao map)
공공 데이터 open api
facebook login api
sourcetree 사용법
JavaScript event3
JavaScript jquery
JavaScript dom
JavaScript ajax
JavaScript 이벤트2
JavaScript 캡슐화
JavaScript Array,내장객체
JavaScript var
JavaScript 객체,생성자
JavaScript 함수,클로저
JavaScript Event
javascript eclipse 자동완성(with tern)
CSS position
HTML5,CSS 선택자
자바 시간 측정
git,eclipse 연동
HTML 기초 정리
Eclipse Web 환경세팅
피보나치의 수
Oracle 반복문,커서,예외,저장 서브프로그램
Oracle PL/SQL
Oracle 다중쿼리(Multiple row query)
Oracle 인덱스, 뷰, 시퀀스, 트랜잭션, 세션 정리
Oracle JOIN 정리
Oracle DDL, DML 정리
Oracle 문자열 함수 정리
Oracle 숫자,날짜,자료형 변환 함수 정리
Oracle 제약조건 정리
Oracle 기초 쿼리 정리
문제2775
DFS
junit
json
algorithmus basic
circular queue(원형큐)
binary search(이진탐색)
port forwarding(포트포워딩)
kakao chatbot(카카오 챗봇)
java io
sort comparable, comparator
Unresolved compilation problem
ArrayList, HashMap
Regular(정규표현식)
Enum Class
String Function
refactoring 이란(상수,제어플래그,assert)
reference,abstract 정리
FileNotFoundException Solve
static
Thread Synchronization(스레드동기화,원자성)
Java Exception(예외처리)
Java 생성자, this, super
roomnum
BeeHouse
Git Reset, Revert
Git Log
Array
stack
pyramid draw
Star Draw(별 그리기4)
Star Draw(별 그리기3)
Star Draw(별 그리기2)
Star Draw(별 그리기1)
Loop(While, For)
자바 데이터 타입, 데이터 연산
시계방향 달팽이 그리기
정수값의 짝수,홀수 갯수 구하기
java, Scanner 정리
draw dog
subscribe via RSS