1. 파일 생성하고 DB create, insert 하기

1. HomeController.java

package com.KOPO.SpringAndSqlite;

import java.sql.SQLException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		DataReader dataReader = new DataReader("C:\\tomcat\\ScoreTable.sqlite", "students");
		dataReader.open();	// DB를 사용하기 위해서는 Open 후에 꼭 Close를 해줘야한다.
		try {
//			dataReader.createTable();
			dataReader.insertData();
//			model.addAttribute("query_result", dataReader.selectData());
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			
		} finally {
			dataReader.close();
		}
	
		return "home";
	}
	// "/"에 GET 방식으로 접속 > DataReader 인스턴스화 > DB 엔진 열고 > createTable()메소드를 시켜 쿼리를 보내고 > DB 엔진을 닫고 > 결과를 .jsp파일로 리턴
	
	@RequestMapping(value = "/hello", method = RequestMethod.GET)
	public String hello(Locale locale, Model model) {
		return "NewFile";
	}
	
}

 

2. DataReader.java

package com.KOPO.SpringAndSqlite;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.sqlite.SQLiteConfig;

public class DataReader {
	private Connection connection;
	private String dbFileName;
	private String dbTableName;
	static {
		try {
			Class.forName("org.sqlite.JDBC");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	// HomeController가 DataReader를 인스턴스화 할 때 생성자로써 DB파일의 이름(전체 디렉토리 포함), 테이블명을 받아온다.
	public DataReader(String databaseFileName, String dbTableName) {
		this.dbFileName = databaseFileName;
		this.dbTableName = dbTableName;
	}
	
	// DB를 Open하는 메소드. 홈 컨트롤러가 DB를 사용할 때 이 메소드를 호출한다.
	public boolean open() {
		try {
			SQLiteConfig config = new SQLiteConfig();
			this.connection = DriverManager.getConnection("jdbc:sqlite:/" + this.dbFileName, config.toProperties());
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	// DB를 Close하는 메소드. 홈 컨트롤러가 DB 사용을 끝내고 닫을 때 이 메소드를 호출한다. (사용 후에는 반드시 닫아줘야함!!)
	public boolean close() {
		if (this.connection == null) {
			return true;
		}
		try {
			this.connection.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	// 여기서부터는 HomeController가 일을 시키는 메소드들... 특정 기능을 하는 쿼리를 만들어 보내고 결과를 받아와 HomeController에게 결과를 return한다. 그러면 이 결과를 받아서 HomeController가 .jsp 파일을 이용해 Response를 return한다.
	public int createTable() throws Exception {
		if (this.connection == null) {
			throw new Exception("DB is not open");
		}
		String query = "CREATE TABLE " + this.dbTableName + "(idx INT PRIMARY KEY, name TEXT, score REAL);";
		java.sql.Statement statement = this.connection.createStatement();
		int result = statement.executeUpdate(query);
		statement.close();
		return result;
	}
	
	public int insertData() throws SQLException {
		String query = "INSERT INTO "  + this.dbTableName + " (name, score) VALUES('abc',11);";
		java.sql.Statement statement = this.connection.createStatement();
		int result = statement.executeUpdate(query);
		statement.close();
		return result;
	}
	
	public boolean selectData() throws SQLException {
		boolean result = false;
		String query = "SELECT * FROM " + this.dbTableName + " WHERE ?;";
		PreparedStatement preparedStatement = this.connection.prepareStatement(query);
		preparedStatement.setInt(1, 1);
		ResultSet resultSet = preparedStatement.executeQuery();
//		resultSet.next();
		if (resultSet.next()) {
			System.out.println(resultSet.getString("name"));
			result = true;
		}
		resultSet.close();
		preparedStatement.close();
		return result;
	}

}

 

3. home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
	<head>
		<title>Home</title>
	</head>
	<body>
		<P>  Query result is ${query_result}. </P>
	</body>
</html>

 

4. NewFile.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
NewFile
</body>
</html>

 

SQL Query를 날려주는 메소드를 실행한다. C:\tomcat 디렉토리는 반드시 미리 만들어둬야한다.

dataReader.createTable();

dataReader.insertData();

create를 먼저 하고, insert를 한다.

 

Spring MVC 구조에 대한 고찰

HomeController : 메인 컨트롤 타워다. Spring MVC 구조가 M, V, C를 분산시켜 만든 구조라지만 실행 구조를 보면 HomeController가 명령을 내리는 실제 메인 컨트롤 타워다.

DataReader : DB를 열고 닫고, 쿼리를 날리고 하는 모든 작업을 하는 기능을 구현한 클래스. HomeController의 명령에 의해 작동. Model에 해당하는 녀석 같다...?

View(.jsp) :  말 그대로 보여지는 부분이다. html 페이지에 대해 정의되어 있다. 

 

0. HomeController가 annotation @Controller에 의해 컨트롤러로 작동을 한다.
1. @RequestMapping에 의해 (value = 페이지 정보, method = requst 방식(get, post, put, delete)) 각 페이지에서의 동작을 명령한다. (Request가 들어오는 동작)
   1) "/"에 GET 방식으로 접속하면
   2) DataReader를 인스턴스화 한다. (full directory, db table name을 함께 보낸다.)
   3) dataReader.open(); 을 통해 DB 접속 엔진을 열고
   4) try{ dataReader.createTable(); } 등을 이용해 메소드를 실행하면 DataReader에 있는 createTable()이라는 메소드가 쿼리를 보내 결과를 자신을 호출한 HomeController 위치에 return한다.
   5) } finally { dataReader.close(); } 을 통해 DB 접속 엔진을 닫는다
   6) 결과를 return하는데 return값은 .jsp 파일이 된다. 즉, HomeController가 받은 Request를 DataReader를 시켜 일을 하고, 어떤 View를 통해 Response를 보낼건가?(Response를 보내는 동작)이다. 

 

