Spring JDBC
โข
JDBC & Spring JDBC ์์กด์ฑ
โข
๋ฐ์ดํฐ ์์ค ์ค์ & Spring JDBC ๋น ๋ฑ๋ก
โข
์ธ์ฝ๋ฉ ํํฐ
โข
ํ
์ด๋ธ ์์ฑ
โข
๋น์ฆ๋์ค ๋ก์ง
โข
ํธ๋์ญ์
JDBC & Spring JDBC ์์กด์ฑ ์ค์
โข
pom.xml
<!-- mysql ๋๋ผ์ด๋ฒ -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.1.0</version>
</dependency>
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
XML
๋ณต์ฌ
โข
pom.xml - lombok
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
XML
๋ณต์ฌ
โข
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.joeun</groupId>
<artifactId>test</artifactId>
<name>Spring-JDBC</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.3.10</org.springframework-version>
<org.aspectj-version>1.9.7</org.aspectj-version>
<!-- ์๋ ๋ฒ์ ์ผ๋ก ํ์ ๋, @AfterReturning ์์ returning ์ด ๊ณ์ null ์ธ ์ด์ -->
<!-- <org.springframework-version>5.0.7.RELEASE</org.springframework-version> -->
<!-- <org.aspectj-version>1.5.4</org.aspectj-version> -->
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<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>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<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>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<!-- <dependency> -->
<!-- <groupId>javax.servlet</groupId> -->
<!-- <artifactId>servlet-api</artifactId> -->
<!-- <version>2.5</version> -->
<!-- <scope>provided</scope> -->
<!-- </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>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<!-- mysql ๋๋ผ์ด๋ฒ -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.1.0</version>
</dependency>
<!-- Spring JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</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>
<!-- ์๋ฐ ๋ฒ์ : 1.6 โ 1.8 -->
<!-- ํ๋ฌ๊ทธ์ธ ๋ฒ์ : 2.5.1 โ 3.8.1 -->
<!-- parameter ์ธ์ ์ถ๊ฐ -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</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>
XML
๋ณต์ฌ
๋ฐ์ดํฐ ์์ค ์ค์ , Spring JDBC ๋น ๋ฑ๋ก
โข
root-context.xml
<!-- ๋ฐ์ดํฐ ์์ค ๋ฑ๋ก -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/joeun"></property>
<property name="username" value="joeun"></property>
<property name="password" value="123456"></property>
</bean>
<!-- JDBC Template ๋น ๋ฑ๋ก -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
XML
๋ณต์ฌ
์ธ์ฝ๋ฉ ํํฐ
โข
web.xml
<!-- ์ธ์ฝ๋ฉ ํํฐ(ํ๊ธ๊นจ์ง ๋ฐฉ์ง) -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
SQL
๋ณต์ฌ
ํ ์ด๋ธ ์์ฑ
โข
board.sql
CREATE TABLE `board` (
`no` int NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`writer` varchar(100) NOT NULL,
`content` text,
`reg_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`upd_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`views` int NOT NULL DEFAULT '0',
PRIMARY KEY (`no`)
) COMMENT='๊ฒ์ํ';
SQL
๋ณต์ฌ
ํธ๋์ญ์
ํธ๋์ญ์
์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํ ๋ฒ์ ์ํ๋์ด์ผํ๋ ์ผ๋ จ์ ์์
์ ์๋ฏธํฉ๋๋ค. ์ด๋ฌํ ์์
์ ๋ชจ๋ ์๋ฃ๋๊ฑฐ๋ ์๋ฌด๊ฒ๋ ์ํ๋์ง ์์์ผ ํฉ๋๋ค. ํธ๋์ญ์
์ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ๊ณผ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ํ์์ ์ก๊ธ์ด ๋ฐ์ํ ๋ ์ก๊ธ๊ณผ ๋์์ ์
๊ธ์ด ๋ชจ๋ ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด์ ธ์ผ ํ๋ฉฐ, ํ๋์ ์์
์ด ์คํจํ๋ฉด ๋ชจ๋ ์์
์ ๋กค๋ฐฑ๋์ด์ผ ํฉ๋๋ค.
ํธ๋์ญ์ ํน์ง - A.C.I.D
ํธ๋์ญ์
์ ๋ค์์ ํน์ง์ ๊ฐ์ง๊ณ ์์ต๋๋ค:
โข
์์์ฑ (Atomicity): ํธ๋์ญ์
๋ด์ ๋ชจ๋ ์์
์ ์ผ๋ถ๋ผ๋ ์คํจํ๋ฉด ์ ์ฒด ํธ๋์ญ์
์ด ๋กค๋ฐฑ๋์ด์ผ ํฉ๋๋ค.
โข
์ผ๊ด์ฑ (Consistency): ํธ๋์ญ์
์ด ์ํ๋๊ธฐ ์ ๊ณผ ํ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ผ๊ด๋ ์ํ์ฌ์ผ ํฉ๋๋ค.
โข
๊ฒฉ๋ฆฌ์ฑ (Isolation): ๋์์ ์คํ๋๋ ์ฌ๋ฌ ํธ๋์ญ์
์ ์๋ก ์ํฅ์ ์ฃผ์ง ์๊ณ ๋
๋ฆฝ์ ์ผ๋ก ์คํ๋์ด์ผ ํฉ๋๋ค.
โข
์ง์์ฑ (Durability): ํธ๋์ญ์
์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ ์๊ตฌ์ ์ผ๋ก ์ ์ฅ๋์ด์ผ ํ๋ฉฐ, ์์คํ
์ฅ์ ๋ฐ์ ์์๋ ์ ์ง๋์ด์ผ ํฉ๋๋ค.
โข
ํธ๋์ญ์
์์กด์ฑ ์ค์
โฆ
๋ค์ ์คํ์ด์ค ๋ฐ ์คํค๋ง ์ค์
โฆ
ํธ๋์ญ์
๊ด๋ฆฌ์ ๋น ๋ฑ๋ก
โฆ
ํธ๋์ญ์
์ด๋
ธํ
์ด์
๊ธฐ๋ฅ ํ์ฑํ
โข
์๋น์ค ๊ตฌํ ํด๋์ค์ ์ด๋
ธํ
์ด์
์ ์ฉ
โฆ
@Transactional
ํธ๋์ญ์ ์์กด์ฑ ์ค์
๋ค์ ์คํ์ด์ค
โข
root-context.xml
xmlns:tx="http://www.springframework.org/schema/tx"
XML
๋ณต์ฌ
์คํค๋ง ์ค์
โข
root-context.xml
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.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
XML
๋ณต์ฌ
ํธ๋์ญ์ ๊ด๋ฆฌ์ ๋น ๋ฑ๋ก
โข
root-context.xml
<!-- ํธ๋์ญ์
๊ด๋ฆฌ์ ๋น ๋ฑ๋ก -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
XML
๋ณต์ฌ
ํธ๋์ญ์ ์ด๋ ธํ ์ด์ ๊ธฐ๋ฅ ํ์ฑํ
โข
root-context.xml
<!-- ํธ๋์ญ์
์ด๋
ธํ
์ด์
๊ธฐ๋ฅ ํ์ฑํ -->
<tx:annotation-driven />
XML
๋ณต์ฌ
์๋น์ค ๊ตฌํ ํด๋์ค์ ์ด๋ ธํ ์ด์ ์ ์ฉ
โข
BoardServiceImpl.java
@Transactional
@Override
public void join(User user) throws Exception {
userDAO.join(user);
UserAuth userAuth = new UserAuth();
userAuth .setUserNo(user.getUserNo());
userAuth .setAuth("ROLE_USER");
userDAO.insertAuth(userAuth );
}
Java
๋ณต์ฌ
๋น์ฆ๋์ค ๋ก์ง
โข
controller
โฆ
BoardController.java
โข
dto
โฆ
Board.java
โข
dao
โฆ
BoardDAO.java
โข
service
โฆ
BoardService.java
โฆ
BoardServiceImpl.java
controller
โข
BoardController.java
BoardController.java
package com.joeun.test.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.joeun.test.dto.Board;
import com.joeun.test.service.BoardService;
@Controller
@RequestMapping("/board")
public class BoardController {
private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
@Autowired
private BoardService boardService;
// ๊ฒ์๊ธ ๋ชฉ๋ก
// @RequestMapping(value = "/list", method = RequestMethod.GET)
@GetMapping("/list") // Spring 4.3 ๋ฒ์ ๋ถํฐ ์ฌ์ฉ
public String list(Model model) throws Exception {
List<Board> boardList = boardService.list();
model.addAttribute(boardList);
return "board/list";
}
// ๊ฒ์๊ธ ์กฐํ
@GetMapping("/read")
public String read(Model model, int no) throws Exception {
Board board= boardService.select(no);
model.addAttribute(board);
return "board/read";
}
// ๊ฒ์๊ธ ๋ฑ๋ก
@GetMapping("/insert")
public String insert() throws Exception {
return "board/insert";
}
// ๊ฒ์๊ธ ๋ฑ๋ก ์ฒ๋ฆฌ
@PostMapping("/insert")
public String insert(Board board) throws Exception {
int result = boardService.insert(board);
return "redirect:/board/list";
}
// ๊ฒ์๊ธ ์์
@GetMapping("/update")
public String update(Model model, int no) throws Exception {
Board board= boardService.select(no);
model.addAttribute(board);
return "board/update";
}
// ๊ฒ์๊ธ ์์ ์ฒ๋ฆฌ
@PostMapping("/update")
public String update(Board board) throws Exception {
int result = boardService.update(board);
return "redirect:/board/list";
}
// ๊ฒ์๊ธ ์ญ์ ์ฒ๋ฆฌ
@PostMapping("/delete")
public String delete(int no) throws Exception {
int result = boardService.delete(no);
return "redirect:/board/list";
}
}
Java
๋ณต์ฌ
dto
โข
Board.java
Board.java
package com.joeun.test.dto;
import java.util.Date;
import lombok.Data;
@Data
public class Board {
private int no;
private String title;
private String writer;
private String content;
private Date regDate;
private Date updDate;
private int views;
public Board() {
}
public Board(String title, String writer, String content) {
this.title = title;
this.writer = writer;
this.content = content;
}
}
Java
๋ณต์ฌ
dao
โข
BoardDAO.java
BoardDAO.java
package com.joeun.test.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
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;
import com.joeun.test.dto.Board;
@Repository // ๋ฐ์ดํฐ ์ก์ธ์ค ๊ฐ์ฒด๋ก ๋น ๋ฑ๋ก
public class BoardDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* ๊ฒ์๊ธ ๋ชฉ๋ก ์กฐํ
* @return
*/
public List<Board> list() {
String sql = " SELECT * FROM board ";
List<Board> boardList = jdbcTemplate.query(sql, new RowMapper<Board>() {
@Override
public Board mapRow(ResultSet rs, int rowNum) throws SQLException {
Board board = new Board();
board.setno( rs.getInt("no") );
board.setTitle( rs.getString("title") );
board.setWriter( rs.getString("writer") );
board.setContent( rs.getString("content") );
board.setRegDate( rs.getTimestamp("reg_date") );
board.setUpdDate( rs.getTimestamp("upd_date") );
board.setViews( rs.getInt("views") );
return board;
}
});
return boardList;
}
public Board select(int no) {
String sql = " SELECT * FROM board WHERE no = ? ";
// List<Board> boardList = jdbcTemplate.query(sql, new RowMapper<Board>() {
// @Override
// public Board mapRow(ResultSet rs, int rowNum) throws SQLException {
// Board board = new Board();
// board.setno( rs.getInt("no") );
// board.setTitle( rs.getString("title") );
// board.setWriter( rs.getString("writer") );
// board.setContent( rs.getString("content") );
// board.setRegDate( rs.getTimestamp("reg_date") );
// board.setUpdDate( rs.getTimestamp("upd_date") );
// board.setViews( rs.getInt("views") );
// return board;
// }
// }, no);
//
// Board board = null;
// if( boardList.isEmpty() )
// board = null;
// else
// board = boardList.get(0);
// 2๋ฒ์งธ ๋ฐฉ๋ฒ
Board board = jdbcTemplate.queryForObject(sql, new RowMapper<Board>() {
@Override
public Board mapRow(ResultSet rs, int rowNum) throws SQLException {
Board board = new Board();
board.setno( rs.getInt("no") );
board.setTitle( rs.getString("title") );
board.setWriter( rs.getString("writer") );
board.setContent( rs.getString("content") );
board.setRegDate( rs.getTimestamp("reg_date") );
board.setUpdDate( rs.getTimestamp("upd_date") );
board.setViews( rs.getInt("views") );
return board;
}
}, no);
// 3๋ฒ์งธ ๋ฐฉ๋ฒ
// Object[] argList = new Object[]{no};
// Board board = jdbcTemplate.queryForObject(sql, argList, new RowMapper<Board>() {
// @Override
// public Board mapRow(ResultSet rs, int rowNum) throws SQLException {
// Board board = new Board();
// board.setno( rs.getInt("no") );
// board.setTitle( rs.getString("title") );
// board.setWriter( rs.getString("writer") );
// board.setContent( rs.getString("content") );
// board.setRegDate( rs.getTimestamp("reg_date") );
// board.setUpdDate( rs.getTimestamp("upd_date") );
// board.setViews( rs.getInt("views") );
// return board;
// }
// });
return board;
}
public int insert(Board board) {
String sql = " INSERT INTO board(title, writer, content) "
+ " VALUES ( ?, ?, ? ) ";
Object[] args = new Object[] {board.getTitle(), board.getWriter(), board.getContent()};
int result = jdbcTemplate.update(sql, args);
// int result = jdbcTemplate.update(sql, board.getTitle(), board.getWriter(), board.getContent());
return result;
}
public int update(Board board) {
String sql = " UPDATE board "
+ " SET title = ? "
+ " ,writer = ? "
+ " ,content = ? "
+ " ,upd_date = now() "
+ " WHERE no = ? ";
Object[] args = new Object[] {board.getTitle(), board.getWriter(), board.getContent(), board.getNo()};
int result = jdbcTemplate.update(sql, args);
return result;
}
public int delete(int no) {
String sql = " DELETE FROM board "
+ " WHERE no = ? ";
Object[] args = new Object[] {no};
int result = jdbcTemplate.update(sql, args);
return result;
}
}
Java
๋ณต์ฌ
service
โข
BoardService.java
โข
BoardServiceImpl.java
BoardService.java
package com.aloha.spring.service;
import java.util.List;
import com.aloha.spring.dto.Board;
public interface BoardService {
// ๊ฒ์๊ธ ๋ชฉ๋ก
public List<Board> list() throws Exception;
// ๊ฒ์๊ธ ์กฐํ
public Board select(int no);
// ๊ฒ์๊ธ ๋ฑ๋ก
public Integer insert(Board board) throws Exception;
// ๊ฒ์๊ธ ์์
public Integer update(Board board) throws Exception;
// ๊ฒ์๊ธ ์ญ์
public Integer delete(int no) throws Exception;
}
Java
๋ณต์ฌ
BoardServiceImpl.java
package com.aloha.spring.service;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.aloha.spring.dao.BoardDAO;
import com.aloha.spring.dto.Board;
@Service // ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ์๋น์ค ํด๋์ค๋ก ๋น ๋ฑ๋ก
public class BoardServiceImpl implements BoardService {
private static final Logger logger = LoggerFactory.getLogger(BoardServiceImpl.class);
@Autowired
private BoardDAO boardDAO;
@Override
public List<Board> list() throws Exception {
List<Board> boardList = boardDAO.list();
return boardList;
}
@Override
public Board select(int no) {
Board board = boardDAO.select(no);
return board;
}
@Override
public Integer insert(Board board) throws Exception {
int result = boardDAO.insert(board);
return result;
}
@Override
public Integer update(Board board) throws Exception {
int result = boardDAO.update(board);
return result;
}
@Override
public Integer delete(int no) throws Exception {
int result = boardDAO.delete(no);
return result;
}
}
Java
๋ณต์ฌ