성장일기 : 문과생의 개발 여정 (งᐖ)ว ( ᐛ )و

DB와 연동되는 경품 추첨 이벤트 구현 QUIZ 본문

백엔드개발/JDBC

DB와 연동되는 경품 추첨 이벤트 구현 QUIZ

hyemi_flora 2023. 11. 13. 11:57

# DB와 연동되는 경품추첨 이벤트 구현

1. DB에 경품들의 이름, 당첨확률, 남은수량 등 필요한 정보를 저장할 수 있는 테이블 생성하기

2. 콘솔에서 뽑기를 진행하면 실제로 DB에서 수량이 줄어들게 만들기

3. 상품이 모두 소진된 상태로벤트가 종료되었음을 알려주고 프로그램이 종료되도록

4. 리셋 기능을 실행하면 DB의 상품이 처음으로 돌아가야한다(충전되어야 한다)

 

 

 

sql Developer>>>

 

-- 테이블생성

-- 테이블은 경품의 이름, 당첨 확률, 남은 수량 등의 정보를 저장

CREATE TABLE prizes (

    prize_id VARCHAR2(10)

        CONSTRAINT prize_id_pk PRIMARY KEY,

    prize_name VARCHAR2(255)

        CONSTRAINT prize_nm_nn NOT NULL

        CONSTRAINT prize_nm_uk UNIQUE,

    prize_amount NUMBER(15)

        CONSTRAINT prize_am_nn NOT NULL

        CONSTRAINT prize_am_chk CHECK(prize_amount >= 0),

    winning_probability NUMBER(5, 2)

        CONSTRAINT prob_chk CHECK(winning_probability >= 0 AND winning_probability <= 1)

        CONSTRAINT prob_nn NOT NULL

);

DROP TABLE prizes;

DESC prizes;

SELECT * FROM prizes;

SELECT * FROM user_constraints WHERE table_name = 'PRIZES';

 

--  "lg gram 15" 15 , "뮤지컬 R석 티켓 2" 50, "공기청정기" 5, "스타벅스 아메리카노 상품권"300

 

INSERT INTO prizes (prize_id, prize_name, prize_amount, winning_probability) VALUES('01', 'lg gram 15', 15, 0.25);

INSERT INTO prizes (prize_id, prize_name, prize_amount, winning_probability) VALUES('02', '뮤지컬 R석 티켓', 30, 0.3);

INSERT INTO prizes (prize_id, prize_name, prize_amount, winning_probability) VALUES('03', '공기청정기', 5, 0.05);

INSERT INTO prizes (prize_id, prize_name, prize_amount, winning_probability) VALUES('04', '스타벅스 아메리카노 상품권', 300, 0.4);

 

 

--------------------------------------

 

CREATE TABLE winners(

    winner_id VARCHAR2(10)

        CONSTRAINT winner_id_pk PRIMARY KEY,

    prize_id VARCHAR2(10)

        CONSTRAINT prize_fk REFERENCES prizes(prize_id),

    winner_name VARCHAR2(255)

);

=============> 이클립스

package myobj.prize;

 

import myobj.prizeDraw.Prize_T;

 

public class DrawMachine {

 

        private Prize_T[] prizes;

        private Prize_T[] pickbox = new Prize_T[100];

        

        // 상품 목록 받고 배치 하는 생성자

        public DrawMachine(Prize_T[] prizes) {

                this.prizes = prizes;

                initPickBox();

        }

        

        private void initPickBox() {

                int index = 0;

                for(int i =0 ; i < prizes.length; ++i) {

                        double persent = prizes[i].getchance() * 100;

                        for(int j = 0; j< persent; ++j) {

                                pickbox[index++] = prizes[i];

                        }

                }

        }

        

        public Prize_T draw() {

                Prize_T present = pickbox[(int)(Math.random() * 100)];

                

                if(present == null) {

                        return new Prize_T("", 0, 0);

                } else {

                        if(present.getQty() == 0) {

                                return new Prize_T("상품소진", 0, 0);

                        }

                        present.minusQty();

                        return present;

                }

        }

 

}

 

 

 

package myobj.prizeDraw;

 

public class Prize_T {

        

        String name;

        int qty;

        double chance;

        

        public Prize_T(String name, int qty, double chance) {

                this.name = name;

                this.chance = chance;

                this.qty = qty;

        }

        

        //Getter, get필드명() : 해당 필드값을 꺼내주는 메서드

        public String getName() {

                return name;

        }

        public double getchance() {

                return chance;

        }

        

        public int getQty() {

                return qty;

        }

        public void minusQty() {

                --qty;

        }

}

 

 

package database.quiz;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

import java.util.Scanner;

 

import database.JdbcConnection;

import myobj.prizeDraw.Draw;

import myobj.prizeDraw.Prize_T;

 

public class J06_PrizeEvent {        

        // DB 테이블 생성: 데이터베이스에 경품 정보를 저장할 테이블을 생성

        // 사용자 입력을 받아 뽑기 이벤트, 리셋 기능 중 선택

        public void startEvent(Connection connection) {

                try (Scanner sc = new Scanner(System.in);) {

                        while (true) {

                                System.out.println("1. 뽑기 이벤트 시작");

                                System.out.println("2. 이벤트 리셋기능");

                                System.out.println("3. 이벤트 종료");

 

                                System.out.println("원하는 기능을 선택하세요>> ");

                                int choice = sc.nextInt();

 

                                switch (choice) {

                                case 1:

                                        drawPrize(connection);

                                        break;

                                case 2:

                                        resetEvent(connection);

                                        break;

                                case 3:

                                        endEvent(connection);

                                        return;

                                default:

                                        System.out.println("유효하지 않은 선택입니다. 다시 시도하세요");

                                }

                        }

                }

 

}

        

