👩💻 자바 개발자 양성과정 54일차
- JAVA에서 csv파일 읽어와서 DB에 추가하기
- Spring MVC
- pring 아키텍처 이해하기 - resources 폴더 사용하기
- Spring 아키텍처 이해하기 - 프로젝트 인덱스 수정 (접속 페이지)
- Spring 작동 원리 이해 - 주소 보고 이해하기
- Spring Legacy에서 component-scan 하는 위치
🌜 JAVA에서 csv파일 읽어와서 DB에 추가하기
dbinfo.properties
db.driverClass=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=1234
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="com.example.vo.StudentVO" alias="studentVo" />
</typeAliases>
</configuration>
mybatis-mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Student">
<!-- 이 결과값을 JdbcDriver에게 넘긴다. -->
<!-- parameterType: Java에서 넘어오는 값의 Type -->
<insert id="insert" parameterType="studentVo" statementType="PREPARED">
INSERT INTO student
VALUES(#{hakbun}, #{name}, #{kor} ,#{eng}, #{mat}, #{edp}, #{tot}, #{avg}, #{grade})
</insert>
<resultMap type="studentVo" id="studentResultMap">
<result property="hakbun" javaType="String" column="hakbun" jdbcType="CHAR"/>
<result property="name" javaType="String" column="name" jdbcType="VARCHAR"/>
<result property="kor" javaType="int" column="kor" jdbcType="TINYINT"/>
<result property="eng" javaType="int" column="eng" jdbcType="TINYINT"/>
<result property="mat" javaType="int" column="mat" jdbcType="TINYINT"/>
<result property="edp" javaType="int" column="edp" jdbcType="TINYINT"/>
<result property="tot" javaType="int" column="tot" jdbcType="SMALLINT"/>
<result property="avg" javaType="double" column="avg" jdbcType="DECIMAL"/>
<result property="grade" javaType="java.lang.Character" column="grade" jdbcType="CHAR"/>
</resultMap>
<select id="selectList" resultMap="studentResultMap" resultType="studentVo" statementType="PREPARED">
SELECT * FROM Student
ORDER BY tot DESC
</select>
</mapper>
bean.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.example" />
<context:property-placeholder location="classpath:dbinfo.properties" />
<!-- HikariCP 설정 Start-->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="${db.driverClass}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean id="dataSource"
class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg name="configuration" ref="hikariConfig" />
</bean>
<!-- HikariCP 설정 End -->
<!-- mybatis-spring 설정 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="mapperLocations">
<list>
<value>classpath:mybatis-mapper.xml</value>
</list>
</property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" />
</bean>
</beans>
StudentDaoImpl.java
package com.example.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.example.vo.StudentVO;
import lombok.extern.java.Log;
@Log
@Repository("studentDao")
public class StudentDaoImpl implements StudentDao {
@Autowired
private SqlSession sqlSession;
@Override
public void insertStudent(StudentVO student) {
this.sqlSession.insert("Student.insert", student);
log.info(student.getName() + "Insert Success.");
}
@Override
public StudentVO selectStudent(String hakbun) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<StudentVO> selectAllStudent() {
return this.sqlSession.selectList("Student.selectList");
}
@Override
public void updateStudent(StudentVO student) {
// TODO Auto-generated method stub
}
@Override
public void deleteStudent(String hakbun) {
// TODO Auto-generated method stub
}
}
StudentServiceImpl.java
package com.example.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.dao.StudentDao;
import com.example.vo.StudentVO;
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentDao studentDao;
@Override
public void create(StudentVO student) {
this.studentDao.insertStudent(student);
}
@Override
public StudentVO read(String hakbun) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<StudentVO> readAll() {
return this.studentDao.selectAllStudent();
}
@Override
public void update(StudentVO student) {
// TODO Auto-generated method stub
}
@Override
public void delete(String hakbun) {
// TODO Auto-generated method stub
}
}
Input.java
package com.example.test;
import java.util.List;
import com.example.vo.StudentVO;
public class Calc {
private List<StudentVO> list;
public Calc(List<StudentVO> list) {
this.list = list;
this.list.forEach(student -> this.calc(student));
}
private void calc(StudentVO student) {
int tot = student.getKor() + student.getEng() + student.getMat() + student.getEdp();
double avg = tot /4.;
char grade = (avg >= 90)? 'A':
(avg >= 80)?'B':
(avg >= 70)?'C':
(avg >= 60)?'D': 'F';
student.setTot(tot);
student.setAvg(avg);
student.setGrade(grade);
}
}
Calc.java
package com.example.test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
import com.example.vo.StudentVO;
import lombok.extern.java.Log;
@Log
public class Input {
private List<StudentVO> list;
private Scanner scan;
public Input(List<StudentVO> list) throws IOException {
this.list = list;
String path = "C:/Temp/sungjuk_utf8.csv";
this.scan = new Scanner((Readable) new BufferedReader(new FileReader(path)));
}
public void input() {
log.info("tttttt");
while(this.scan.hasNext()) {
String line = this.scan.nextLine();
String[] array = line.split(",");
StudentVO student = new StudentVO(array[0].trim(),
array[1].trim(), Integer.parseInt(array[2].trim()),
Integer.parseInt(array[3].trim()),
Integer.parseInt(array[4].trim()),
Integer.parseInt(array[5].trim()));
this.list.add(student);
log.info(student.toString());
}
}
}
StudentBeanJUnitSpringTest.java
package com.example.test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.example.service.StudentService;
import com.example.vo.StudentVO;
import lombok.extern.java.Log;
@Log
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Component
class StudentBeanJUnitSpringTest2 {
@Autowired
private StudentService studentService;
private List<StudentVO> list;
@Disabled
@BeforeEach
public void init() {
try {
list = new ArrayList<StudentVO>();
Input input = new Input(list);
input.input();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
@DisplayName("Student Insert")
void test() {
Calc calc = new Calc(this.list);
this.list.forEach(student -> this.studentService.create(student));
}
@Disabled
@Test
@DisplayName("SelectListStudent Test")
void test1() {
this.studentService.readAll().forEach(student -> System.out.println(student));;
}
}
🌜 Spring MVC
이걸 서버에서 돌리면
가장먼저 프로젝트 내 web.xml이 실행된다.
Spring MVC Demo 처리 순서
◼ Web Browser의 요청을 web.xml의 <url-pattern></url-pattern>를 통해 /의
요청을 받는다.
◼ servlet-name이 appServlet인 servlet-class는
org.springframework.web.servlet.DispatcherServlet이다.
◼ 이 DispatcherServlet는 Loading하면서 /WEB-INF/spring/appServlet/servletcontext.xml를 Parameter로 초기화한다.
◼ servlet-context.xml에서 <context:component-scan base-package="com.exampl
e.biz" />를 통해 Scan을 base-package에서 한다.
◼ com.example.biz에 @Controller를 찾는다.
◼ @Controller가 있는 HomeController.java에서 @RequestMapping(value = "/", m
ethod = RequestMethod.GET)가 설정되어 있는 method인 public String home(L
ocale locale, Model model)를 찾는다.
◼ 왜냐하면 지금 Browser가 요청한 Method는 GET이고, 요청 경로는 /이기 때문이
다.
🌜 Spring 아키텍처 이해하기 - resources 폴더 사용하기
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<p> The time on the server is ${serverTime}. </p>
<img src="resources/idol.png">
</body>
</html>
이미지를 다른 폴더에 넣고 호출해보자
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<p> The time on the server is ${serverTime}. </p>
<img src="images/idol.png">
</body>
</html>
/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.example.biz" />
</beans:beans>
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="논리경로" location="물리경로" />
이곳에 경로를 추가를 해야지만 다른 resources외에 폴더를 사용할 수 있다.
<resources mapping="/images/**" location="/images/" />
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/images/**" location="/images/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.example.biz" />
</beans:beans>
이렇게 수정하고 나니 images의 이미지도 잘 출력된다.
🌜 Spring 아키텍처 이해하기 - 프로젝트 인덱스 수정 (접속 페이지)
여기 부분을 수정하고 프로젝트 run하면 인덱스 페이지가 수정된다.
🌜 Spring 작동 원리 이해 - 주소 보고 이해하기
localhost:8080까지는 웹서버와 톰캣서버가 읽는다.
/biz는 웹xml가 읽는다.
/view는 Controller가 읽는다.
🌜 Spring Legacy에서 component-scan 하는 위치