반응형

최신 오라클  라이브러리가 cx_Oracle에서 oracledb 변경되었다.

 

Insert

# Plan MH 일괄 추출
from datetime import datetime

import oracledb
import os


os.putenv('NLS_LANG', '.UTF8')
now = datetime.today()

# DB연결
conn = oracledb.connect(user='myuser', password='1234', dsn='abcd.abcde.com:1526/abcd')
cursor = conn.cursor() #지시자 생성

query_str = "insert into SOME_TABLE values (:1,:2,:3,:4,:5,:6,:7,:8)"
data = ('20240125','AAAA','BBBB','1400350','CCCC','2',now,'DDDD')
cursor.execute(query_str,data)
conn.commit()

conn.close()
반응형
반응형

 

1. template/hello.html

데이터를 받아들일 html템플릿을 만들어둔다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello</title>
</head>
<body>
    <p th:text="${user}">Hello Thymeleaf!!</p>
</body>
</html>

 

2.Controller.java

자료를 넘길때는 ModelAndView객체에 담아서 보낸다.

...
	
@GetMapping("/user")
public ModelAndView hello(@RequestParam("id") String id) throws Exception {

    ModelAndView mav = new ModelAndView();		
    UserDto res = userService.getUserById(id);

    mav.setViewName("hello");	
    mav.addObject("user",res.getName());

    return mav;
}
    
 ...
반응형
반응형

 

 

1. Controller: UserProfileController.java

package com.example.myba.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.myba.dto.ItemDto;
import com.example.myba.dto.ResponseDto;
import com.example.myba.service.QuickService;

import io.swagger.v3.oas.annotations.parameters.RequestBody;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
public class UserProfileController {
	
	@Autowired
	private QuickService quickService; //자동으로 값을 넣은 객체를 생성해줌. DI
	
	@GetMapping("/dummy")
	public String dummy() {
//		log.info("dummy");
		return "{}";
	}
	
	@GetMapping("/dummy2")
	public String dummy2() {
		return "dummy2";
	}
	
	@GetMapping("/member")
	public String getMember(@RequestParam("empNo") String empNo) {
		return "OK";
	}

	@GetMapping("/company/{id}")
	public String getCompany(@PathVariable("id") String id) {
		return "OK";	
	}
	
	@PostMapping("/item")
	public ResponseDto registerItem(@RequestBody ItemDto item) {
		
		boolean b = quickService.registerItem(item);
		
		if(b==true) {
			ResponseDto responseDto = new ResponseDto();
			responseDto.setMessage("ok");
			
			return responseDto;
		}
		
		ResponseDto responseDto = new ResponseDto();
		responseDto.setMessage("fail");
		
		return responseDto;
	}
	
	@PostMapping("/user")
	public String registerUser(@RequestBody String user) {		
		return "OK";
	}
	
	@GetMapping("/item")
	public ItemDto getItem(@RequestParam("id") String id) {
		ItemDto res = quickService.getItemById(id);
		return res;
	}
	
}

 

2. dto

- ItemDto.java

package com.example.myba.dto;

public class ItemDto {
	
	private String id;
	
	private String name;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
}

 

 

- ResponseDto.java

package com.example.myba.dto;

public class ResponseDto {
	private String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
	
}

 

3. mapper: QuickMapper.java

package com.example.myba.mapper;

import java.util.HashMap;

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface QuickMapper {
	HashMap<String, Object> findById(HashMap<String, Object> paramMap);
}

 

 

 

4. mapper.xml: QuickMapper.xml

<?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="com.example.myba.mapper.QuickMapper">

	<select id="findById" parameterType="hashmap" resultType="hashmap">
		SELECT id, name FROM item WHERE id = #{id}
	</select>
	
</mapper>

 

 

5. service: QuickService.java

package com.example.myba.service;

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.myba.dto.ItemDto;
import com.example.myba.mapper.QuickMapper;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class QuickService {
	
	@Autowired QuickMapper quickMapper;
	
	public boolean registerItem(ItemDto itemDto) {
		// TODO:
		
		return true;
	}
	
	public ItemDto getItemById(String id) {
		
		HashMap<String, Object> paramMap = new HashMap<>();
		paramMap.put("id", id);
		
		HashMap<String, Object> res = quickMapper.findById(paramMap);
		
		
		ItemDto itemDto = new ItemDto();
		itemDto.setId((String)res.get("ID"));;
		itemDto.setName((String)res.get("NAME"));
		
		return itemDto;
	}
}

 