웹 페이지를 새로고침 해야 작동하는 이유?

위에 고찰에서 작동 방식을 보면 알 수 있듯이 @RequestMapping에 의해 작동하려면 해당 메소드가 실행될 수 있도록 Request를 날려줘야한다.

 

 

2. DB Broswer for SQLite로 확인하기

 

 

3. Eclipse로 확인하기

model.addAttribute("query_result", dataReader.selectData());

HomeController.java에서 파일을 저장하면 서버가 실행되고, Home에서 새로고침을 한다.

 

 

 

cf. HomeController의 locale

사용자의 언어, 국가뿐 아니라 사용자 인터페이스에서 사용자가 선호하는 사항을 지정한 매개 변수의 모임이다.

쉽게 말해서

한국 : 2020년 6월 5일, 섭씨, kg, m, ...
미국 : June 5, 2020, 화씨, lbs, peet, ...

 

cf. HomeController의 model

데이터 -> model -> View

HomeController가 DataReader를 시켜 DB에서 데이터를 받아와 리턴한다. 그러면 HomController의 mode이 그 데이터를 받아 View에 넘겨주는 역할을 한다.

model.addAttribute("query_result", dataReader.selectData());

이 model이 호출될 때 보면 'public String home(Locale locale, Model model) {   }' 이런식으로 호출된다.

즉, Model이라는 클래스를 model이라는 변수명으로 호출하고, 이 클래스가 가지고 있는 addAttribute라는 메소드를 이용하는 것이다.

이 addAttribute 메소드는 "query_result"라는 변수에 dataReader가 selectData 메소드를 실행해 return한 값을 받아오는데, 그 값이 들어간다. 즉, String abc = "안녕하세요" 처럼 query_result = 'selectData의 return값'을 변수로 받게 되고, 그 값을 View에 던져주는 기능이다.

+ Recent posts