jujube bat 2020. 3. 14. 20:52

JDBC 실습

- 메이븐 프로젝트를 생성한다.

- pom.xml에 jdk버전 관련 설정을 하고, 의존성에 mysql 드라이버를 추가한다. 

- mysql에 localhost 사용자를 등록해준다. (아이디 : "connectuser", 비밀번호 : "connect123!@#")

- myqsl에 "connectdb"라는 이름의 DB를 생성한다.

- "connectdb"에 Role 테이블을 생성하고, 샘플 데이터를 몇 개 넣어준다. 

 

Role 스키마 구조

 

role table에 들어있는 샘플 데이터

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<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>kr.or.connect</groupId>
  <artifactId>jdbcexam</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>jdbcexam</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    //mysql 5.1.21 드라이버 등록
    <dependency>
		<groupId>mysql</groupId> 
		<artifactId>mysql-connector-java</artifactId>
		<version>5.1.21</version>
	</dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        //jdk8 사용을 위한 플러그인 설정
        <plugin> 
		  <groupId>org.apache.maven.plugins</groupId>
		  <artifactId>maven-compiler-plugin</artifactId>
		  <version>3.6.1</version>
		  <configuration>
			 <source>1.8</source>
			 <target>1.8</target>
		  </configuration>
			 </plugin>
        </plugins>
    </pluginManagement>
  </build>
</project>

 

Role.java

package kr.or.connect.jdbcexam.dto;

public class Role { //role 테이블을 Java 객체를 정의 
	private Integer roleId;  //컬럼1 (primary key)
	private String description; //컬럼2

	public Role() {

	}

	public Role(Integer roleId, String description) { //생성자
		super();
		this.roleId = roleId;
		this.description = description;
	}
	
    //아래의 get, set, toString 함수들은 이클립스의 edit-generate 기능으로 손쉽게 만들 수 있다.
	public Integer getRoleId() {
		return roleId;
	}

	public void setRoleId(Integer roleId) {
		this.roleId = roleId;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	//편하게 출력할 목적으로 toString 오버라이딩.
	@Override
	public String toString() {
		return "Role [roleId=" + roleId + ", description=" + description + "]";
	}
}

 

RoleDao.java

package kr.or.connect.jdbcexam.dao;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import kr.or.connect.jdbcexam.dto.Role;

public class RoleDao {
	
	private static String dburl = "jdbc:mysql://localhost:3306/connectdb"; //DB연결에 필요한 정보를 상수화해서 사용
	private static String dbUser = "root";
	private static String dbpassword = "0000";
	