6. application.properties

spring.application.name=myba

#spring.datasource.url=jdbc:mysql://localhost:3306/personal_info
#spring.datasource.username=asdf
#spring.datasource.password=1234
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:~/test
spring.datasource.username=asdf
spring.datasource.password=1234

spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@12.34.56.78:1526:abcde
spring.datasource.username=asdf
spring.datasource.password=1234


mybatis.type-aliases-package=com.example.myba.mapper 
# Mybatis mapper 위치 설정
mybatis.mapper-locations= mybatis-mapper/*.xml

 

 

7. 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.2.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>myba</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>myba</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>3.0.3</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter-test</artifactId>
			<version>3.0.3</version>
			<scope>test</scope>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
		<dependency>
		    <groupId>org.springdoc</groupId>
		    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
		    <version>2.1.0</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
		    <groupId>org.projectlombok</groupId>
		    <artifactId>lombok</artifactId>
		    <version>1.18.30</version>
		    <scope>provided</scope>
		</dependency>
		
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
		</dependency>


	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

 

 

 

 

반응형
반응형

여기서 최신버전을 복사해서 pom.xml의 디펜던시에 넣어준다.

 

Maven Repository: org.springdoc » springdoc-openapi-starter-webmvc-ui » 2.5.0 (mvnrepository.com)

<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.5.0</version>
</dependency>

 

localhost:8080/swagger-ui/index.html

 

반응형
반응형
import turtle

turtle.title('거북이')
turtle.color('black', 'red')
turtle.shape('turtle')
turtle.penup();
turtle.write("빠른 거북이!!")
turtle.forward(80)
turtle.pendown();
turtle.backward(100)
turtle.exitonclick()

 

 

수행해보니 이번엔 속도가 너무 빠르네요. 속도값은 다음과 같습니다.

 

0: 가장 빠른

1: 가장 느린

3: 느린

6: 보통 (기본값)

10: 빠른

 

지금 기본값이 보통 이라고? 너무 빠른데요. 1로 변경해보겠습니다.

import turtle

turtle.title('거북이')
turtle.color('black', 'red')
turtle.shape('turtle')
turtle.penup();
turtle.write("빠른 거북이!!")

turtle.speed(1) #코드 추가

turtle.forward(80)
turtle.pendown();
turtle.backward(100)
turtle.exitonclick()

 

숫자값이 기억하기 어렵다면 문자로 전달해도 됩니다.

 'fastest', 'fast', 'normal', 'slow', 'slowest'

 

 

반응형
반응형

Tkinter에서 다른 위젯의 배치를 위한 Frame을 사용할 수 있습니다. 아래는 Frame 예제입니다.

import tkinter as tk

root = tk.Tk()
root.title("GUI Frame")
root.geometry("640x480+100+100")
root.resizable(True,True)

frame1 = tk.Frame(root, relief="solid", bd=1, highlightcolor="red")
frame1.pack(side="top", fill="both", expand=True)

frame2 = tk.Frame(root, relief="solid", bd=2, bg="blue")
frame2.pack(side="bottom", fill="both", expand=True)

root.mainloop()

 

 

Frame Parameter

Param 의미 기본값 속성
width 프레임의 너비 0 상수
height 프레임의 높이 0 상수
relief 테두리 모양 flat flat, groove, raised, ridge, solid, sunken
bg 배경색 SystemButtonFace color
bd 테두리 두께 0 상수
padx 내부 x방향 패딩 1 상수
pady 내부 y방향 패딩 1 상수
highlightcolor 프레임이 선택될 때 색상 SystemWindowFrame color

 

반응형
반응형

Tkinter에서 위젯을 화면에 배치하는 방법에는 pack / grid / place의 세가지 방식이 있습니다. grid는 엑셀과 같은 이미지를 떠올리면 될 것 같습니다. 행과 열을 기준으로 위치시키는 방식이고, pack은 상/하/좌/우(동/서/남/북)으로 위치시키는 방식, 그리고 place는 절대좌표계를 이용해서 위치시키는 방식입니다.

 

1. Grid방식

import tkinter as tk

root = tk.Tk()
root.title("GUI Grid위젯배치")
root.geometry("640x480+100+100")
root.resizable(True,True)

bb1 = tk.Button(root, text="(0,0)")
bb1.grid(row=0,column=0)
bb2 = tk.Button(root, text="(0,1)")
bb2.grid(row=0,column=1)
bb3 = tk.Button(root, text="(0,2)")
bb3.grid(row=0,column=2)
bb4 = tk.Button(root, text="(1,0)")
bb4.grid(row=1, columnspan=3, sticky="ew")

root.mainloop()

 

Grid 속성

- 먼저 선언한 Grid부터 배치된다.

- 셀 단위로 배치되며, 한번에 여러 셀을 건너뛰어 배치할 수 없다.

- pack()과 같이 사용할 수 없으며, place()와는 같이 사용할 수 있다.

 

Grid Parameter

Param 의미 기본값 속성
row 행 위치 0  
column 열 위치 0  
rowspan 행 합치기 1  
columnspan 열 합치기 1  
sticky 할당된 공간 내에서 위치 조정. 어디에 고정할 것인가? - n(north), e(east), s(south), w(west)
news와 같이 전방향 고정으로 조합하여 사용 가능
ipadx x방향 내부 패딩 0  
ipady y방향 내부 패딩 0  
padx x방향 외부 패딩 0  
pady y방향 외부 패딩 0  

 

2. Pack방식

Pack은 상하좌우(동서남북) 에 위젯들을 위치시키는 방식입니다.

import tkinter as tk

root = tk.Tk()
root.title("GUI pack 위젯배치")
root.geometry("640x480+100+100")
root.resizable(True,True)

bb1 = tk.Button(root, text="left", width=10)
bb1.pack(side="left", fill="y")
bb2 = tk.Button(root, text="top", width=10)
bb2.pack(side="top")
bb3 = tk.Button(root, text="(right)", width=10)
bb3.pack(side="right")
bb4 = tk.Button(root, text="(bottom)", width=10)
bb4.pack(side="bottom", anchor="n")

root.mainloop()

 

Pack 속성

- 먼저 선언한 pack부터 배치된다.

- pack의 파라미터로 위젯의 크기를 변경할 수 있다.

- grid()와 같이 사용할 수 없으며 place()와는 같이 사용할 수 있다.

 

Pack Parameter

Param 의미 기본값 속성
side 위치(공간)할당 top top, bottom, left, right
anchor 고정 기준 center center, n(north), e(east), s(south), w(west)
news와 같이 전방향 고정으로 조합하여 사용 가능
fill 할당된 공간에 대한 크기 맞춤 none none, x, y, both
expand 미사용 공간 확보 False Boolean
ipadx x방향 내부 패딩 0  
ipady y방향 내부 패딩 0  
padx x방향 외부 패딩 0  
pady y방향 외부 패딩 0  

 

3. place방식

import tkinter as tk

root = tk.Tk()
root.title("GUI Grid위젯배치")
root.geometry("640x480+100+100")
root.resizable(True,True)

bb1 = tk.Button(root, text="(30,30)")
bb1.place(x=30, y=30)
bb2 = tk.Button(root, text="(100,30)")
bb2.place(x=100, y=30)
bb3 = tk.Button(root, text="(30,80)")
bb3.place(x=30, y=80)
bb4 = tk.Button(root, text="(100,80)")
bb4.place(x=100, y=80)

root.mainloop()

 

Place 속성

- 먼저 선언한 요소부터 배치된다.

- place의 절대 위치로 배치되며, 크기를 조정할 수 있다.

- pack(), grid()와 같이 사용할 수 있다.

 

place Parameter

Param 의미 기본값 속성
x x 좌표 0 상수
y y 좌표 0 상수
relx x좌표 배치 비율 0 0~1
rely y좌표 배치 비율 0 0~1
width 위젯 폭 0 상수
height 위젯 높이 0 상수
relwidth 위젯의 상대 너비 0 0~1
relheight 위젯의 상대 높이 0 0~1
anchor 고정 기준 nw n(north), e(east), s(south), w(west)
news와 같이 전방향 고정으로 조합하여 사용 가능

 

 

오늘은 헷갈리지 않도록 grid / pack / place의 속성에 대해 정리하는 시간을 가져봤습니다. 

반응형
반응형

예전에 테스트삼아 해봤는데, 오랫만에 하니까 잘 모르는 것도 있고, 좀 바뀐 부분도 있어서 정리도 할겸 올립니다. 아래와 같은 tkinter 화면을 만들겁니다.

 

1. main.py

우선 main.py에서는 구동만 시켜주고, 화면을 구성하는 파일은 gui.py로 별도 모듈로 만들 예정입니다.

import gui

if __name__ == '__main__':
    gui.main_screen()

 

2. gui.py

import tkinter as tk


def main_screen():
    root = tk.Tk()
    root.title("GUI Sample")
    root.geometry("640x480+100+100")
    root.resizable(True,True)
    root.configure(background='white')  # 배경을 흰색으로 하고,
    # root.wm_attributes("-transparentcolor", 'white') # 흰색을 투명으로 하면 투명한 앱이 됩니다.

    #레이블
    label_1=tk.Label(root, text="위젯 테스트", width=20,height=3,fg="red",relief="solid")
    label_1.pack()
    label_2=tk.Label(root, text="위젯 테스트2", width=20, height=3, fg="blue", relief="groove")
    label_2.pack()

    #리스트박스
    listbox = tk.Listbox(root, selectmode='extended', height=0)
    listbox.insert(0, "no1")
    listbox.insert(1, "no2")
    listbox.insert(2, "no3")
    listbox.insert(3, "no4")
    listbox.insert(4, "no5")
    listbox.pack()

    #체크박스
    checkVal1 = tk.IntVar()
    checkVal2 = tk.IntVar()
    checkBtn1 = tk.Checkbutton(root, text="체크박스 고르기1", variable=checkVal1, activebackground="blue")
    checkBtn2 = tk.Checkbutton(root, text="체크박스 고르기2", variable=checkVal2, activebackground="blue")
    checkBtn1.pack()
    checkBtn2.pack()

    #라디오버튼
    radioVal1=tk.IntVar()
    radioBtn1 = tk.Radiobutton(root, text="1번", value=3, variable=radioVal1)
    radioBtn2 = tk.Radiobutton(root, text="2번", value=6, variable=radioVal1)
    radioBtn3 = tk.Radiobutton(root, text="3번", value=9, variable=radioVal1)
    radioBtn1.pack()
    radioBtn2.pack()
    radioBtn3.pack()

    #상단메뉴
    def close():
        root.quit()
        root.destroy()

    menubar = tk.Menu(root)

    menu_1 = tk.Menu(menubar, tearoff=0)
    menu_1.add_command(label="Sub Menu1-1")
    menu_1.add_command(label="Sub Menu1-2")
    menu_1.add_separator()
    menu_1.add_command(label="종료", command=close)
    menubar.add_cascade(label="Menu1", menu=menu_1)

    menu_2 = tk.Menu(menubar, tearoff=0, selectcolor="red")
    menu_2.add_radiobutton(label="Sub Menu2-1", state="disable")
    menu_2.add_radiobutton(label="Sub Menu2-2")
    menu_2.add_radiobutton(label="Sub Menu2-3")
    menubar.add_cascade(label="Menu2", menu=menu_2)

    menu_3 = tk.Menu(menubar, tearoff=0)
    menu_3.add_checkbutton(label="Sub Menu3-1")
    menu_3.add_checkbutton(label="Sub Menu3-2")
    menu_3.add_checkbutton(label="Sub Menu3-3")
    menubar.add_cascade(label="Menu3", menu=menu_3)

    root.config(menu=menubar)

    # 메뉴 버튼 (상단 메뉴바랑 상관 없음)
    menubutton = tk.Menubutton(root, text="Menu Button", relief="raised", direction="right")
    menubutton.pack()

    menu = tk.Menu(menubutton, tearoff=0)
    menu.add_command(label="Sub-1")
    menu.add_separator()
    menu.add_command(label="Sub-2")
    menu.add_command(label="Sub-3")

    menubutton["menu"] = menu

    # 배치연습
    bb1=tk.Button(root, text="(50,50)")
    bb1.place(x=50,y=50)
    bb2 = tk.Button(root, text="(130,50)",width=10, height=1)
    bb2.place(x=130, y=50)
    bb3 = tk.Button(root, text="(50,100)", border=3)
    bb3.place(x=50, y=100)
    bb4 = tk.Button(root, text="(130,100)")
    bb4.place(x=130, y=100)


    root.mainloop()
반응형

+ Recent posts