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