P06_jdbc_template
JDBC-template.txt
# JDBC template API
- 템플릿 메서드 패턴이 적용된 클래스
- JDBC 의 반복적인 코들르 제거하기 위해서 제공되는 클래스
- 반복되는 DB 로직은 JdbcTemplate 템플릿 메서드가 제공하고,
개발자는 달라지는 SQL 구문과 설정값만 신경쓰면 됨
> update() : INSERT, DELETE, UPDATE SQL 문을 실행하기 위해 사용되는 메서드
* getJdbcTemplate.update("INSERT INTO TABLE VALUES(?,?,?)", new Object[]{name, age, phone});
> query() : SELECT 문의 실행 결과가 여러 목록으로 반환되는 경우에 사용되는 메서드
* Object[] args = {"%" + searchKeyword + "%"};
getJdbcTemplate.query("SELECT * FROM TABLE WHERE NAME LIKE ?", args, new UserFlowMapper());
> queryForInt() : SELECT 문의 실행 결과로 반환되는 정수값을 받기 위해서 사용되는 메서드
* int count = getJdbcTemplate.queryForInt("SELECT COUNT(*) FROM TABLE");
> queryForObject() : SQL 실행 결과를 Object 로 반환되는 경우에 사용되는 메서드
* String name = getJdbcTemplate.queryForObject("SELECT NAME FROM USERS WHERE ID=?", new Object[]{"test}, String.class)
# DataSource 설정
- JdbcTemplate 클래스의 JDBC API 를 이용하여 DB 연동을 처리하려면 반드시 DB 로부터 컨넥션을 가져와야 함
DataSource 를 <bean> 등록하여 스프링 컨테이너가 생성하도록 한다
DataSource 인터페이스를 구현한 BasicDataSource 클래스를 사용
-------------------------------------------------------------
# pom.xml 수정 의존성 추가
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
com.book.template
resources/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.book.template"/>
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
BooksVO.java
package com.book.template;
public class BooksVO {
private String code;
private String name;
private int price;
private String maker;
public BooksVO() {}
public BooksVO(String code, String name, int price, String maker) {
super();
this.code = code;
this.name = name;
this.price = price;
this.maker = maker;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getMaker() {
return maker;
}
public void setMaker(String maker) {
this.maker = maker;
}
@Override
public String toString() {
return "[ 도서번호 : " + code + " - 도서명 : " + name + " - 가격 : " + price + " - 출판사 : " + maker + " ]";
}
}
BooksDAO.java
package com.book.template;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
@Repository
public class BooksDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
private final String BOOKS_INSERT = "insert into books values(?, ?, ?, ?)";
private final String BOOKS_LIST = "select * from books order by code asc";
private final String BOOKS_UPDATE = "update books set name=?, price=?, maker=? where code=?";
private final String BOOKS_DELETE = "delete books where code=?";
private final String BOOKS_SEARCH = "select * from books";
public int insertBooks(BooksVO vo) {
int su = 0;
su = jdbcTemplate.update(BOOKS_INSERT, vo.getCode(), vo.getName(), vo.getPrice(), vo.getMaker());
return su;
}
public List<BooksVO> getBooksList(BooksVO vo){
List<BooksVO> list = null;
list = jdbcTemplate.query(BOOKS_LIST, new BooksRowMapper());
return list;
}
public int updateBooks(BooksVO vo) {
int su = 0 ;
su = jdbcTemplate.update(BOOKS_UPDATE, vo.getName(), vo.getPrice(), vo.getMaker(), vo.getCode());
return su;
}
public int deleteBooks(BooksVO vo) {
int su = 0;
su = jdbcTemplate.update(BOOKS_DELETE, vo.getCode());
return su;
}
public BooksVO getBooks(BooksVO vo) {
try {
Object[] args = { vo.getCode() };
return jdbcTemplate.queryForObject(BOOKS_SEARCH, args, new BooksRowMapper());
} catch (Exception e) {
return null;
}
}
}
BookService.inter
package com.book.template;
import java.util.List;
public interface BookService {
int insertBooks(BooksVO vo);
List<BooksVO> getBooksList(BooksVO vo);
int updateBooks(BooksVO vo);
BooksVO getBooks(BooksVO vo);
int deleteBooks(BooksVO vo);
}
BookServiceImpl.java
package com.book.template;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("bookService")
public class BookServiceImpl implements BookService {
@Autowired
private BooksDAO booksDAO;
@Override
public int insertBooks(BooksVO vo) {
return booksDAO.insertBooks(vo);
}
@Override
public List<BooksVO> getBooksList(BooksVO vo) {
return booksDAO.getBooksList(vo);
}
@Override
public int updateBooks(BooksVO vo) {
return booksDAO.updateBooks(vo);
}
@Override
public BooksVO getBooks(BooksVO vo) {
return booksDAO.getBooks(vo);
}
@Override
public int deleteBooks(BooksVO vo) {
return booksDAO.deleteBooks(vo);
}
}
JDBCTest.java
package com.book.template;
import java.util.List;
import java.util.Scanner;
import org.springframework.context.support.GenericXmlApplicationContext;
public class JDBCTest {
public static void main(String[] args) {
GenericXmlApplicationContext context =
new GenericXmlApplicationContext("applicationContext.xml");
BookService bookService = context.getBean("bookService", BookService.class);
BooksVO vo = new BooksVO();
int su = 0;
List<BooksVO> list = null;
Scanner scanner = new Scanner(System.in);
System.out.println("--- 도서 정보 등록 ---");
System.out.print("도서 번호 >> ");
vo.setCode(scanner.next()); scanner.nextLine();
System.out.print("도서명 >> ");
vo.setName(scanner.nextLine());
System.out.print("도서 가격 >> ");
vo.setPrice(scanner.nextInt());
System.out.print("출판사 >> ");
vo.setMaker(scanner.next());
su = bookService.insertBooks(vo);
if(su > 0)
System.out.println("도서 등록 성공!!");
else
System.out.println("도서 등록 실패~");
System.out.println("--- 도 서 목 록 ---");
list = bookService.getBooksList(null);
for(BooksVO book : list) {
System.out.println(book);
}
System.out.println();
System.out.println("--- 도서 정보 수정 ---");
System.out.print("도서 번호 >> ");
vo.setCode(scanner.next()); scanner.nextLine();
System.out.print("도서명 >> ");
vo.setName(scanner.nextLine());
System.out.print("도서 가격 >> ");
vo.setPrice(scanner.nextInt());
System.out.print("출판사 >> ");
vo.setMaker(scanner.next());
su = bookService.updateBooks(vo);
if(su > 0)
System.out.println("도서 수정 성공!!");
else
System.out.println("도서 성공 실패~");
System.out.println("--- 도 서 목 록 ---");
list = bookService.getBooksList(null);
for(BooksVO book : list) {
System.out.println(book);
}
System.out.println();
System.out.println("--- 도서 정보 삭제 ---");
System.out.print("도서 번호 >> ");
vo.setCode(scanner.next());
su = bookService.deleteBooks(vo);
if(su > 0)
System.out.println("도서 삭제 성공!!");
else
System.out.println("도서 삭제 실패~");
System.out.println("--- 도 서 목 록 ---");
list = bookService.getBooksList(null);
for(BooksVO book : list) {
System.out.println(book);
}
System.out.println();
System.out.println("--- 도서 정보 확인 ---");
System.out.print("도서 번호 >> ");
vo.setCode(scanner.next());
vo = bookService.getBooks(vo);
if(vo != null)
System.out.println(vo);
else
System.out.println("없는 도서입니다~");
}
}
BooksRowMapper.java
package com.book.template;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class BooksRowMapper implements RowMapper<BooksVO> {
@Override
public BooksVO mapRow(ResultSet rs, int rowNum) throws SQLException {
BooksVO vo = new BooksVO();
vo.setCode(rs.getString("code"));
vo.setName(rs.getString("name"));
vo.setPrice(rs.getInt("price"));
vo.setMaker(rs.getString("maker"));
return vo;
}
}
Q01_score
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.score</groupId>
<artifactId>template</artifactId>
<name>Q01_score</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>11</java-version>
<org.springframework-version>5.2.1.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<repositories>
<repository>
<id>oracle</id>
<url>http://maven.jahia.org/maven2</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>21.5.0.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
resources
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.score.template"/>
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
db.properties
jdbc.driverClassName=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:xe
jdbc.username=dbtest
jdbc.password=a1234
com.score.template
ScoreVO
package com.score.template;
public class ScoreVO {
private String no;
private String name;
private int kor;
private int eng;
private int mat;
private int tot;
private double avg;
private String logtime;
public ScoreVO() {}
public ScoreVO(String no, String name, int kor, int eng, int mat) {
super();
this.no = no;
this.name = name;
this.kor = kor;
this.eng = eng;
this.mat = mat;
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getKor() {
return kor;
}
public void setKor(int kor) {
this.kor = kor;
}
public int getEng() {
return eng;
}
public void setEng(int eng) {
this.eng = eng;
}
public int getMat() {
return mat;
}
public void setMat(int mat) {
this.mat = mat;
}
public int getTot() {
return tot;
}
public void setTot(int tot) {
this.tot = tot;
}
public double getAvg() {
return avg;
}
public void setAvg(double avg) {
this.avg = avg;
}
public String getLogtime() {
return logtime;
}
public void setLogtime(String logtime) {
this.logtime = logtime;
}
@Override
public String toString() {
return "성적 [ no : " + no + ", name : " + name + ", kor : " + kor + ", eng : " + eng + ", mat : " + mat + ", tot : "
+ tot + ", avg : " + avg + " ]";
}
}
ScoreService
package com.score.template;
import java.util.List;
public interface ScoreService {
int insertScore(ScoreVO vo);
List<ScoreVO> getScoreList(ScoreVO vo);
}
ScoreServiceImpl
package com.score.template;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("scoreService")
public class ScoreServiceImpl implements ScoreService{
@Autowired
private ScoreDAO scoreDAO;
@Override
public int insertScore(ScoreVO vo) {
return scoreDAO.insertScore(vo);
}
@Override
public List<ScoreVO> getScoreList(ScoreVO vo) {
return scoreDAO.getScoreList(vo);
}
}
ScoreDAO
package com.score.template;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class ScoreDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
private final String INSERT = "INSERT INTO score VALUES(?,?,?,?,?,?,?,SYSDATE)";
private final String LIST = "SELECT * FROM score ORDER BY avg DESC";
public int insertScore(ScoreVO vo) {
int su = 0;
int tot = vo.getKor() + vo.getEng() + vo.getMat();
double avg = tot/3.0;
vo.setTot(tot);
vo.setAvg(avg);
su = jdbcTemplate.update(INSERT, vo.getNo(), vo.getName(), vo.getKor(), vo.getEng(), vo.getMat(),vo.getTot(),vo.getAvg());
return su;
}
public List<ScoreVO> getScoreList(ScoreVO vo){
List<ScoreVO> list = null;
list = jdbcTemplate.query(LIST, new ScoreRowMapper());
return list;
}
}
ScoreRowMapper
package com.score.template;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class ScoreRowMapper implements RowMapper<ScoreVO>{
@Override
public ScoreVO mapRow(ResultSet rs, int rowNum) throws SQLException {
ScoreVO vo = new ScoreVO();
vo.setNo(rs.getString("no"));
vo.setName(rs.getString("name"));
vo.setKor(rs.getInt("kor"));
vo.setEng(rs.getInt("eng"));
vo.setMat(rs.getInt("mat"));
vo.setTot(rs.getInt("tot"));
vo.setAvg(rs.getDouble("avg"));
vo.setLogtime(rs.getString("logtime"));
return vo;
}
}
ScoreMain
package com.score.template;
import java.util.List;
import java.util.Scanner;
import org.springframework.context.support.GenericXmlApplicationContext;
public class ScoreMain {
public static void main(String[] args) {
GenericXmlApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
ScoreService scoreService = context.getBean("scoreService", ScoreService.class);
ScoreVO vo = new ScoreVO();
int su = 0;
List<ScoreVO> list = null;
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("1. 학생 정보 등록" + "2. 리스트" + ">>");
int i = sc.nextInt();
switch ( i ) {
case 1:
System.out.println("--- 학생 정보 등록 ---");
System.out.print("학번 >> ");
vo.setNo(sc.next());
System.out.print("이름 >> ");
vo.setName(sc.next());
System.out.print("국어 >> ");
vo.setKor(sc.nextInt());
System.out.print("영어 >> ");
vo.setEng(sc.nextInt());
System.out.print("수학 >> ");
vo.setMat(sc.nextInt());
su = scoreService.insertScore(vo);
if (su > 0) {
System.out.println("학생 정보 등록 성공");
} else {
System.out.println("학생 정보 등록 실패");
}
break;
case 2:
System.out.println("--- 학생 목록 조회 ---");
list = scoreService.getScoreList(null);
for (ScoreVO stu : list) {
System.out.println(stu);
}
break;
case 0:
System.out.print("종료");
System.exit(0);
default:
System.out.println("다시");
break;
}
}
}
}