Spring & Springboot/올인원 스프링 프레임워크

전자 도서관 프로젝트 - 데이터베이스 연동

YJ_ma 2023. 10. 7. 21:06

하이디SQL 설정하기

관계형 데이터베이스(RDBMS)인 MariaDB를 사용하여 연동하는 작업을 수행해본다.

1. MariaDB를 다운받고 하이디SQL(HeidiSQL)을 실행한다.

1-1. <신규> 버튼을 클릭

1-2. 이름은 library로 설정

1-3. 접속 정보(127.0.0.1, root, 3306)을 확인한 후 암호 입력

1-4. 확인 마치면 <저장>버튼 클릭

1-5. <열기> 버튼 클릭

 

2. library 데이터베이스 창이 열리면 상단의 쿼리를 클릭한다.

프로젝트에서 사용하는 데이터베이스를 db_library 이름으로 생성해주고 사용한다.

CREATE DATABASE db_library;
USE db_library;

3. db_library에 관리자 회원 정보를 관리하는 테이블을 tbl_admin_member이름으로 생성해준다.

CREATE TABLE tbl_admin_member(
    a_m_no		INT 		AUTO_INCREMENT,
    a_m_approval	INT 		NOT NULL DEFAULT 0,
    a_m_id		VARCHAR(20)	NOT NULL,
    a_m_pw		VARCHAR(100)	NOT NULL,
    a_m_name		VARCHAR(20)	NOT NULL,
    a_m_gender		CHAR(1)		NOT NULL,
    a_m_part		VARCHAR(20)	NOT NULL,
    a_m_position	VARCHAR(20)	NOT NULL,
    a_m_mail		VARCHAR(50)	NOT NULL,
    a_m_phone		VARCHAR(20)	NOT NULL,
    a_m_reg_date	DATETIME,
    a_m_mod_date	DATETIME,
    PRIMARY KEY(a_m_no)
);

4. SELECT를 이용해서 tbl_admin_member 테이블을 정상적으로 생성되었는지 확인해본다.

SELECT * FROM tbl_admin_member;

 

JdbcTemplate 준비하기

· 자바에서는 데이터베이스와 통신하기 위해 JDBC와 데이터베이스 제조사에서 제공해주는 드라이버를 이용한다.

· JDBC를 이용하게 되면 'JDBC 드라이버 로드 → 데이버베이스 연결 → SQL 쿼리 작성 → PreparedStatement 생성 → 쿼리 실행' 단계를 거치게 된다.

· 하지만 이러한 과정은 중복 코드가 많아지는 문제가 발생할 수 있다.

 

· 따라서, 스프링에서는 JDBC보다 더 세련된 JdbcTemplate 클래스를 제공한다.

· JdbcTemplate을 이용하면 'JDBC 드라이버 로드, 데이터베이스 연결'같은 반복 작업을 하지 않고, 'SQL 쿼리 작성 및 실행'작업에 집중할 수 있다.

· JdbcTemplate을 사용하려면 메인 레퍼지토리에서 해당 모듈을 가져오고, 스프링 설정 파일을 이용해 JdbcTemplate 빈 객체를 스프링 컨테이너에 생성하는 작업을 수행한다.

1. pom.xml에 spring-jdbcmariadb-java-client 모듈을 가져오기 위한 코드를 추가하고 저장한다.

■ pom.xml 코드

<!-- JDBC -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

<!-- mariaDB -->
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client  -->
<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
    <version>3.1.2</version>
</dependency>

2. jdbc-context.xml 파일을 새로 만든다.

[spring] 폴더에서 마우스 오른쪽 클릭 > [New]-[Other] 클릭 > [Select a wizard] 창에서 xml을 입력하여 XML File선택

파일명에 jdbc-context.xml을 입력하고 <Finish>를 클릭한다.

3. 생성된 jdbc-context.xml 파일에 다음과 같이 코딩한다.

