국비/SpringBoot

2023.04.18 58일차 SpringBoot

춘핑이 2023. 4. 18. 17:59

58일차 SpringBoot

insert update ddlete하는 방법에 대해서 배웠다.
서버에서 java로 sql을 시킨다.

16 jdbc

새 고객데이터를 추가하는 컨트롤러를 만들어보자.
select구문은 executeQuery()메소드를 실행시켜 ResultSet을 반환받았다.
insert구문은 ResultSet이 필요가 없다.
executeUpdate메소드를 사용하고 업데이트한 행수를 리턴받는다.

@RequestMapping("link1")
public void method1() {
    // 새 고객 데이터 추가하기
    String sql = "INSERT INTO Customers(customerId, customerName, city) "
            + "VALUES (92,'서태웅','부산')";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        int count = pstmt.executeUpdate();

        try (con; pstmt;) {
            System.out.println(count);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

/sub15/link2요청시 10번째 직원 추가하는 코드 작성해보기

@RequestMapping("link2")
public void method2() {
    String sql = "INSERT INTO Employees (EmployeeId, lastName, firstName) "
            + "VALUES(10, '백호', '강')";
    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        int count = pstmt.executeUpdate();

        try (con; pstmt;) {
            System.out.println(count);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.1 insert

EmployeeId를 직접 넣어주고 잇엇는데 직접 넣어주지 않아도된다.
자동으로 증가하는 컬럼이기 때문이다. 자동으로 증가하는 컬럼이 왜 필요한지는 나중에 테이블 만들때 알아보자.
DESC 테이블이름; 을 작성하면 테이블의 정보를 볼 수 있다.
컬럼명 - 타입 - NULL - KEY - Default - 기타값이 있는데
기타값에 auto increment가 있으면 자동으로 값이 증가한다.

새 공급자 데이터추가 (supplierID, supplierName, City)
자동증가 컬럼은 직접 값을 넣지 않고 추가하기

INSERT INTO Suppliers (SupplierName, City) VALUES ('son', 'london');

16.2 JDBC

사용자에게 값을 입력받아 넣기 위해서 SQL문에서 들어가야하는 부분을 ?로 바꾸면된다.
PreparedStatement를 이용해서 값을 세팅해주면된다.

//http://localhost:8080/sub15/link3?customerName=송태섭&city=부산&country=한국

@RequestMapping("link3")
public void method3(
        @RequestParam("customerName") String customerName,
        @RequestParam("city") String city,
        @RequestParam("country") String country) {

    String sql = "INSERT INTO Customers(customerName, city, Country) "
            + "VALUES (?, ?, ?)";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, customerName);
        pstmt.setString(2, city);
        pstmt.setString(3, country);
        int count = pstmt.executeUpdate();

        try (con; pstmt;) {
            System.out.println(count);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.3 JDBC - 2 연습

/sub15/link4>firstName=박지성&lastName=두개의 심장
직원정보 추가하기

@RequestMapping("link4")
public void method3(String firstName, String lastName) {
    String sql = "INSERT INTO Employees(firstName, lastName) "
            + "VALUES (?, ?)";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, firstName);
        pstmt.setString(2, lastName);

        try (con; pstmt;) {
            int count = pstmt.executeUpdate();
            System.out.println(count);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.4 form으로 추가하기

폼을 이용해서 파라미터를 받고 jdbc를 실행시켜보자.

@RequestMapping("link5")
public void method5() {
    // form이 있는 view로 포워드
    // view : /WEB-INF/vies/sub15/link5.jsp
}

<h1>새 직원 입력</h1>
<form action="/sub15/link6" method="post" >
    firstName : <input type="text" name="firstName"/> <br />
    lastName : <input type="text" name="lastName"/> <br />
    <input type="submit" value="전송" />
</form>

@RequestMapping("link6")
public void method6(String firstName, String lastName) {
    String sql = "INSERT INTO Employees(firstName, lastName) "
            + "VALUES (?, ?)";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, firstName);
        pstmt.setString(2, lastName);

        try (con; pstmt;) {
            int count = pstmt.executeUpdate();
            System.out.println(count);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.5 form연습 - 2

경로 : /sub15/link7 form이 있는 jsp로 포워드
경로 : /sub15/link8 3개 메소드 파라미터 활용해서 supplier테이블에 레코드추가하기

// 경로 : /sub15/link7 form이 있는 jsp로 포워드
@RequestMapping("link7")
public void method7() {
}

<h1>공급자 추가</h1>
<form action="/sub15/link8">
    공급자 이름 : <input type="text" name="name"/> <br />
    도시 : <input type="text" name="city"/> <br />
    나라 : <input type="text" name="country"/> <br />
    <input type="submit" value="전송" />
</form>

// 경로 : /sub15/link8 처리메소드
@RequestMapping("link8")
public void method8(String name, String city, String country) {
    // 3개 메소드 파라미터 활용해서 supplier테이블에 레코드추가
    String sql = "INSERT INTO Suppliers(SupplierName, City, Country) "
            + "VALUES (?, ?, ?)";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, name);
        pstmt.setString(2, city);
        pstmt.setString(3, country);

        try (con; pstmt;) {
            int count = pstmt.executeUpdate();
            System.out.println(count + "행이 추가되었습니다.");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.6 javaBean활용

@ModelAttribute을 사용하면 request가 알아서 dto클래스에 매핑된다.

@RequestMapping("link10")
public void method10(@ModelAttribute("customer") Customer customer) {

    String sql = "INSERT INTO Customers(customerName, contactName, address) "
            + "VALUES (?, ?, ?)";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, customer.getName());
        pstmt.setString(2, customer.getContactName());
        pstmt.setString(3, customer.getAddress());
        try (con; pstmt;) {
            int count = pstmt.executeUpdate();
            System.out.println(count + "행이 추가되었습니다.");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.7 javaBean활용 - 2

경로 : /sub15/link11 view로 포워드
경로 : /sub15/link12 supplier 테이블에 데이터 추가하기
Supplier dto(javabean)만들기

@Data
public class Supplier {
    private String supplierName;
    private String contactName;
    private String address;
    private String city;
    private String postalCode;
    private String country;
    private String phone;
}

<h1>새 공급자 등록</h1>
<form action="/sub15/link12" method="post">
    <!-- (input[name]+br)*7+input:s -->
    이름: <input type="text" name="supplierName" />
    <br />
    계약명: <input type="text" name="contactName" />
    <br />
    주소: <input type="text" name="address" />
    <br />
    도시: <input type="text" name="city" />
    <br />
    우편번호: <input type="text" name="postalCode" />
    <br />
    국가: <input type="text" name="country" />
    <br />
    전화번호: <input type="text" name="phone" />
    <br />
    <input type="submit" value="등록" />
</form>

// 경로 : /sub15/link12
@RequestMapping("link12")
public void method12(Supplier supplier) {
    String sql = "INSERT INTO Suppliers (supplierName, contactName, address, city, postalCode, country, phone) "
            + "VALUES(?,?,?,?,?,?,?)";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, supplier.getSupplierName());
        pstmt.setString(2, supplier.getContactName());
        pstmt.setString(3, supplier.ge ㅠtAddress());
        pstmt.setString(4, supplier.getCity());
        pstmt.setString(5, supplier.getPostalCode());
        pstmt.setString(6, supplier.getCountry());
        pstmt.setString(7, supplier.getPhone());

        try (con; pstmt;) {
            int count = pstmt.executeUpdate();
            System.out.println(count + "행이 업데이트되었습니다.");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.8 자동으로 증가하는 값 읽어오기

데이터를 입력할때 자동으로 증가하는 값을 활용하기 위해 읽을 필요가 있다.
몇번째에 들어가는지 등을 확인하고 싶어서 사용하는 것이다.
서버에 여러사람이 접속하기 때문에 그냥 마지막값을 읽어오면 꼬일 수가 있다.
입력할때 늘어나는 값을 바로 알아내고 싶다.

값을 안넣었지만 알고 싶다.
오버로딩된 prepareStatement(sql, int autogeneratekey)메소드를 사용하면된다.
autogeneratekey는 statement에 상수로 RETURN_GENERATED_KEYS로 정의되어있다.
이걸 이용해서 generate된 컬럼 값을 얻을 수 있다.

DB마다 작성하는 코드가 달라지기 때문에 사용할때 느낌만 보자.

getGeneratedKeys()메소드로 가져올 수 있다. ResultSet 타입을 리턴한다.
따라서 next를 호출해서 커서를 옮기고 값을 받아와야한다.

@RequestMapping("link12")
public void method12(Supplier supplier) {
    String sql = "INSERT INTO Suppliers (supplierName, contactName, address, city, postalCode, country, phone) "
            + "VALUES(?,?,?,?,?,?,?)";
    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        pstmt.setString(1, supplier.getSupplierName());
        pstmt.setString(2, supplier.getContactName());
        pstmt.setString(3, supplier.getAddress());
        pstmt.setString(4, supplier.getCity());
        pstmt.setString(5, supplier.getPostalCode());
        pstmt.setString(6, supplier.getCountry());
        pstmt.setString(7, supplier.getPhone());
        int count = pstmt.executeUpdate();

        // 자동생성된 컬럼(키)값 얻기
        ResultSet key = pstmt.getGeneratedKeys();

        int keyValue = 0;
        try (con; pstmt; key;) {
            if (key.next()) {
                keyValue = key.getInt(1);
            }
            System.out.println(count + "행이 업데이트되었습니다.");
            System.out.println(keyValue);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.9 DELETE

DELETE쿼리를 JDBC로 실행해보자
자동 증가하는 컬럼은 중복되지 않는 값을 가지고 있으니 이 값을 가지고 처리하자.

@RequestMapping("link1")
public void method1(int id) {
    String sql = "DELETE FROM Suppliers WHERE SupplierID = ?";
    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        pstmt.setInt(1, id);
        try (con; pstmt;){
            int count = pstmt.executeUpdate();
            System.out.println(count + "개의 행 삭제");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.10 DELETE - 2

/sub16/link2?id= 요청시 CustomerId기준으로 고객테이블의 데이터 삭제

@RequestMapping("link2")
public void method2(int id) {
    String sql = "DELETE FROM Customers WHERE CustomerID = ?";
    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        pstmt.setInt(1, id);
        try (con; pstmt;){
            int count = pstmt.executeUpdate();
            System.out.println(count + "개의 행 삭제");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.11 UPDATE

UPDATE쿼리를 JDBC로 실행해보자
자동 증가하는 컬럼은 중복되지 않는 값을 가지고 있으니 이 값을 가지고 처리하자.

// /sub17/link1?id=35&name=서태웅
@RequestMapping("link1")
public void method1(int id, String name) {
    String sql = "UPDATE Suppliers SET SupplierName = ? WHERE SupplierId = ?";
    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        pstmt.setString(1, name);
        pstmt.setInt(2, id);
        try (con; pstmt;){
            int count = pstmt.executeUpdate();
            System.out.println(count + "개의 행 업데이트");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.12 UPDATE -2

/sub17/link2?id=35&address=seoul로 요청시 업데이트하는 메소드 메소드

@RequestMapping("link2")
public void method2(int id, String address) {
    String sql = "UPDATE Suppliers SET address = ? WHERE SupplierId = ?";
    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, address);
        pstmt.setInt(2, id);
        try (con; pstmt;){
            int count = pstmt.executeUpdate();
            System.out.println(count + "개의 행 업데이트");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

여기서 의문점은 update를 특정 컬럼마다 만들어줘야하느냐? 아니다.
일단 sql에는 테이블의 컬럼을 다 작성한다.
원래 가지고 있는 값을 조회하고 넣어준다. 조회수 수정하는 방향으로 작성한다.
마이바티스 쓰면 이런거 안쓴다.

@RequestMapping("link4")
public void method4(int id, Model model) {

    String sql = "SELECT * FROM Suppliers WHERE SupplierId = ?";

    Supplier supplier = null;

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, id);
        ResultSet rs = pstmt.executeQuery();
        try (con; pstmt; rs;) {
            if (rs.next()) {
                supplier = new Supplier();
                supplier.setSupplierId(rs.getInt("supplierId"));
                supplier.setSupplierName(rs.getString("supplierName"));
                supplier.setContactName(rs.getString("contactName"));
                supplier.setAddress(rs.getString("address"));
                supplier.setCity(rs.getString("city"));
                supplier.setPostalCode(rs.getString("postalCode"));
                supplier.setCountry(rs.getString("country"));
                supplier.setPhone(rs.getString("phone"));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    model.addAttribute("supplier", supplier);
    System.out.println(supplier.getSupplierName());
    System.out.println(supplier.getContactName());
}

<h1>${supplier.supplierId }번 공급자 수정</h1>
<form action="/sub17/link3" method="post">
    <!-- (input[name][value]+br)*7+input:s -->
    <input type="text" name="supplierName" value="${supplier.supplierName}" />
    <br />
    <input type="text" name="contactName" value="${supplier.contactName }" />
    <br />
    <input type="text" name="address" value="${supplier.address }" />
    <br />
    <input type="text" name="city" value="${supplier.city }" />
    <br />
    <input type="text" name="postalCode" value="${supplier.postalCode }" />
    <br />
    <input type="text" name="country" value="${supplier.country }" />
    <br />
    <input type="text" name="phone" value="${supplier.phone }" />
    <br />
    <input type="hidden" name="id" value="${supplier.supplierId }" />
    <input type="submit" value="수정" />
</form>

@RequestMapping("link3")
public void method3(int id, Supplier supplier) {
    String sql = "UPDATE Suppliers SET "
            + "SupplierName = ?, "
            + "ContactName = ?, "
            + "Address = ?, "
            + "City = ?,"
            + "PostalCode = ?,"
            + "Country = ?, "
            + "Phone = ? "
            + "WHERE SupplierId = ?";
    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, supplier.getSupplierName());
        pstmt.setString(2, supplier.getContactName());
        pstmt.setString(3, supplier.getAddress());
        pstmt.setString(4, supplier.getCity());
        pstmt.setString(5, supplier.getPostalCode());
        pstmt.setString(6, supplier.getCountry());
        pstmt.setString(7, supplier.getPhone());
        pstmt.setInt(8, id);

        try (con; pstmt;) {
            int count = pstmt.executeUpdate();
            System.out.println(count + "개의 행 업데이트");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

16.12 UPDATE -3

Customers 테이블 수정하는 코드를 작성해보자.
1.Customer dto 작성하기
2.메소드 5, 6 작성해서 조회하고 수정하기

@Data
public class Customer {
    private int customerId;
    private String customerName;
    private String contactName;
    private String address;
    private String city;
    private String postalCode;
    private String Country;
}

// 고객조회
@RequestMapping("link5")
public void method5(int id, Model model) {
    String sql = "SELECT * FROM Customers WHERE customerId = ?";
    Customer customer = null;

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setInt(1, id);
        ResultSet rs = pstmt.executeQuery();

        try (rs; pstmt; con;) {
            if (rs.next()) {
                customer = new Customer();
                customer.setCustomerId(rs.getInt("customerId"));
                customer.setCustomerName(rs.getString("customerName"));
                customer.setContactName(rs.getString("contactName"));
                customer.setAddress(rs.getString("address"));
                customer.setCity(rs.getString("city"));
                customer.setPostalCode(rs.getString("postalCode"));
                customer.setCountry(rs.getString("country"));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    model.addAttribute("customer", customer);
}

<h1>${customer.customerId }번 고객 수정</h1>
<form action="/sub17/link6" method="post">
    <!-- (input[name][value]+br)*7+input:s -->
    <input type="text" name="customerName" value="${customer.customerName}" />
    <br />
    <input type="text" name="contactName" value="${customer.contactName }" />
    <br />
    <input type="text" name="address" value="${customer.address }" />
    <br />
    <input type="text" name="city" value="${customer.city }" />
    <br />
    <input type="text" name="postalCode" value="${customer.postalCode }" />
    <br />
    <input type="text" name="country" value="${customer.country }" />
    <br />
    <input type="hidden" name="customerId" value="${customer.customerId}" />
    <input type="submit" value="수정" />
</form>

// 고객수정
@RequestMapping("link6")
public void method6(Customer customer) {
    String sql = "UPDATE Customers SET "
            + "customerName = ?, "
            + "contactName = ?, "
            + "address = ?,"
            + "city = ?,"
            + "postalCode = ?, "
            + "Country = ? "
            + "WHERE customerId = ?";

    try {
        Connection con = DriverManager.getConnection(url, dbId, pwd);
        PreparedStatement pstmt = con.prepareStatement(sql);
        pstmt.setString(1, customer.getCustomerName());
        pstmt.setString(2, customer.getContactName());
        pstmt.setString(3, customer.getAddress());
        pstmt.setString(4, customer.getCity());
        pstmt.setString(5, customer.getPostalCode());
        pstmt.setString(6, customer.getCountry());
        pstmt.setInt(7, customer.getCustomerId());
        try (pstmt; con;){
            int count = pstmt.executeUpdate();
            System.out.println(count + "개의 행 업데이트");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

2023.04.19

스프링에서 JDBC를 통해 서버와 DB를 다루는 방법에 대해서 배웠다.
나중가서 마이바티스 등을 사용하면서 코드는 줄어들 것이지만 그 이면안에서 작동하는 방법을 아는 것이 이해하는데 도움이 될 것이라고 생각된다.