-
DB연동Spring_FrameWork 2019. 3. 22. 17:21
JDBC 프로그래밍을 하다보면 중복되는 코드가 많다 .
반복되는 줄이려고 탬플릿 메서드 패턴과 전략패턴을 사용해서
스프링이 만든것이 JdbcTemplate이다 이것을 활용하면 코드를 줄일수 있음
스프링으로 DB연동을 처리할때 얻을 수 있는 장점은 트랜잭견부분이다.
JDBC API를 사용할 경우 , 트랜잭션을 처리하려면 다음과 같이 Connection 의 setAutoCommit()을 이용해서 자동 커밋을 비활성화 하고
commit() 과 rollback() 메서드를 이용해서 트랜잭션을 커밋하거나 롤백해야한다,
public void insert(Member member){
Connetion conn = null;
PreparedStatement = null;
try{
conn = DriverManager.getConnection("jdbc:mysql://localhost/sprig4fs?characterEncoding=utf8","id","passward");
conn.setAutoCommit(false)
....
conn.commit();
}catch(SQLException ex){
if(conn!=null)
try{conn.rollback();}catch(SQLException e){}
}finally(){
if(pstmt!=null){
try{pstmt.colse();}catch(SQLException e){}
}
if(conn!=null){
try{conn.colse();}catch(SQLException e){}
}
}
}
스프링을 사용하면 트랜잭션을 적용하고 싶은 메서드에 @Transactional 애노테이션을 붙이기만 하면 된다.
pom.xml설정
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152<?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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>sp4</groupId><artifactId>sp4-chap08</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.1.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>4.1.0.RELEASE</version></dependency><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.2.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.30</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.7</source><target>1.7</target><encoding>utf-8</encoding></configuration></plugin></plugins></build></project>cs mysql 스키마 생성
1234567891011121314create user 'spring4'@'localhost' identified by 'spring4';create database spring4fs character set=utf8;grant all privileges on spring4fs.* to 'spring4'@'localhost';create table spring4fs.MEMBER (ID int auto_increment primary key,EMAIL varchar(255),PASSWORD varchar(100),NAME varchar(100),REGDATE datetime,unique key (EMAIL)) engine=InnoDB character set = utf8;cs 1행 mysql 사용자 spring4 계정생성 (암호로 spring4 사용)
3행 spring4fs DB 생성
5행 spring4fs DB에 spring4 계정이 접근할 수 있도록 권한 부여
07 - 14 행 spring4fs DB에 Member테이블 생성 캐릭터셋은 utf8로 설정
그리고 예제에서 사용할 데이터를 미리 넣어둔다
insert into MEMBER(EMAIL, PASSWORD, NAME, REGDATE)
values('aaa@aaa.net','1234','kim',now());
03 DataSource 설정
JDBC API 는 DataSource를 이용해서 DB를 연결을 구하는 방법을 정의 하고 있다.
DataSoruce를 사용하면 다음과 같은 방식으로 Connection을 구할 수 있다.
스프링이 제공하는 DB 연동기능도 DataSource를 사용해서 DBConnection 을 구할 수 있도록 구현 되어 있다.
DB연동에 사용할 DataSource를 스프링 빈으로 등록하고
DB연동 기능을 구현한 빈객체는 DataSource를 주입받아 사용한다.
DataSource 기능을 제공하는 모듈로는 c3p0 와 dbcp 등이 존재하고,
스프링 테스트 목적으로 사용할 수 있는 DataSource 구현을 제공하고 있다.
c3p0 모듈이 제공하는 DataSource 구현을 사용한다.
c3p0모듈은 DataSource를 구현한 ComboPooledDataSource 클래스를 제공하고 있으므로, 이 클래스를 스프링 빈으로 등록해서 DataSource로 사용하면 된다.
12345678910111213141516171819<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="jdbc:mysql://localhost/spring4fs?characterEncoding=utf8" /><property name="user" value="spring4" /><property name="password" value="spring4" /></bean></beans>cs driverClass : JDBC 드라이버 클래스를 지정한다. 위설정은 MYSQL
jdbcUrl : JDBC URL 지정 , 데이터베이스와 테이블의 캐릭터 셋을 UTF-8로 설정 했으므로 JDBC URL의 caracterEncoding 파라미터를 이용해서 MYSQL에 연결할 사용할 캐릭터 셋을 UTF-8로 지정
user : 사용자 계정 지정
password : DB 연결할 때 사용할 암호 지정
close : 커넥션 풀에 보관된 Connection을 종료할 목적으로 사용됨.
04 JdbcTemplate 을 이용한 쿼리 실행
DataSource를 설정했다면 스프링이 제공하는 JdbcTemplate 클래스를 이용해서 DB를 연동 처리 할 수 있다.1234567891011121314151617package spring;import java.util.List;import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;public class MemberDao {private JdbcTemplate jdbcTemplate;public MemberDao(DataSource dataSource) {super();this.jdbcTemplate = new JdbcTemplate(dataSource);}cs 먼저 dataSource를 주입받도록 설정한다.
그리고 스프링에 MemberDao 클래스에 추가 했으므로 스프링 설정에 MemberDao 빈설정을 추가한다.
1234567891011121314151617181920212223<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="jdbc:mysql://localhost/spring4fs?characterEncoding=utf8" /><property name="user" value="spring4" /><property name="password" value="spring4" /></bean><bean id= "memberDao" class="spring.MemberDao"><constructor-arg ref="dataSource"/></bean></beans>cs JDBCTemplate를 이용한 조회 쿼리 실행
JdbcTemplate 클래스 SELECT 쿼리 실행을 위한 query() 메서드를 제공하고 있다.그중에서 자주 사용되는 쿼리 메소드- List<T> query(String sql, RowMapper<T> rowMapper)- List<T> query(String sql, Object[] args,RowMapper<T> rowMapper)- List<T> query(String sql, RowMapper<T> rowMapper, Object...args)sql파라미터로 전달받은 쿼리를 실행하고 rowmapper를 이용해서 ResultSet의 결과를 자바 객체로 변환한다.sql 파라미터가 인덱스 기반 파라미터 (PreparedStatement 의 물음표) 를 가진 경우 , args 파라미터를 이용해서 각 인텍스 파라미터를 지정한다.쿼리 실행결과를 변환하는 RowMapper 인터페이스는 다음과 같이 정의 되어있다.public interface RowMapper<T>{T mapRow(ResultSet rs, int rowNum)throws SQLException;}RowMapper의 mapRow() 메서드 SQL 실행결과로 구한 ResultSet으로부터 한 행의 데이터를 읽어와 이를 자바 객체로 변환해 주는 매퍼 기능을 구현한다.
한번 해보자
123456789101112131415161718192021222324252627282930313233343536373839404142434445package spring;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;public class MemberDao {private JdbcTemplate jdbcTemplate;public MemberDao(DataSource dataSource) {super();this.jdbcTemplate = new JdbcTemplate(dataSource);}public Member selectByEmail(String email) {//로우매퍼 인터페이스 구현RowMapper<Member> rm=new RowMapper<Member>() {@Overridepublic Member mapRow(ResultSet rs,int rowNum) throws SQLException {Member member = new Member(rs.getString("EMAIL"),rs.getString("PASSWORD"),rs.getString("NAME"),rs.getTimestamp("REGDATE"));member.setId(rs.getLong("ID"));return member;}};//jdbc탬플레이트에 query 실행List<Member> result = jdbcTemplate.query("select *from MEMBER where EMAIL =?", rm,email);//없으면 null 반환 있으면 리스트의 반환return result.isEmpty() ? null : result.get(0);}}cs selectAll도 구현
1234567891011121314151617public List<Member> selectAll() {List<Member> results = jdbcTemplate.query("select * from MEMBER",new RowMapper<Member>() {@Overridepublic Member mapRow(ResultSet rs, int rowNum) throws SQLException {Member member= new Member(rs.getString("EMAIL"),rs.getString("PASSWORD"),rs.getString("NAME"),rs.getTimestamp("REGDATE"));member.setId(rs.getLong("ID"));return member;}});return results;}cs 결과가 1행인 경우 조회 메서드 : queryForObject()
만약에 카운트 같은 쿼리는 정수 타입으로 바로 받는 게 편하다1234public int count() {Integer count = jdbcTemplate.queryForObject("select count(*) from MEMBER", Integer.class);return count;}cs queryforObject의 주의점은 결과는 반드시 한 행
그 이상이면 오류가 발생한다.
정확히 1개가 아니라면 query 메서드를 사용해야한다.
JDBCTemplate을 이용한 변경 쿼리 실행
INSERT, UPDATE, DELETE 쿼리를 실행할 때에는 다음의 update()메서드를 사용하면된다.- int update(String sql)- int update(String sql,Object...args)update 사용예1234public void update(Member member) {jdbcTemplate.update("update MEMBER set NAME = ?, PASSWORD = ? where EMAIL = ?",member.getName(), member.getPassword(), member.getEmail());}cs PreparedStatementCreator를 이용한 쿼리 실행
지금 까지 코드는 쿼리에서 사용할 값을 인자로 전달해 주었다.
1234public void update(Member member) {jdbcTemplate.update("update MEMBER set NAME = ?, PASSWORD = ? where EMAIL = ?",member.getName(), member.getPassword(), member.getEmail());}cs 경우에 따라 set 메서드를 사용해서 직접 인덱스 파라미터 값을 설정해 주어야 할 때가 있다.
이런 경우에는 PreparedStatementCreator를 인자로 받는 메서드를 이용해서 직접 PreparedStatement를 생성하고 설정해 주어야한다.
jdbc.Template,update(new PreparedStatementCreator(){
@Override
public PreparedStatement createPreparedStatement(Connection con)throws SQLException{
//파라미터로 전달받은 Connection 을 이용해서 PreparedStatement를 생성
PreparedStatement pstmt = con.preapeStatement("insert into MEMBER(EMAIL, PASSWORD, NAME, REGDATE)values (?,?,?,?)");
// 인덱스 파라미터 값 설정
pstmt.setString(1,member.getEmail());
pstmt.setString(2,member.getPasswordl());
pstmt.setString(3,member.getName());
pstmt.setTimestamp(4,new Timestamp(member.getRegisterDate().getTime()));
//생성한 pstmt 리턴
return pstmt
}
});
INSERT 쿼리 실행시 , KeyHolder를 이용해서 자동 생성 키 값을 구하기
오토 인크리먼트같은 자동 증가 칼럼테이블에 값을 삽입할 경우 , 해당 칼럼의 값이 자동으로 생성된다.보통 INSERT 문에는 increment 하는 값을 넣지 않음쿼리 실행후 생성된 키값을 알고 싶다면KeyHolder를 사용하면 된다.MemberDao insert()메서드를 구현 할 때 삽입되는 Member 객체의 ID 값을 구할수 있다.12345678910111213141516171819KeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection con)throws SQLException {PreparedStatement pstmt = con.prepareStatement("insert into MEMBER (EMAIL, PASSWORD, NAME, REGDATE) "+"values (?, ?, ?, ?)",new String[] {"ID"});pstmt.setString(1, member.getEmail());pstmt.setString(2, member.getPassword());pstmt.setString(3, member.getName());pstmt.setTimestamp(4,new Timestamp(member.getRegisterDate().getTime()));return pstmt;}}, keyHolder);Number keyValue = keyHolder.getKey();member.setId(keyValue.longValue());cs PreparedStatement pstmt = con.prepareStatement("insert into MEMBER (EMAIL, PASSWORD, NAME, REGDATE) "+"values (?, ?, ?, ?)",new String[] {"ID"});여기에서 두번째 파라미터가 자동증가 칼럼이므로 아이디를줌
update()메서드 는 PreaparedStatement를 실행후 , 자동 생성된 키값을 KeyHolder에 보관한다.
보관된 키는 getKey 메서드로 구할 수있다.
Number로 받은후 원하는 타입으로 변경해서 사용한다.
다음코드는 long타입으로 변환
Number keyValue = keyHolder.getKey();member.setId(keyValue.longValue());05 MemberDAO 테스트
메인 클래스 작성하자1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162package main;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;import org.springframework.context.support.AbstractApplicationContext;import org.springframework.context.support.GenericXmlApplicationContext;import spring.Member;import spring.MemberDao;public class MainForMemberDao {private static MemberDao memberDao;public static void main(String[] args) {AbstractApplicationContext ctx =new GenericXmlApplicationContext("classpath:appCtx.xml");memberDao = ctx.getBean("memberDao", MemberDao.class);selectAll();updateMember();insertMember();ctx.close();}private static void selectAll() {System.out.println("----- selectAll");int total = memberDao.count();System.out.println("전체 데이터: " + total);List<Member> members = memberDao.selectAll();for (Member m : members) {System.out.println(m.getId() + ":" + m.getEmail() + ":" + m.getName());}}private static void updateMember() {System.out.println("----- updateMember");Member member = memberDao.selectByEmail("aaa@aaa.net");String oldPw = member.getPassword();String newPw = Double.toHexString(Math.random());member.changePassword(oldPw, newPw);memberDao.update(member);System.out.println("암호 변경: " + oldPw + " > " + newPw);}private static void insertMember() {System.out.println("----- insertMember");SimpleDateFormat dateFormat = new SimpleDateFormat("MMddHHmmss");String prefix = dateFormat.format(new Date());System.out.println("prefix :"+prefix);Member member =new Member(prefix + "@test.com", prefix, prefix, new Date());memberDao.insert(member);System.out.println(member.getId() + " 데이터 추가");}}cs 트랜잭션 처리
두개이상의 쿼리를 한번의 작업에 서 실행해야할때@Transaction을 이용한 트랜잭션 처리
트랜잭션범위를 지정 가능한 애노테이션123456789101112131415161718192021222324package spring;import org.springframework.transaction.annotation.Transactional;public class ChangePasswordService {private MemberDao memberDao;public ChangePasswordService(MemberDao memberDao) {this.memberDao = memberDao;}@Transactionalpublic void changePassword(String email, String oldPwd, String newPwd) {Member member = memberDao.selectByEmail(email);if (member == null)throw new MemberNotFoundException();member.changePassword(oldPwd, newPwd);memberDao.update(member);}}cs chagePassword() 메서드에서 실행되는 코드를 하나의 트랜잭션 범위에서 실행한다.따라서, memberDao,selectByEmail()에서 실행하는 쿼리와member.changePassword() 에서 실행하는 쿼리가 한트랜잭션에서 묶여서 실행된다.@Transactional 애노테이션이 제대로 동작하려면 다음의 두가지 내용을 스프링 설정에 추가해야한다.1. PlatformTransactionManager 빈 설정2. @Transactional 애노테이션 활성화 설정1234567891011121314151617181920212223242526272829<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="jdbc:mysql://localhost/spring4fs?characterEncoding=utf8" /><property name="user" value="spring4" /><property name="password" value="spring4" /></bean><bean id = "transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><tx:annotation-driven transaction-manager="transactionManager"/><bean id= "memberDao" class="spring.MemberDao"><constructor-arg ref="dataSource"/></bean></beans>cs PlatformTransactionManager는 스프링이 제공하는 트랜잭션 관리자를 위한 인터페이스이다.스프링으 구현 기술에 상관없이 동일한 방식으로 트랜잭션을 처리하기 위해 이 인터페이스를 사용함JDBC 연동을 사용하는 경우 DataSourceTracsactionManager클래스를
PlatformTransactionManager로 사용한 경우다.
위설정은 dataSource를 프로퍼티의 값으로 이용해서 트래잭션 연동에 사용할 DataSource를 지정한다.
<tx:annotation-driven> 태그는 @Transactional 애노태이션을 실행하는 기능을 활성화 .
transaction-manager 속성을 사용해서 트랜잭션을 수행할때 사용할 PlatformTransactionManager 빈을 지정한다.
앞서는 transactionManger 빈을 설정 했다.
트랜잭션 처리를 위한 설정을 완료하면 , 트랜잭션 범위에서 실행하고 싶은 스프링 빈 객체의 메서두애 @Transactional 애노테이션을 붙이면 된다.
chagePwdSvc를 실행할 메인클래스를 작성
12345678910111213141516171819202122232425262728293031package main;import org.springframework.context.support.AbstractApplicationContext;import org.springframework.context.support.GenericXmlApplicationContext;import spring.ChangePasswordService;import spring.IdPasswordNotMatchingException;import spring.MemberNotFoundException;public class MainForCPS {public static void main(String[] args) {AbstractApplicationContext ctx =new GenericXmlApplicationContext("classpath:appCtx.xml");ChangePasswordService cps =ctx.getBean("changePwdSvc", ChangePasswordService.class);try {cps.changePassword("aaa@aaa.net", "1234", "1111");System.out.println("암호를 변경했습니다.");} catch (MemberNotFoundException e) {System.out.println("회원 데이터가 존재하지 않습니다.");} catch (IdPasswordNotMatchingException e) {System.out.println("암호가 올바르지 않습니다.");}ctx.close();}}cs Log를 보기 위해 Log4j를 사용해 보자
pom.xml에 log4j.xml추가
12345<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>cs 메이븐 업데이트 후
로그를 어떤형식으로 어디에 기록할지 에 대한 설정 파일로 부터 읽어온다.
src/main/resources
log4j.xml 에 다음과 같이 설정
123456789101112131415161718192021<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"><log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"><appender name="console" class="org.apache.log4j.ConsoleAppender"><layout class="org.apache.log4j.PatternLayout"><param name="ConversionPattern"value="[%t] [%d{yyyy-MM-dd HH:mm:ss}] %-5p %c:%M - %m%n" /></layout></appender><root><priority value="INFO" /><appender-ref ref="console" /></root><logger name="org.springframework.jdbc"><level value="DEBUG" /></logger></log4j:configuration>cs 로그의 디버그 레벨을 보기위한 설정
메인을 실행했더니
<bean id="changePwdSvc" class="spring.ChangePasswordService">
<constructor-arg ref="memberDao"/>
</bean>
빈등록을 안했었음
아까 비번이 랜덤으로 바뀌어있을 것이므로
비민번호를 "1234"로 변경후
12345678910111213141516171819202122log4j:WARN Continuable parsing error 21 and column 23log4j:WARN 요소 유형 "log4j:configuration"의 콘텐츠는 "(renderer*,throwableRenderer?,appender*,plugin*,(category|logger)*,root?,(categoryFactory|loggerFactory)?)"과(와) 일치해야 합니다.[main] [2019-03-26 03:10:06] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader:loadBeanDefinitions - Loading XML bean definitions from class path resource [appCtx.xml][main] [2019-03-26 03:10:06] INFO org.springframework.context.support.GenericXmlApplicationContext:prepareRefresh - Refreshing org.springframework.context.support.GenericXmlApplicationContext@1376c05c: startup date [Tue Mar 26 03:10:06 KST 2019]; root of context hierarchy[main] [2019-03-26 03:10:06] INFO com.mchange.v2.log.MLog:<clinit> - MLog clients using log4j logging.[main] [2019-03-26 03:10:07] INFO com.mchange.v2.c3p0.C3P0Registry:banner - Initializing c3p0-0.9.2.1 [built 20-March-2013 10:47:27 +0000; debug? true; trace: 10][main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager:getTransaction - Creating new transaction with name [spring.ChangePasswordService.changePassword]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''[main] [2019-03-26 03:10:07] INFO com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource:getPoolManager - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge4n6a11eiedp6vm1k2z|462d5aee, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge4n6a11eiedp6vm1k2z|462d5aee, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost/spring4fs?characterEncoding=utf8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 15, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 3, numHelperThreads -> 3, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ][main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager:doBegin - Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@6ae5aa72] for JDBC transaction[main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager:doBegin - Switching JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@6ae5aa72] to manual commit[main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.core.JdbcTemplate:query - Executing prepared SQL query[main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.core.JdbcTemplate:execute - Executing prepared SQL statement [select *from MEMBER where EMAIL =?][main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.core.JdbcTemplate:update - Executing prepared SQL update[main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.core.JdbcTemplate:execute - Executing prepared SQL statement [update MEMBER set NAME = ?, PASSWORD = ? where EMAIL = ?][main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.core.JdbcTemplate:doInPreparedStatement - SQL update affected 1 rows[main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager:processCommit - Initiating transaction commit[main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager:doCommit - Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@6ae5aa72][main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager:doCleanupAfterCompletion - Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@6ae5aa72] after transaction[main] [2019-03-26 03:10:07] DEBUG org.springframework.jdbc.datasource.DataSourceUtils:doReleaseConnection - Returning JDBC Connection to DataSource암호를 변경했습니다.[main] [2019-03-26 03:10:07] INFO org.springframework.context.support.GenericXmlApplicationContext:doClose - Closing org.springframework.context.support.GenericXmlApplicationContext@1376c05c: startup date [Tue Mar 26 03:10:06 KST 2019]; root of context hierarchycs 진행하면 된다.
'Spring_FrameWork' 카테고리의 다른 글
스프링 부트에서 JPA 데이터베이스 사용하기 (0) 2020.06.06 AOP소개 (0) 2019.03.19 빈 라이프사이클과 범위 (0) 2019.03.19 DI정리 (0) 2019.03.18 의존 자동 주입 (0) 2019.03.15