노승현
DBCP 본문
우리 손에 JdbcTemplate 파일이 없다면
어노테이션 사용을 못한다.
DBCP
DB Connection Pool
- MemerDAO02 with 템플릿 패턴
- RowMapper 클래스 작성
- 템플릿 의존주입을 위한 템플릿 new => <bean>
- Util 역할의 dataSource 가 필요
- 이 과정에서 pom.xml. jar 추가
- 기존 DAO -> DAO02 로 Repository 변경
- Impl 멤버변수 타입 변경
- 사용하지 않는 임포트는 지워라
Destroy-method=“close”
자동 close 해주는 역할이지만 속도가 따라오지 못한다면 지워줘라
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
외부에서 가져오는 클래스이기때문에 따로 설정할 수가 없다.
개발자가 만든것
Advisor ==aspect == 위빙처리해달라 == 결합
설정으로 만든 것
FC 중요 <- 유일하게 Servlet 파일
1.FC == DS
Servlet
스프링 컨테이너는 POJO만 new 가능
서블릿 컨테이너(톰캣, 웹 서버)로 new
-> .xml(설정파일)이 필요
사용자(브라우저,Client)
요청
요청정보를 FC(DS)에서 받아서
요청정보를 꺼냄
요청에 맞는 Action(Controller)을 수행해야하는데,
이때 활용하는게 HM
Action을 수행하면
어디로(경로)
어떻게(포워드 vs 리다이렉트) 가야하는지 전달
+ 요청한 정보와 함께(data, datas, memberInfo, list 등으로)
ActionForward 를 썼지만,
Spring 에서는 VR 을 사용
output을 토대로 응답
SpringMVC 구조
스프링(@어노테이션)을 사용해 기존에 사용하던 DAO를 업그레이드
변경점
- DB연결방식 변경
- destroy-method="close"
- 자동으로 사용 후 객체를 닫아준다
- destroy-method="close"
- 멤버변수
//JDBCUtil.java → applicationContext.xml()
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/kimdb" />
<property name="username" value="root" />
<property name="password" value="1234" />
</bean>
멤버변수
// 변경 전
private Connection conn;
private PreparedStatement pstmt;
↓
// 변경 후
@Autowired
private JdbcTemplate jdbcTemplate;
- 메서드(변경 전)
1)CUD
public boolean insert(MemberDTO mDTO) {
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(INSERT);
pstmt.setString(1, mDTO.getMid());
pstmt.setString(2, mDTO.getPassword());
pstmt.setString(3, mDTO.getName());
pstmt.setString(4, mDTO.getRole());
int rs=pstmt.executeUpdate();
if(rs<=0) {
return false;
}
} catch (SQLException e) {
e.printStackTrace();
return false;
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
return true;
}
2)R One
public MemberDTO selectOne(MemberDTO mDTO) {
MemberDTO data=null;
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(SELECTONE);
pstmt.setString(1, mDTO.getMid());
pstmt.setString(2, mDTO.getPassword());
ResultSet rs=pstmt.executeQuery();
if(rs.next()) {
data=new MemberDTO();
data.setMid(rs.getString("MID"));
data.setPassword(rs.getString("PASSWORD"));
data.setName(rs.getString("NAME"));
data.setRole(rs.getString("ROLE"));
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
return data;
}
3)R All
public ArrayList<MemberDTO> selectAll(MemberDTO mDTO) {
ArrayList<MemberDTO> datas=new ArrayList<MemberDTO>();
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(SELECTALL);
ResultSet rs=pstmt.executeQuery();
while(rs.next()) {
MemberDTO data=new MemberDTO();
data.setMid(rs.getString("MID"));
data.setPassword(rs.getString("PASSWORD"));
data.setName(rs.getString("NAME"));
data.setRole(rs.getString("ROLE"));
datas.add(data);
}
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
return datas;
}
메서드(변경 후)
- queryForObject SelectOne는 반환값이 하나라서 사용
- CUD와 다르게 인자를 배열로 전달해야함
- new MemberRowMapper 인자 위치를 정하기 위해서 사용(인자를 매칭시켜주기 위해서)
- 결과값을 반환하는 객체는 싱글톤 유지를 하지 않는다
1)CUD
public boolean insert(MemberDTO mDTO) {
int result = jdbcTemplate.update(INSERT, mDTO.getMid(), mDTO.getPassword(), mDTO.getName(), mDTO.getRole());
if (result <= 0) {
return false;
}
return true;
}
2)R One
public MemberDTO selectOne(MemberDTO mDTO) {
Object[] args = {mDTO.getMid(), mDTO.getPassword()};
return jdbcTemplate.queryForObject(SELECTONE, args, new MemberRowMapper());
}
3)R All
public ArrayList<MemberDTO> selectAll(MemberDTO mDTO) {
return (ArrayList<MemberDTO>)jdbcTemplate.query(SELECTALL, new MemberRowMapper());
}
변경법
1) 기존 CRUD메서드의 내용을 전부 지운다
2) 멤버변수 JDBCUtill을 지우고 JdbcTemplate을 작성한다
- 템플릿 패턴을 활용한 클래스반복되는 JDBC의 로직을 캡슐화한 클래스
- 기존 DAO에 템플릿 패턴을 활용한 클래스를 구현해서 가독성 증가
- // @Autowired꼭 하기
3) CRUD 메서드에 코드를 작성한다
4) RowMapper(MemberRowMapper)클래스 작성
5) 의존 주입(DB연결 객체)
- dataSource, jdbcTemplate
6) 멤버변수 타입(자료형) 변경(Impl.java파일의 멤버변수)
- 트랜잭션
- 기능의 단위 근대 원자성(이제 더이상 쪼갤 수 없는 가장 작은 단위)
- 특징은 4가지가 있는데 그 중 원자성과 롤백을 배움
- .xml(설정파일)에 필요한 코드
1.
xmlns:tx="http://www.springframework.org/schema/tx"
2.
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
3.
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" />
// CRUD중 R은 트랜잭션이 불필요해 read-only="true"작성
<tx:method name="select*" read-only="true" />
</tx:attributes>
</tx:advice>
4.
<aop:config>
<aop:pointcut id="aPointcut" expression="execution(* com.spring.biz..*Impl.*(..))" />
// advisor == aspect == 위빙처리해달라 == 결합
<aop:advisor pointcut-ref="aPointcut" advice-ref="txAdvice" />
</aop:config>
// 결론 R을 제외한 CUD에 각각의 트랜잭션이 적용됨
ex) 하나의 insert에서 같은 PK값으로 insert를 2번 사용하면
- 2번째로 실행되는 insert메서드가 실패함
- 트랜잭션이 적용되어있기 때문에 하나의 insert도 실행되지 않음
Spring을 적용한 Controller
- FrontController가 DispatcherServlet으로 변경됨
- Action(Interface)가 Controller(Interface)로 변경됨
사용법
- 사용자(브라우저, Client)
- 요청
- 요청정보를 FC(DS)에서 받아서
- 요청정보를 꺼내요...
- 요청에 맞는 Action(Controller)을 수행해야하는데
- 이때 활용하는게 HM
- Action을 수행하면
- 어디로(경로)
- 어떻게(포워드 VS 리다이렉트) 가야하는지 전달
- + 요청한 정보와 함께(data, datas, memberInfo, list 등....)
- JSP에서는 ActionForward를 썻지만,
- Spring에서는 VR을 사용
- putput을 토대로 응답
'Spring' 카테고리의 다른 글
Spring 통합 질문 (0) | 2024.03.08 |
---|---|
Spring 이관 및 boot 실행 (0) | 2024.03.08 |
Spring MVC ver.2 로 변환하기 (1) | 2024.03.05 |
ASPECT 란? (1) | 2024.03.04 |
Spring 파일 생성 및 흐름 이해 (2) | 2024.02.28 |