        // 뽑기 이벤트 메서드

        private void drawPrize(Connection connection) {

                // DB에서 남은 상품 수량 확인

                String sql = "SELECT prize_name, prize_amount, winning_probability FROM prizes";

                List<Prize_T> prizes = new ArrayList<>();

                try (Connection conn = JdbcConnection.getConnection();

                                PreparedStatement pstmt = conn.prepareStatement(sql);

                                ResultSet rs = pstmt.executeQuery()) {

                        // 수량이 0보다 크고, 당첨확률도 0이상일때 뽑기

 

                        while (rs.next()) {

                                String name = rs.getString("prize_name");

                                int qty = rs.getInt("prize_amount");

                                double chance = rs.getDouble("winning_probability");

                                Prize_T prize = new Prize_T(name, qty, chance);

                                prizes.add(prize);

                        }

                        // 뽑기

                        if (!prizes.isEmpty()) {

                                Draw drawMachine = new Draw(prizes.toArray(new Prize_T[0]));

                                Prize_T selected = drawMachine.draw();

 

                                System.out.println("!" + selected.getName() + "뽑으셨습니다");

 

                                String updateSql = "UPDATE prizes SET prize_amount = prize_amount - 1 " + "WHERE prize_name = ?";

                                // 뽑기를 진행한 경우 DB의 상품 수량 감소

                                try (PreparedStatement updatePstmt = conn.prepareStatement(updateSql)) {

                                        updatePstmt.setString(1, selected.getName());

                                        updatePstmt.executeUpdate();

                                } catch (SQLException e) {

                                        e.printStackTrace();

                                }

                        } else {

                                System.out.println("더 이상 남은 상품이 없습니다.");

                        }

 

                } catch (SQLException e) {

                        e.printStackTrace();

                }

 

        }

 

    private void endEvent(Connection connection) {

        // 프로그램 종료

        System.out.println("이벤트가 종료되었습니다.");

        System.exit(0);

    }

   

 

 

        // 리셋 기능 구현 메서드

        public void resetEvent(Connection connection) {

                // DB의 상품 정보를 초기 값으로 리셋

                // DB파일에서 롤백을 수행하는 것은 특정시점으로 되돌릴 수 있지만 해당 상황에는 맞지 않는다.

                // 이벤트에서 사용된 상품 수량을 초기화하고 이벤트를 리셋하려면 초기 데이터로 테이블을 다시 채우는 것이 일반적이라고 한다.

                String resetSql = "INSERT INTO prizes  (prize_id, prize_name, prize_amount, winning_probability)"

                                + "VALUES(?, ?, ?)";

                try (Connection conn = JdbcConnection.getConnection();

                                PreparedStatement pstmt = conn.prepareStatement(resetSql)) {

                        // 초기 데이터 배열을 선언할 때 Object 타입을 사용하면 서로 다른 타입의 데이터를 하나의 배열에 담을 수 있다.

                        Object[][] initialData = { { 01, "lg gram 15", 15, 0.25 }, { 02, "뮤지컬 R석 티켓'", 30, 0.3 },

                                        { 03, "공기청정기", 5, 0.05 }, { 04, "스타벅스 아메리카노 상품권", 300, 0.4 } };

                for (Object[] data : initialData) {

                    pstmt.setInt(1, (int) data[0]);

                    pstmt.setString(2, (String) data[1]);

                    pstmt.setInt(3, (int) data[2]);

                    pstmt.setDouble(4, (double) data[3]);

                    pstmt.executeUpdate();

                }

 

                System.out.println("상품 수량이 초기화되었습니다.");

                } catch (SQLException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                }

        }

  

        

        public static void main(String[] args) {

                // DB 연결 & 오토클로즈 작성

                // DB 연결 해제 코드 작성

 

                try (Connection conn = JdbcConnection.getConnection()) {

                        J06_PrizeEvent prizeEvent = new J06_PrizeEvent();

                        prizeEvent.startEvent(conn);

                } catch (SQLException e) {

                        e.printStackTrace();

                }

        }

 

}

 

 

++)

Connection connection은 메서드의 매개변수로 전달되는 Connection 인터페이스의 객체입니다. 이렇게 선언된 매개변수는 메서드 내에서 주어진 데이터베이스에 대한 연결을 나타냅니다.

Connection은 Java에서 데이터베이스와의 연결을 나타내는 인터페이스입니다. JDBC(Java Database Connectivity)를 사용하여 Java 프로그램에서 데이터베이스에 연결하려면 Connection 인터페이스를 사용합니다. Connection 인터페이스는 데이터베이스 서버와의 연결을 설정하고 명령을 실행하는 데 사용됩니다.

메서드의 시그니처에서 Connection connection을 보면, 이 메서드는 데이터베이스 연결을 필요로 하는 것을 나타냅니다. 이 메서드 내에서는 전달된 connection 객체를 사용하여 데이터베이스에서 정보를 읽고 쓰거나 쿼리를 실행할 수 있습니다. 예를 들어, drawPrize 메서드 내에서는 전달된 connection 객체를 사용하여 데이터베이스에서 남은 상품의 수량을 확인하고 상품을 뽑는 로직을 구현할 수 있습니다.

 

출처: <https://chat.openai.com/c/18a352c4-2221-4999-9d48-30a61e7900f4>

 

'백엔드개발 > JDBC' 카테고리의 다른 글

quiz  (1) 2023.11.13
Data Model Class  (0) 2023.11.13
Meta data  (1) 2023.11.13
Transaction  (0) 2023.11.13
Execute Update  (0) 2023.11.13