· MariaDB 드라이버를 로드하고 이를 이용해서 데이터베이스에 연결하는 설정으로 본인의 데이터베이스 접속 정보를 참고하여 url, username, password를 설정한다.

· 스프링 컨테이너에 JdbcTemplate 빈 객체를 생성하는 코드로 dataSource를 MariaDB connection 객체로 초기화한다.

■ jdbc-context.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:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
		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
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
		
	<!-- <context:property-placeholder location="/WEB-INF/spring/property/real.info.properties" /> -->
	
	<!-- MariaDB connection 객체 -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="org.mariadb.jdbc.Driver" />
		<property name="url" value="jdbc:mariadb://127.0.0.1:3306/db_library" />
		<property name="username" value="root" />
		<property name="password" value="system" />
	</bean>
	
	<!-- JdbcTemplate 객체 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<!-- TransactionManager 객체 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
</beans>

4. 프로젝트가 서버에서 실행될 때 jdbc-context.xml를 인식할 수 잇도록 web.xml 파일을 열어서 <context-param>에 jdbc-context.xml을 추가한다.

■ web.xml 코드

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/spring/root-context.xml
    /WEB-INF/spring/jdbc-context.xml
    </param-value>
</context-param>

이제 스프링 컨테이너에 JdbcTemplate 빈 객체가 생성되는 것을 확인할 수 있다.

AdminMemberDao는 이를 이용하여 데이터베이스와 통신할 수 있게 된다.

 

관리자 회원가입 처리하기(DAO)

AdminMemberDao에서 JdbcTemplate을 사용하기 위해서는 @Autowired를 이용해서 의존 객체 자동 주입을 한다.

■ AdminMemberDao.java 코드

package com.office.library.admin.member;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class AdminMemberDao {
	
	@Autowired
	JdbcTemplate jdbcTemplate;
}

다음으로 중복 아이디를 체크하는 isAdminMember()를 정의한다.

· isAdminMember() : 중복을 체크하기 위해 관리자가 입력한 아이디(a_m_id)를 매개변수로 받는다.

· 관리자가 입력한 아이디가 tbl_admin_member 테이블에 이미 존재하는지 확인하는 쿼리문

· jdbcTemplate의 queryForObject()을 이용해서 SQL문을 실행하고 결과를 result에 저장

   - sql : SQL문

   - Integer.class : 쿼리 실행 후 반환되는 데이터 타입

   - a_m_id : 관리자 입력 아이디

· queryForObject()가 1을 반환 → 이미 사용중인 아이디

· queryForObject()가 0을 반환 → 회원가입 가능한 아이디

package com.office.library.admin.member;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class AdminMemberDao {

	@Autowired
	JdbcTemplate jdbcTemplate;

	public boolean isAdminMember(String a_m_id) {
		System.out.println("[AdminMemberDao] isAdminMember()");

		String sql = "SELECT COUNT(*) FROM tbl_admin_member "
				+ "WHERE a_m_id = ?";

		int result = jdbcTemplate.queryForObject(sql, Integer.class, a_m_id);

		if (result > 0)
			return true;
		else
			return false;
	}
}

 

isAdminMember()을 이용해서 중복 아이디 확인 결과가 true이면 tbl_admin_member 테이블에 관리자 정보를 추가하기 위한 insertAdminAccount()을 구현해준다.

