목차
Java 프로젝트 만들기
버전 업데이트
/pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gimhae</groupId>
<artifactId>day45_1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring-version>3.1.4.RELEASE</spring-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<finalName>day44</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Models
EmpVo
package com.gimhae.model;
public class EmpVo {
private int empno,pay;
private String ename;
private LocalDate hiredate;
public EmpVo() {
}
static class Builder{
private int empno,pay;
private String ename;
private LocalDate hiredate;
public Builder empno(int empno) {
this.empno=empno;
return this;
}
public Builder pay(int pay) {
this.pay=pay;
return this;
}
public Builder ename(String ename) {
this.ename=ename;
return this;
}
public Builder hiredate(java.sql.Date temporal) {
this.hiredate=LocalDate.from(temporal.toLocalDate());
return this;
}
public EmpVo build() {
return new EmpVo(this);
}
}
public EmpVo(Builder builder) {
this.empno=builder.empno;
this.ename=builder.ename;
this.pay=builder.pay;
this.hiredate=builder.hiredate;
}
public static Builder Builder() {
return new Builder();
}
public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public int getPay() {
return pay;
}
public void setPay(int pay) {
this.pay = pay;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public LocalDate getHiredate() {
return hiredate;
}
public void setHiredate(LocalDate hiredate) {
this.hiredate = hiredate;
}
@Override
public String toString() {
return "EmpVo [empno=" + empno + ", pay=" + pay + ", ename=" + ename + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + empno;
result = prime * result + ((ename == null) ? 0 : ename.hashCode());
result = prime * result + pay;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EmpVo other = (EmpVo) obj;
if (empno != other.empno)
return false;
if (ename == null) {
if (other.ename != null)
return false;
} else if (!ename.equals(other.ename))
return false;
if (pay != other.pay)
return false;
return true;
}
}
EmpDao (Interface)
package com.gimhae.model;
public interface EmpDao {
List<EmpVo> pullList();
EmpVo getList(int idx);
int addList(EmpVo bean);
int setList(EmpVo bean);
int rmList(int idx);
int listSize();
}
EmpDaoImpl
package com.gimhae.model;
public class EmpDaoImpl implements EmpDao {
JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
RowMapper<EmpVo> rowMapper;
public EmpDaoImpl() {
rowMapper=new RowMapper<EmpVo>() {
@Override
public EmpVo mapRow(ResultSet rs, int rowNum) throws SQLException {
return EmpVo.Builder()
.empno(rs.getInt("empno"))
.ename(rs.getString("ename"))
.pay(rs.getInt("pay"))
.hiredate(rs.getDate("hiredate"))
.build();
}
};
}
@Override
public List<EmpVo> pullList() {
String sql="select * from emp38 order by empno";
return jdbcTemplate.query(sql, rowMapper);
}
@Override
public EmpVo getList(int idx) {
String sql="select * from emp38 where empno=?";
return jdbcTemplate.queryForObject(sql, rowMapper,idx);
}
@Override
public int addList(EmpVo bean) {
String sql="insert into emp38 (ename,pay,hiredate) values (?,?,now())";
return jdbcTemplate.update(sql,bean.getEname(),bean.getPay());
}
@Override
public int setList(EmpVo bean) {
String sql="update emp38 set ename=?,pay=? where empno=?";
return jdbcTemplate.update(sql,bean.getEname(),bean.getPay(),bean.getEmpno());
}
@Override
public int rmList(int idx) {
String sql="delete from emp38 where empno=?";
return jdbcTemplate.update(sql,idx);
}
@Override
public int listSize() {
String sql="select count(*) as cnt from emp38";
return jdbcTemplate.queryForInt(sql);
}
}
/main/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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.cj.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/xe"
p:username="scott" p:password="tiger"
/>
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="dataSource"
/>
<bean id="empDao"
class="com.gimhae.model.EmpDaoImpl"
p:jdbcTemplate-ref="jdbcTemplate"
/>
</beans>
log4j.properties
log4j.rootLogger=WARN, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# Print the date in ISO 8601 format
log4j.appender.A1.layout.ConversionPattern=%c - %m%n
# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.gimhae.model=debug
Test cases
EmpDaoTest.java
package com.gimhae.model;
public class EmpDaoTest {
static ApplicationContext ac;
EmpDao empDao;
EmpVo target;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
ac=new ClassPathXmlApplicationContext("/applicationContext.xml");
}
@Before
public void setUp() throws Exception {
empDao=ac.getBean(EmpDao.class);
target=EmpVo.Builder().empno(4).pay(4444).ename("tester004").build();
}
@Test
public void testPullList() {
List<EmpVo> list=empDao.pullList();
assertNotNull(list);
assertTrue(list.size()>0);
}
@Test
public void testGetlList() {
assertEquals(target, empDao.getList(target.getEmpno()));
}
@Test
public void testAddlList() {
target.setEname("new1");
target.setPay(1111);
assertSame(1,empDao.addList(target));
}
@Test
public void testListSize() {
assertNotSame(0,empDao.listSize());
}
@Test
public void testSetList() {
target.setEname("tester4");
assertSame(1,empDao.setList(target));
}
@Test
public void testRmList() {
assertSame(1,empDao.rmList(34));
}
}
Log messgage 출력하기
ArroundLog.java
package com.gimhae.aop;
public class AroundLog implements MethodInterceptor {
Logger log;
@Override
public Object invoke(MethodInvocation ivc) throws Throwable {
log=Logger.getLogger(ivc.getThis().getClass());
Object[] args=ivc.getArguments();
log.debug("params:"+Arrays.toString(args));
Object obj=ivc.proceed();
log.debug("return:"+obj);
return obj;
}
}
applicationContext.xml
...
<bean id="advice"
class="com.gimhae.aop.AroundLog"
/>
<bean id="pointcut"
class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedNames">
<list>
<value>pullList</value>
</list>
</property>
</bean>
<bean id="pointcutAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor"
p:pointcut-ref="pointcut"
p:advice-ref="advice"
/>
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
p:beanNames="empDao"
p:interceptorNames="pointcutAdvisor"
/>
...
Transaction
2개 이상의 query 문장이 실행될 떄, 동시에 실행되거나, 한 문장이 실패할떄 발생하는 문제를 없애기 위해 transaction이 사용된다.
EmpDaoImpl
public class EmpDaoImpl2 implements EmpDao {
JdbcTemplate jdbcTemplate;
PlatformTransactionManager transactionManager;
...
}
...
@Override
public List<EmpVo> pullList() {
String sql="select * from emp38 order by empno";
PreparedStatementCreator psc=null;
psc=new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement pstmt=con.prepareStatement(sql);
return pstmt;
}
};
return jdbcTemplate.query(psc, rowMapper);
}
@Override
public EmpVo getList(int idx) {
String sql="select * from emp38 where empno=?";
return jdbcTemplate.queryForObject(sql, rowMapper,idx);
}
@Override
public int addList(EmpVo bean) {
String sql="insert into emp38 (ename,pay,hiredate) values (?,?,now())";
String sql2="insert into emp38 (empno,ename,pay,hiredate) values (4,?,?,now())";
TransactionDefinition definition=new DefaultTransactionDefinition();
TransactionStatus status=transactionManager.getTransaction(definition);
try {
PreparedStatementCreator psc=null;
psc=new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
System.out.println(con.hashCode());
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, bean.getEname());
pstmt.setInt(2, bean.getPay());
return pstmt;
}
};
jdbcTemplate.update(psc);
psc=new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
System.out.println(con.hashCode());
PreparedStatement pstmt=con.prepareStatement(sql2);
pstmt.setString(1, bean.getEname());
pstmt.setInt(2, bean.getPay());
return pstmt;
}
};
int result=jdbcTemplate.update(psc);
transactionManager.commit(status);
return result;
}catch(Exception e) {
transactionManager.rollback(status);
return 0;
}
}
...
}
혹은
simpler version:
public class EmpDaoImpl implements EmpDao {
JdbcTemplate jdbcTemplate;
PlatformTransactionManager transactionManager;
TransactionDefinition definition;
...
}
...
@Override
public int addList(EmpVo bean) {
String sql="insert into emp38 (ename,pay,hiredate) values (?,?,now())";
int result=0;
TransactionStatus status=transactionManager.getTransaction(definition);
try {
result=jdbcTemplate.update(sql,bean.getEname(),bean.getPay());
transactionManager.commit(status);
}catch (Exception e) {
transactionManager.rollback(status);
}
return result;
}
...
applicationContext.xml
...
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"
/>
<bean id="empDao"
class="com.gimhae.model.EmpDaoImpl2"
p:jdbcTemplate-ref="jdbcTemplate"
p:transactionManager-ref="transactionManager"
/>
...
RollBack - 실패시 packaging이 진행되도록 Rollback
EmpDaoTest
...
@Before
public void setUp() throws Exception {
empDao=ac.getBean(EmpDao.class);
//EmpVo [empno=4, pay=4444, ename=tester4];
target=EmpVo.Builder()
.empno(4)
.pay(4444)
.ename("tester4")
.build();
PlatformTransactionManager manager=ac.getBean(PlatformTransactionManager.class);
manager.getTransaction(ac.getBean(TransactionDefinition.class)).setRollbackOnly();
}
...
Maven web 프로젝트 만들기
pom.xml 라이브러리 업데이트 -[web, webmvc, servlet, jsp]
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-version}</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>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
...
maven clean
-[Run As] > [Maven Build]
convert to maven project
- [configure] > [convert to Maven Project]
make web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
</web-app>
Spring 프로젝트 만들기
Servlet Mapping
web.xml
...
<servlet>
<servlet-name>day45</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlet/day45-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>day45</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
...
Controller
day45-servlet.xml
--
applicationContext.xml
...
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"
/>
ListController
package com.gimhae.controller;
public class ListController implements Controller {
EmpDao empDao;
@Autowired
public void setEmpDao(EmpDao empDao) {
this.empDao = empDao;
}
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("emp/list","list",empDao.pullList());
}
}
InsertController
--
DeleteController
--
Pages
/index.jsp
...
<script type="text/javascript">
location.href="index.do"
</script>
...
views/template/head.jspf
...
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath}"></c:set>
<link rel="stylesheet" type="text/css" href="${root }/css/bootstrap.min.css">
<script type="text/javascript" src="${root }/js/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="${root }/js/bootstrap.min.js"></script>
<style type="text/css">
body {
padding-top: 50px;
}
.starter-template {
padding: 40px 15px;
text-align: center;
}
</style>
views/template/menu.jspf
...
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.4.1/dist/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="${root }/">home</a></li>
<li><a href="${root }/intro.do">intro</a></li>
<li><a href="${root }/emp/list.do">emp</a></li>
<li><a href="${root }/login/login.do">login</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container">
<div class="starter-template">
<div class="row">
<div class="col-md-12">
views/template/footer.jspf
...
</div>
</div>
<div class="col-md-12">
<address>
<p>김해캠퍼스 (50834) 경남 김해시 인제로 197</p>
<p>Copyright ©2024 INJE University. All rights reserved.</p>
</address>
</div>
</div>
</div></html>
views/main.jsp
...
<%@include file="template/head.jspf" %>
...
<%@include file="template/menu.jspf" %>
<div class="jumbotron">
<h2>환영합니다.</h2>
</div>
<%@include file="template/footer.jspf" %>
...
views/intro.jsp
...
<%@include file="template/head.jspf" %>
...
<%@include file="template/menu.jspf" %>
<img src="https://www.inje.ac.kr/kor/assets/images/sub/gimhae-campus-1.jpg">
<%@include file="template/footer.jspf" %>
...
views/emp/list.jsp
...
<%@include file="../template/head.jspf" %>
...
<%@include file="../template/menu.jspf" %>
<h2 class="page-header">목록</h2>
<table class="table">
<thead>
<tr>
<td>사번</td>
<td>이름</td>
<td>금액</td>
<td>날짜</td>
</tr>
</thead>
<tbody>
<c:forEach items="${list }" var="bean">
<c:url value="detail.do" var="detail">
<c:param name="idx" value="${bean.empno }"/>
</c:url>
<tr>
<td><a href="${detail }">${bean.empno }</a></td>
<td><a href="${detail }">${bean.ename }</a></td>
<td><a href="${detail }">${bean.pay }</a></td>
<td><a href="${detail }">${bean.hiredate }</a></td>
</tr>
</c:forEach>
</tbody>
</table>
<%@include file="../template/footer.jspf" %>
...
views/emp/add.jsp
--
DB 정보 property로 따로 보관하기
applicationContext.xml
...
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"
p:location="classpath:/db.properties"
/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.mysql.cj.jdbc.Driver"
p:url="${db.mysql.url}"
p:username="${db.mysql.user}" p:password="${db.mysql.password}"
/>
...
db.properties
db.mysql.url=jdbc:mysql://localhost:3306/xe
db.mysql.user=scott
db.mysql.password=tiger
'100일 챌린지 > 빅데이터기반 인공지능 융합 서비스 개발자' 카테고리의 다른 글
Day 46 - iBatis/MyBatis (데이터베이스 연동을 위한 ORM 시스템) (1) | 2024.09.30 |
---|---|
Day 46 - Spring ver 3. 프로젝트 만들기 (1) | 2024.09.30 |
Day 44 - DI로 Web Project 만들기 (1) | 2024.09.26 |
Day 44 - DI, Logging, AOP (0) | 2024.09.26 |
Day 43 - Spring 사용하기 (0) | 2024.09.25 |