9:28 학원 도착
docker build -t hello-java .
. 은 해당 폴더의 파일들을 이용해서 이미지를 빌드하겠다는 의미
그 이미지는 Hello.java 파일을 실행하는 이미지이다.
컨테이너 안에서 어떤 프로세스가 시작이되고 종료되면 컨테이너도 같이 종료된다.
docker ps -a : 모든 컨테이너(종료된 컨테이너포함)들이 나타남(name은 도커 컨테이너 이름이고 이것은 검색을 하거나 설정하거나 할 때 필요한 고유값이어야 함)
java-hello를 실행할 때 docker 컨테이너 이름을 부여하지 않아서 무작위 이름(confident_spence, objective_boyd 같은)이 부여됨
컨테이너 실행할 때 이름을 부여하면서 실행하려면
docker run -d --name app1 hello-java2
docker run -백그라운드에서실행되게detached설정으로 --name 도커컨테이너의고유한이름 실행할이미지파일
docker logs app1
실행했던 기록을 불러오는 것.
docker container prune : docker 컨테이너 기록을 삭제 -> 이후 docker ps -a 하면 아무것도 나타나지 않는다.
docker run --name app2 hello-java3
Ctrl+C 하면 컨테이너도 종료됨.
docker logs -f app2 : 로그를 실시간으로 출력함
이때는 Ctrl C 를 누르면 로그만 종료됨.
docker logs -f --tail 10 app2 : 로그를 최근 거 10개를 꼬리 물고 와서 실시간으로 출력함
마찬가지로 Ctrl C를 누르면 도커는 종료되지 않고 로그만 종료됨.
docker stop app2를 하면 백그라운드에서 실행되던 도커가 종료되고
다시 docker ps -a 하면 실행되었던 모든 도커 이름이 나타나고
docker rm app2 -> app2 도커를 제거
docker rm app1 -> app1 도커를 제거
도커에서 이미지를 실행하려면 docker images로 image 이름을 찾아서 docker run -d --name 도커이름 실행할이미지이름 을 입력하면 된다.(계속 같은거를 다시 쓰고 다시 쓰고 있지만 이러면 확실해진다!)
CentOS 안에서 app1이라는 이름의 컨테이너가 있고 app1에서는 jdk환경과 hello.class 파일이 있어서 도커를 실행시키면 자바 파일도 실행된다.
docker exec -it app1 bash라고 입력하면 컨테이너 환경으로 들어간다.
컨테이너 환경에서 java 를 입력하면 반응이 있고,
java --version을 입력하면 자바의 버젼까지 확인이 가능하다.
컨테이너의 내용은 dockerfile 때문에 가능해졌다.
컨테이너에서 CentOS로 빠져나올 때는 exit
컨테이너로 들어갈 때는 docker exec -it 컨테이너명 bash
-it 의 의미는 interactive(명령어로 입력하여 상호작용할 수 있는 공간으로 들어간다는 의미인듯)
+terminal 터미널에서 입력할 수 있도록 터미널로 연결된다는 의미인듯
docker run --name app1 -d -it hello-java3 입력해보기
현재 디렉토리의 모든 내용을 COPY . . 했기 때문에.
앞의 쩜은 현재 디렉토리의 모든 것을 뒤의쩜 작업디렉토리에 모두 넣었다.
하지만 설정 파일이나 안 넣고 싶은 파일이 있을 수도 있잖아.
그럴 때는 .dockerignore (.gitignore 와 비슷한 역할)에 빼고 싶은 파일들을 적어둔다.
즉, .dockerignore는 docker로 build 할 때 무시할 파일이나 폴더를 명시해놓으면 알아서 제외되고 이미지가 만들어진다.
그러면 docker 컨테이너 안에서 확인되지 않는다.
과제
1. Spring04_Thymeleaf 프로젝트를 빌드해서 xxx.jar 파일을 얻어낸다.
2. 얻어낸 jar 파일의 이름을 spring.jar 파일로 이름을 변경한다.
3. Linux에서 /home/docker-test/spring폴더를 만든다.
4. /home/docker-test/spring 폴더 안에 spring.jar 파일을 넣는다.
5. 위 폴더 안에서 jdk 환경에서 spring.jar를 실행할 수 있는 이미지를 생성할 Dockerfile을 생성한다.
6.생성된 Dockerfile을 이용해 spring-image라는 이름의 이미지를 build 한다.
7. Spring-image를 이용해서 spring-app이라는 이름의 container로 백그라운드로 실행한다.
단, port 번호는 9000:9000설정이 적용되도록. -> 이부분은 모르겠다. -> 전에 작성한 포스트 참고해서 하고 있다.
docker run -d --name oracle11g -p 1521:1521 -p 8080:8080 -e ORACLE_ALLOW_REMOTE=true -e ORACLE_PASSWORD=oracle oracleinanutshell/oracle-xe-11g
8. 실행후 firewall-cmd를 이용해서 9000포트를 열고 웹브라우저로 http://아이피주소:9000/spring04 요청을 해서 index페이지가 응답되는지 확인한다.
왜 안되나 했더니 6번에서 이미지 만든게 바보같이 java 폴더에서 해서 ㅠㅠㅠㅋㅋㅋㅋㅋㅋㅋㅋ
spring 폴더로 와서 다시 하는 중.
빌드중에 샘이랑 같이 하는 중(ls -l은 생략)
cd /home/docker-test/spring
mv Spring어쩌구긴이름.jar spring.jar
docker build -t spring-image . ->이미지 생성됨
docker run -d --name spring-app4 -p 9000:9000 spring-image2
계속 안돼서 왜 안되나 했더니
CMD ["java", "-jar", "spring.jar"]여야 하는데 "spring"으로 했어서!!!
다시 해봐야지.
아 된다...ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ ㅠㅠ 바부팅 ㅠ 이제 절대 안까먹겟따!! ㅋㅋㅋ
<오전: 프로젝트 진행>
내가 볼 테이블들만 정리
// 유저+매점 테이블, 본사직원은 storenum, storename, storecall NULL
Table tb_user {
userid number [pk, note: "사용자의 고유번호 시퀀스"]
storename varchar2(20) [unique, note: "어디 지점인지"]
storecall varchar2(20) [note: "학원 전화번호"]
id varchar2(20) [note: "유저 아이디"]
userpwd varchar2(20) [note: "유저 비밀번호"]
pwdstatus number [default: 1, note: "0이면 비밀번호 수정한거"]
username varchar2(20) [note: "유저 이름"]
role varchar2(20) [ref: > tb_acode.acode, note: "ROLE"]
phone varchar2(20) [note: "유저 전화번호"]
deleted varchar2 [default: "NO", note: "NO->재직중, YES->퇴사"]
}
// 각 호점 학원에서 운영하는 강의들의 수업 테이블
Table tb_class {
classid number [pk, note: "수업의 고유번호 시퀀스"]
classname varchar2(50) [note: "수업명"]
lectureid number [ref: > tb_bcode.bcode, note: "LECTURE"]
storename varchar2(20) [ref: > tb_user.storename]
description clob [note: "수업에 대한 상세 설명"]
teacherid number [ref: > tb_teacher.teacherid, note: "맡은 강사의 고유번호"]
startdate date [note: "수업이 시작하는 날짜"]
enddate date [note: "수업이 끝나는 날짜"]
starttime date [note: "수업이 시작하는 시간"]
endtime date [note: "수업이 끝나는 시간"]
maxstudent number [note: "수업의 최대 인원"]
status varchar2(20) [ref: > tb_bcode.bcode, note: "CLS"]
weekday varchar2(20) [note: "수업 요일"]
price number [note: "수업의 가격"]
}
// 학생이 어떤 수업을 듣는지 보는 중간 테이블
Table tb_student_class {
studentid number [ref: > tb_student.studentid]
classid number [ref: > tb_class.classid]
}
//지점에서 보는 매출 테이블
Table tb_adminsale {
adminsaleid number [pk, note: "고유번호 시퀀스"]
storename varchar2(20) [ref: > tb_user.storename]
credate date [note: "매출 날짜"]
editdate date [note: "매출 수정 날짜"]
salename varchar2(20) [note: "매출 항목"]
price number [note: "총 금액"]
acode varchar2 [ref: > tb_acode.acode, note: "구분"]
bcode varchar2 [ref: > tb_bcode.bcode, note: "구분 상세"]
auto varchar2 [default: 'YES', note: "NO->지점 담당자가 직접 넣었을 때"]
}
// 본사에서 제공하는 발주 품목 테이블
Table tb_product {
productid number [pk, note: "품목 고유번호 시퀀스"]
productname varchar2(255)
category varchar2(50) [ref: > tb_bcode.bcode, note: "PRODUCT"]
price number [note : "가격 -> 수정가능"]
deleted varchar2(10) [default: 'NO', note: "YES -> 발주 품목에서 제거됨" ]
}
// 지점에서 본사로 보낼 발주 목록
Table tb_order {
orderid number [pk, note: "발주 명세서의 고유번호 시퀀스"]
name varchar2(20) [note: "발주한 사람 이름"]
storename varchar2(20) [ref: > tb_user.storename]
credate date [default: 'SYSDATE', note: "발주 처음 요청 날짜"]
editdate date [default: 'SYSDATE', note: "발주 수정 날짜"]
rejdate date [default: `SYSDATE`, note: "본사에서 발주 반려된 날짜"]
orddate date [default: "SYSDATE", note: "마지막 발주 요청 결과 날짜"]
status varchar2(20) [ref: > tb_bcode.bcode, note: "ORDER"]
memoreply varchar2(500)
memorequest varchar2(500)
totalprice number [note: "지점에서 본사로 보낼때 프론트에서 값을 구해서 요청할 때 insert"]
}
// 지점에서 발주 목록에 추가할 품목 테이블
Table tb_order_detail {
orderdetailid number [pk, note: "각 발주 품목의 고유 번호"]
orderid number [ref: > tb_order.orderid]
productid number [ref: > tb_product.productid]
quantity number
price number [ref: > tb_product.price, note: "개당 가격"]
}
SalesMapper랑 mapper 만들던 중에 Dto 부터 만듦
package com.example.FinalProject.dto;
import lombok.Data;
@Data
public class SalesDto {
int adminsaleid;//지점 adminsale 고유번호
int ceosaleid;//본사 ceosale 고유번호
int storenum;//매장번호 = tb_user.storename
String salename;//매출 항목
String credate;//매출 날짜
String editdate;//매출 수정 날짜
int price;//항목 금액
String acode;//구분코드 : 수입/지출
String bcode;//상세구분코드 : 수업료수입, 기타수입,강사월급, 발주비용, 기타지출
String auto;//default: yes(발주나 수업에서 처리됨), no: 담당자가 직접 입력
//쿼리문 관련
int totalprofit;//총수입
int totalcost;//총지출
int totalprice;//총금액
String sdate;//문자열로 변환된 date 타입의 data
String smonth;//상동
String syear;//상동
//수업 관련 : tb_class, tb_student_class
String clsstatus;//수업 상태 : 진행중
int classid;//수업 고유 번호
int clsprice;//수업료
int studentcount;//학생 수
//발주 관련 :tb_product, tb_order, tb_order_detail
int orderid;//발주고유번호
int orderstatus;//발주상태
int orderdetailid;//발주 품목의 고유번호
int productid;//tb_product.productid
int quantity;//수량
int productprice;//개당 가격
int productname;//품목 이름
}
SalesMapper 만드는 중. CEO 측은 내 파트 아니어서 일단 내 파트에서 필요한 기능은 이정도 되는 것 같은...데.
package com.example.FinalProject.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.example.FinalProject.dto.SalesDto;
@Mapper
public interface SalesMapper {
//Admin 측
//지점번호와 bcode를 읽으면
List<SalesDto> getAdminSalesList(@Param("storenum") int storenum, @Param("bcodes") List<String> bcodes);
SalesDto getAdminSalebyId(int adminsaleid);
int insertAdminSales(SalesDto dto);
int editAdminSales(SalesDto dto);
int deleteAdminSales(int adminsaleid);//
//발주가 "승인"일 때 발주 비용 추가하는 메소드(발주에서 사용)
int insertOrderApprovedCost(SalesDto dto);
//수업이 '진행중'일 때 수업료 수입을 추가하는 메소드(수업에서 사용)
int insertClsIngProfit(SalesDto dto);
//연도별 수입 데이터 불러오기
List<SalesDto> getAdminProfitStatbyYear();
//연도별 지출 데이터 불러오기
List<SalesDto> getAdminCostStatbyYear();
//연도별 과목별 데이터 불러오기
List<SalesDto> getAdminSalesStatbyLectYearly();
//연도의 월별 과목별 데이터 불러오기
List<SalesDto> getAdminSalesStatbyLectMonthly();
//Ceo측
}
<오후 : 프로젝트 진행>
깃허브에 내가 작업하는부분만 포트폴리오 용으로 만들고 싶어서 왔다 갔다 하다가 이전에 했던거랑 자꾸 중복되고,
이번에 멘토링 후 조장님이 올린거는 gemini API도 포함되어 있고 그래서 그냥 이전에 하던 환경에서 수정내용 반영해서 하려고 함.
로그인은 나중에 처리하고 일단 내가 만든 화면 UI 좀 손봐야겠다.
맵퍼 작성 중에 발주와 수업과 연관된 맵퍼는 다른 맵퍼들이 만들어진 다음에야 어느정도 활용 가능할 수 있는 것 같다.
일단 보류하고 남은 한시간은 내가 좋아하는 프론트 하다 가야징 ㅎㅎ
프론트 자꾸 사이드바가 공중에 떠있어서 우리가 참고하기로 한 프로젝트 분석했는데 진짜 대박적.
우리가 배운 방식이랑 다르게 라우터를 두지 않고 currentMenu를 둬서 진행함. 이걸 우리꺼에 잘 적용을 해봐야겠다.
오늘 한 거 최종
package com.example.FinalProject.dto;
import lombok.Data;
@Data
public class SalesDto {
int adminsaleid;//지점 adminsale 고유번호
int ceosaleid;//본사 ceosale 고유번호
String storename;//매장번호 = tb_user.storename
String salename;//매출 항목
String credate;//매출 날짜
String editdate;//매출 수정 날짜
int price;//항목 금액
String acode;//구분코드 : 수입/지출
String bcode;//상세구분코드 : 수업료수입, 기타수입,강사월급, 발주비용, 기타지출
String auto;//default: yes(발주나 수업에서 처리됨), no: 담당자가 직접 입력
//쿼리문 관련
int totalprofit;//총수입
int totalcost;//총지출
int totalprice;//총금액
String sdate;//문자열로 변환된 date 타입의 data
String smonth;//상동
String syear;//상동
//수업 관련 : tb_class, tb_student_class
String clsstatus;//수업 상태 : 진행중
int classid;//수업 고유 번호
int clsprice;//수업료
int studentcount;//학생 수
//발주 관련 :tb_product, tb_order, tb_order_detail
int orderid;//발주고유번호
int orderstatus;//발주상태
int orderdetailid;//발주 품목의 고유번호
int productid;//tb_product.productid
int quantity;//수량
int productprice;//개당 가격
int productname;//품목 이름
}
package com.example.FinalProject.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.example.FinalProject.dto.SalesDto;
@Mapper
public interface SalesMapper {
//Admin 측
//지점번호와 bcode를 넣어서 수입/지출 리스트를 가져오기
List<SalesDto> getAdminSalesList(@Param("storenum") int storenum, @Param("bcodes") List<String> bcodes);
SalesDto getAdminSalebyId(int adminsaleid);
int insertAdminSales(SalesDto dto);
int editAdminSales(SalesDto dto);
int deleteAdminSales(int adminsaleid);//
//발주가 "승인"일 때 발주 비용 추가하는 메소드와 관련 메소드(발주에서 사용)
int insertOrderApprovedCost(SalesDto dto);
int countByClassId(@Param("classid") int classid);
int getPriceByClassId(@Param("classid") int classid);
String getNameByClassId(@Param("classid") int classid);
//수업이 '진행중'일 때 수업료 수입을 추가하는 메소드와 관련 메소드(수업에서 사용)
int insertClsIngProfit(SalesDto dto);
//연도별 수입 데이터 불러오기
List<SalesDto> getAdminProfitStatbyYear();
//연도별 지출 데이터 불러오기
List<SalesDto> getAdminCostStatbyYear();
//연도별 과목별 데이터 불러오기
List<SalesDto> getAdminSalesStatbyLectYearly();
//연도의 월별 과목별 데이터 불러오기
List<SalesDto> getAdminSalesStatbyLectMonthly();
//Ceo측
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.SalesMapper">
<select id="getAdminSalesList" parameterType="map" resultType="AdminSale">
SELECT *
FROM tb_adminsale
<where>
storename = #{storename}
<if test="bcodes != null and bcodes.size() > 0">
AND bcode IN
<foreach item="bcode" collection="bcodes" open="(" separator="," close=")">
#{bcode}
</foreach>
</if>
</where>
ORDER BY credate DESC
</select>
<select id="getAdminSalebyId">
select * from tb_adminsale
where adminsaleid=#{adminsaleid}
</select>
<insert id="insertAdminSales">
insert into tb_adminsale
(adminsaleid, storename, credate, editdate, salename, price, acode, bcode, auto)
values
(adminsale_seq.nextval, #{storename}, sysdate, sysdate, #{salename}, #{price}, #{acode}, #{bcode}, 'NO' )
</insert>
<update id="editAdminSales">
update tb_adminsale
set (storename=#{storename}, editdate=sysdate, salename=#{salename},
price=#{price}, acode=#{acode}, bcode=#{bcode}, auto='NO')
where adminsaleid=#{adminsaleid}
</update>
<delete id="deleteAdminSales">
delete from tb_adminsale
where adminsaleid=#{adminsaleid}
</delete>
<insert id="insertOrderApprovedCost">
insert into tb_adminsale
(adminsaleid, storename,credate,editdate, salename,price, acode, bcode,auto)
values
(adminsale_seq.nextval,#{storename}, sysdate, sysdate, #{salename}, #{price}, #{acode}, #{bcode}, 'YES')
</insert>
<select id="countByClassId" resultType="int">
SELECT COUNT(*)
FROM tb_student_class
WHERE classid = #{classid}
</select>
<select id="getPriceByClassId" resultType="int">
SELECT price
FROM tb_class
WHERE classid = #{classid}
</select>
<select id="getNameByClassId" resultType="string">
SELECT classname
FROM tb_class
WHERE classid = #{classid}
</select>
</mapper>
package com.example.FinalProject.service;
public interface SalesService {
public void insertRevenueByClass(int classid, String storename, String acode, String bcode);
}
package com.example.FinalProject.service;
import org.springframework.beans.factory.annotation.Autowired;
import com.example.FinalProject.dto.SalesDto;
import com.example.FinalProject.mapper.SalesMapper;
public class SalesSerivceImpl implements SalesService{
@Autowired SalesMapper salesmapper;
@Override
public void insertRevenueByClass(int classid, String storename, String acode, String bcode) {
// int studentCount = studentClassMapper.countByClassId(classid);
// int classPrice = classMapper.getPriceByClassId(classid);
// String classname = classMapper.getNameByClassId(classid);
// String salename = classname + " 수업 수익";
// int totalRevenue = studentCount * classPrice;
// SalesDto dto = new SalesDto();
// dto.setStorename(storename);
// dto.setSalename(salename);
// dto.setPrice(totalRevenue);
// dto.setAcode(acode);
// dto.setBcode(bcode);
// salesmapper.insertOrderApprovedCost(dto);
}
}
......
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ하... 내일은 대학원 시험때문에 못나올거 같고, 낼 모레 이어서 해보자....
'자바풀스택 과정 > 자바 풀 스택 : 수업내용정리' 카테고리의 다른 글
자바 풀 스택 4/25 하루 기록 106(최종프로젝트 22일차) (0) | 2025.04.25 |
---|---|
자바 풀 스택 4/24 하루 기록 105(104는 대학원 시험때문에 기록 못함)(최종프로젝트 21일차) (0) | 2025.04.24 |
자바 풀 스택 4/20 하루 기록 101(멘토링 2차시)(최종프로젝트 19일차) (0) | 2025.04.20 |
자바 풀 스택 4/18 하루 기록 100(최종프로젝트 18일차) (1) | 2025.04.18 |
자바 풀 스택 4/17 하루 기록 099(최종프로젝트 17일차) (1) | 2025.04.17 |