	public Role getRole(Integer roleId) {
		Role role = null;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		
		try { //데이터베이스에 연결이 혹시 끊기는 등의 상황에 대해 예외를 처리해야한다.
			Class.forName("com.mysql.jdbc.Driver"); //데이터베이스 드라이버 로드
			conn = (Connection) DriverManager.getConnection(dburl, dbUser, dbpassword); //접속할 DB의 url, 유저, 비번
			String sql = "SELECT description, role_id FROM role WHERE role_id = ?";
			ps = (PreparedStatement) conn.prepareStatement(sql);
			ps.setInt(1, roleId); //sql의 첫번째 ?에 roleId를 넣어준다.
			rs = ps.executeQuery(); //실행한다.
			
			if(rs.next()) { //다음 데이터가 있다면,
				String description = rs.getString(1); //첫번째 속성(컬럼)의 값(select 기준, 위의 sql문에서 첫번째 컬럼이 description임 )
				int id = rs.getInt("role_id");  //role_id 를 얻어온다. 속성명으로 얻어올 수 있다.
				role = new Role(id,description); //위 두 줄에서 얻어온 데이터로 Role 객체를 만든다. 
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally { //finally 구절은 어떤일이 있어도 반드시 실행된다.
			if(rs != null) {//rs, ps, conn 순서로 close를 해준다. 만약 위에서 conn까지만 할당되고 ps, rs 는 할당이 되지 않았을 수 있다. 그래서 rs가 null인지 체크한다.(ps, conn에도 똑같이 적용)
				try {
					rs.close(); //close라는 메소드도 예외를 발생시킬 수 있기에 예외처리를 한다. 
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			
			if(ps != null) {
				try {
					ps.close(); //close라는 메소드도 예외를 발생시킬 수 있기에 예외처리를 한다. 
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			
			if(conn != null) {
				try {
					conn.close(); //close라는 메소드도 예외를 발생시킬 수 있기에 예외처리를 한다. 
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		return role;
	}
	
	public List<Role> getRoles(){
		List<Role> list = new ArrayList<>();
		
		try {
			Class.forName("com.mysql.jdbc.Driver"); //데이터베이스 드라이버 로드
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		String sql = "SELECT description, role_id FROM role order by role_id desc";
		try (Connection conn = (Connection) DriverManager.getConnection(dburl, dbUser, dbpassword); 
				PreparedStatement ps = (PreparedStatement) conn.prepareStatement(sql)){ //이렇게 작성하면, DB에서 할당받은 객체를 자동으로 close 한다. (보면 finally 문구가 없다.)
			
			try (ResultSet rs = ps.executeQuery()){ //여기서도 이렇게 쓰면 객체를 자동으로 close함
				
				while(rs.next()) { //튜플을 하나씩 꺼내온다. 더 이상 꺼낼 튜플이 없으면 false를 반환하여 종료됨.
					int id = rs.getInt("role_id"); //db 튜플에서 id를 꺼냄
					String description = rs.getString(1); // 튜플에서 description을 꺼냄
					Role role = new Role(id, description); // 꺼낸 데이터로 Role 객체를 만듬
					list.add(role); //리스트에 추가함
				}
			}catch(Exception ex) {
				ex.printStackTrace();
			}
			
		}catch(Exception ex) {
			ex.printStackTrace();
		}
		return list;
	}
	
	public int addRole(Role role){
		int insertCount = 0;
		
		Connection conn = null;
		PreparedStatement ps = null;
		
		try { //데이터베이스에 연결이 혹시 끊기는 등의 상황에 대해 예외를 처리해야한다.
			Class.forName("com.mysql.jdbc.Driver"); //데이터베이스 드라이버 로드
			
			conn = (Connection) DriverManager.getConnection(dburl, dbUser, dbpassword); //접속할 DB의 url, 유저, 비번
			
			String sql = "INSERT INTO role (role_id, description) VALUES (?,?)";
			
			ps = (PreparedStatement) conn.prepareStatement(sql);
			
			ps.setInt(1, role.getRoleId()); // 1번째 ?에 얻어온 Role 객체의 ID를 넣어줌
			ps.setString(2, role.getDescription()); //2번째 ?에 얻어온 Role 객체의 Description를 넣어줌
			
			insertCount = ps.executeUpdate(); //insert, update를 실행할때 이렇게함
		
		}catch(Exception e){
			e.printStackTrace();
		}finally { //finally 구절은 어떤일이 있어도 반드시 실행된다.
			if(ps != null) {
				try {
					ps.close(); 
				} catch (SQLException e) {}
			}
			
			if(conn != null) {
				try {
					conn.close(); 
				} catch (SQLException e) {}
			}
		}
		return insertCount;
	}
	
	
	public int deleteRole(Integer roleId){
		int deleteCount = 0;
		
		try {
			Class.forName("com.mysql.jdbc.Driver"); //데이터베이스 드라이버 로드
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		String sql = "DELETE FROM role WHERE role_id = ?";
		try (Connection conn = (Connection) DriverManager.getConnection(dburl, dbUser, dbpassword); 
				PreparedStatement ps = (PreparedStatement) conn.prepareStatement(sql)){ //이렇게 작성하면, 예외처리도 하고, DB에서 할당받은 객체를 자동으로 close 한다. (보면 finally 문구가 없다.)
		
				ps.setInt(1, roleId); //sql의 첫번째 ?에 roleId를 넣어준다.
				deleteCount = ps.executeUpdate(); //실행한다.
		
		}catch(Exception ex) {
			ex.printStackTrace();
		}
		return deleteCount;
	}
	
	public int updateRole(Role role){
		int updateCount = 0;
		
		try {
			Class.forName("com.mysql.jdbc.Driver"); //데이터베이스 드라이버 로드
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		String sql = "UPDATE role SET description = ? where role_id = ?";
		try (Connection conn = (Connection) DriverManager.getConnection(dburl, dbUser, dbpassword); 
				PreparedStatement ps = (PreparedStatement) conn.prepareStatement(sql)){ //이렇게 작성하면, 예외처리도 하고, DB에서 할당받은 객체를 자동으로 close 한다. (보면 finally 문구가 없다.)
				
				ps.setString(1,role.getDescription());
				ps.setInt(2, role.getRoleId()); //sql의 첫번째 ?에 roleId를 넣어준다.
				updateCount = ps.executeUpdate(); 
		
		}catch(Exception ex) {
			ex.printStackTrace();
		}
		return updateCount;
	}
}

 

jdbcExam1.java (Select)

package kr.or.connect.jdbcexam;
import kr.or.connect.jdbcexam.dao.RoleDao;
import kr.or.connect.jdbcexam.dto.Role;

public class JDBCExam1 {

	public static void main(String[] args) {
		RoleDao dao = new RoleDao(); //role 객체 생성
		Role role = dao.getRole(100); //dao를 통해 100번 role 객체를 DB에서 받아옴.(select)
		System.out.println(role); //받아온 객체를 출력
	}
    
}

 

jdbcExam2.java (Insert)

package kr.or.connect.jdbcexam;
import kr.or.connect.jdbcexam.dao.RoleDao;
import kr.or.connect.jdbcexam.dto.Role;

public class JDBCExam2 {
	public static void main(String[] args) {
		int roleId = 500;
		String description = "CTO";
		
		Role role = new Role(roleId, description);
		
		RoleDao dao = new RoleDao();
		int insertCount = dao.addRole(role);
		
		System.out.println(insertCount);
	}
}

jdbcExam3.java (Select *)

package kr.or.connect.jdbcexam;

import kr.or.connect.jdbcexam.dao.RoleDao;
import kr.or.connect.jdbcexam.dto.Role;
import java.util.List;

public class JDBCExam3 {
	public static void main(String[] args) {
		RoleDao dao = new RoleDao();
		
		List<Role> list = dao.getRoles();
		
		for(Role role : list) {
			System.out.println(role);
		}
	}
}

jdbcExam4.java (Delete)

package kr.or.connect.jdbcexam;

import kr.or.connect.jdbcexam.dao.RoleDao;

public class JDBCExam4 {
	public static void main(String[] args) {
		int roleId = 500;

		RoleDao dao = new RoleDao();
		int deleteCount = dao.deleteRole(roleId);

		System.out.println(deleteCount);
	}
}

jdbcExam5.java (Update)

package kr.or.connect.jdbcexam;

import kr.or.connect.jdbcexam.dao.RoleDao;
import kr.or.connect.jdbcexam.dto.Role;

public class JDBCExam5 {
	public static void main(String[] args) {

		int roleId = 1;
		String description = "CEO";
		
		Role role = new Role(roleId, description);
		
		RoleDao dao = new RoleDao();
		int updateCount = dao.updateRole(role);

		System.out.println(updateCount);
	} 
}