public int insertAdminAccount(AdminMemberVo adminMemberVo) {
    System.out.println("[AdminMemberDao] insertAdminAccount()");

    List<String> args = new ArrayList<String>();

    String sql = "INSERT INTO tbl_admin_member(";
    if (adminMemberVo.getA_m_id().equals("super admin")) {
        sql += "a_m_approval, ";
        args.add("1");
    }

    sql += "a_m_id, ";
    args.add(adminMemberVo.getA_m_id());

    sql += "a_m_pw, ";
    args.add(adminMemberVo.getA_m_pw());

    sql += "a_m_name, ";
    args.add(adminMemberVo.getA_m_name());

    sql += "a_m_gender, ";
    args.add(adminMemberVo.getA_m_gender());

    sql += "a_m_part, ";
    args.add(adminMemberVo.getA_m_part());

    sql += "a_m_position, ";
    args.add(adminMemberVo.getA_m_position());

    sql += "a_m_mail, ";
    args.add(adminMemberVo.getA_m_mail());

    sql += "a_m_phone, ";
    args.add(adminMemberVo.getA_m_phone());

    sql += "a_m_reg_date, a_m_mod_date) ";

    if (adminMemberVo.getA_m_id().equals("super admin"))
        sql += "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";
    else
        sql += "VALUES(?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";

    int result = -1;

    try {
        result = jdbcTemplate.update(sql, args.toArray());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;		
}

 

비밀번호 암호화

· insertAdminAccount()에는 보안상의 문제가 있다.

ex, 비밀번호는 다른 사람이 알아서는 안되는 중요한 정보로, 조직(도서관)의 내부 인력 누구도 다른 사람의 비밀번호를 확인할 수 없어야 한다.

· 이러한 중요한 정보는 데이터베이스에 암호화하여 추가하고 이를 다시 조회할 때 복호화해야 한다.

· 스프링에서는 데이터를 암호화하고 복호화하는 모듈로 spring-security-core가 있다.

1. pom.xml 파일을 열어 앞서 추가한 mariadb-java-client 아래에 spring-security-core 모듈을 가져오기 위한 코드를 추가해준다.

■ pom.xml 코드

<!-- Spring security -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

2. [spring] 폴더에 security-context.xml 파일을 새로 만들고 다음과 같이 코딩한다.

■ security-context.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">
		
	<bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
	
</beans>

3. 프로젝트가 서버에서 실행될 때 security-context.xml을 인식할 수 있도록 web.xml 파일의 <context-param>에 security-context.xml을 추가해준다.

■ web.xml 코드

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/spring/root-context.xml
    /WEB-INF/spring/jdbc-context.xml
    /WEB-INF/spring/security-context.xml
    </param-value>
</context-param>

비밀번호 암호화 준비가 끝났으면 AdminMemberDao.java에서 멤버 필드로 PasswordEncoder를 선언하고 의존 객체를 자동 주입한다.

■ AdminMemberDao 코드

@Component
public class AdminMemberDao {

	@Autowired
	JdbcTemplate jdbcTemplate;
	
	@Autowired
	PasswordEncoder passwordEncoder;
    
    ...
    
    public int insertAdminAccount(AdminMemberVo adminMemberVo) {
		System.out.println("[AdminMemberDao] insertAdminAccount()");
        
        sql += "a_m_pw, ";
		args.add(passwordEncoder.encode(adminMemberVo.getA_m_pw()));
        
        ...

 

관리자 회원가입 결과 화면 만들기

· 데이터베이스에 관리자 정보를 추가한 후 응답에 필요한 화면(뷰)를 만들어본다.

· 응답에 필요한 화면은 [views]-[member] 폴더의 create_account_ok.jsp와 create_account_ng.jsp이다.

관리자 회원가입하고 결과 확인하기

프로젝트를 실행하고 관리자 회원가입을 진행해본다.

1. 프로젝트 톰켓을 시행하고 http://localhost:8090/library/admin/으로 접속한 후 '회원가입' 메뉴를 클릭한다.

2. 회원가입 양식에 관리자 정보를 입력한다.

- 아이디 : super_admin (최고 관리자 등록)

3. CREATE ACCOUNT SUCCESS!!가 뜨는지 확인한다 (뜬다면 성공적으로 수행)

첫 화면 회원가입 입력
회원가입 성공 출력된 로그

4. 마지막으로 하이디 SQL에서 tbl_admin_member 테이블을 조회하여 데이터베이스에 최고 관리자(super_admin) 회원정보가 정상적으로 추가되어 있는지 확인해본다.

- 이때, 비밀번호는 암호화된 상태이어야 한다!

SELECT * FROM tbl_admin_member;

실행 결과