배경

Spring boot를 통해서 개발을 하게 된다면, DB에 데이터를 삽입, 읽기 등 여러 가지 작동을 하기 위해서는 방식이 필요하다. 쿼리를 작동시키는 방식에는 여러 가지 방식이 존재한다.

특히 Spring JPA Data Doc은 레퍼런스도 있고, SQL이 자동생성되게 할 수 있습니다.

https://docs.spring.io/spring-data/jpa/docs/2.3.3.RELEASE/reference/html/#jpa.repositories

 

Spring Data JPA - Reference Documentation

Example 108. Using @Transactional at query methods @Transactional(readOnly = true) public interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") v

docs.spring.io

 

~~Repository에 @Query와 함께 메소드를 작성하면, Service에서 바로 사용할 수 있다.

직접적으로 DB에 쿼리문으로 접근할 수 있다.

 

사용방법

1. 쿼리를 직접쓰는 경우는 다음과 같은 조건이 있어야 한다

@Query("SELECT u FROM User u WHERE u.status = 1")
Collection<User> findAllActiveUsers();

⭐⭐⭐From table 별칭을 Select문 안에 넣어야 한다. 안그러면 오류를 만들어낸다⭐⭐⭐

 

2. DB에서처럼 쿼리를 작성하는 방식

@Query(
value = "SELECT * FROM USERS u WHERE u.status = 1",
nativeQuery = true)
Collection<User> findAllActiveUsersNative();

 nativeQuery = true 속성을 줘야만 가능하다.

 

3. Parameter를 전달해주기

 

1️⃣ ?를 통한 경우 -> parameter의 위치에 따른 숫자를 넣어주면 된다.

?1 -> parameter 첫번째 자리에 있는걸 넣겠다는 뜻.

public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}

 

2️⃣ :name -> 파라미터의 이름으로 검색하는 경우

public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname,
@Param("firstname") String firstname);
@Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(String lastname, String firstname); //이렇게도 사용 가능하다.
}

 

물론 이경우 말고도 여러가지 케이스가 존재한다. SPEL을 이용할 수도 있기도하고 Sorting하는 방식이라던가 진짜 여러가지 방식으로 활용 가능하다.

자세한건

https://docs.spring.io/spring-data/jpa/docs/2.3.3.RELEASE/reference/html/#jpa.repositories

 

Spring Data JPA - Reference Documentation

Example 108. Using @Transactional at query methods @Transactional(readOnly = true) public interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") v

docs.spring.io


참고 : https://sundries-in-myidea.tistory.com/91

 

Spring Data JPA에서 Query를 사용하는 방법

쿼리를 자동 생성해준다고? Spring boot를 통해서 개발을 하게 된다면, DB에 데이터를 삽입, 읽기 등 여러 가지 작동을 하기 위해서는 방식이 필요하다. 쿼리를 작동시키는 방식에는 여러 가지 방식

sundries-in-myidea.tistory.com

 

1. MySQL 쿼리문 에러 정리

--- The error occurred in sqlmaps/empty.xml. 
--- The error occurred while applying a parameter map. 
--- Check the mapNamespace.id-InlineParameterMap. 
--- Check the statement (query failed). 
--- Cause: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Unknown column 'columnName' in 'field list'
해당하는 컬럼명(columnName)이 없다는 것. 오타일 확률이 높으니 눈을 크게 뜨고 찾아보자.
간간히 대소문자도 걸리던거 같던데 기준을 모르겠다.

 

2. Mysql 테이블, DB 관리

MySQL 접속/상태 확인
텔넷에서 MySQL 접속하기
mysql -u[사용자아이디] -p[비밀번호]

접속 끊기
mysql> exit
 
현재 상태 보기
mysql> status



DB 관리
DB 목록 보기
mysql> SHOW DATABASES;

 

DB 고르기
mysql> USE DB이름;

 

DB 만들기
mysql> CREATE DATABASE DB이름;

 

DB 지우기
mysql> DROP DATABASE DB이름;



테이블 관리
테이블 목록 보기
mysql> SHOW TABLES;

 

테이블 구조 보기
mysql> DESC 테이블이름;
mysql> DESCRIBE 테이블이름;
mysql> EXPLAIN 테이블이름;

 

테이블 만들기
CREATE TABLES 테이블이름 ( 항목이름1 변수형, 항목이름2 변수형, ... );

mysql> CREATE TABLE customer
> ( Name char(50),
> Address char(50),
> City char(50),
> Country char(25),
> Birthday date );

 

테이블 이름 바꾸기
mysql> RENAME TABLE 테이블이름1 to 테이블이름2;

 

테이블 지우기
mysql> DROP TABLE 테이블이름;
 

 

3. JPA, Mysql 연동
연동할때는 Entity의 column이 bookReport라면 Mysql에서는 book_report 이렇게 스네이크 형식으로 바꾸어야 한다.

 

 

'개발합시다. > Today I Learned' 카테고리의 다른 글

[22.01.18 TIL] Springboot @Query 사용법  (0) 2022.01.18
21.09.17 TIL (비트연산자)  (0) 2021.09.20
21.09.16 TIL (Typechecker, Import All)  (0) 2021.09.17
21.08.25 TIL  (0) 2021.08.26
2021.08.13 TIL  (0) 2021.08.13

1.비트연산자

 

사용하게 된 이유는 다음과 같다.

위의 사진처럼 체크한 것을 DB상에 데이터로 넣어야되는데 각각의 항목에 대해 Column을 만들기에는 너무 공간낭비가 커서 BIT를 사용해서 넣기로 하였다.

 

그래서 '권리침해~'를 예시로 들면 해당없음만 체크하면 2^0 x 1, 압류만 체크하면 2^1 x 1 이렇게 저장해주기로 했다.

그래서 front측에서는 값을 모두 바꿔서 10진수 숫자로 Backend에 넘겨주면 백엔드에서는 이걸 다시 2진수로 바꿔서 로직을 돌리고, DB에 넣을때는 결국 다시 10진수로 넣어주면 되었다.

 

그래서 지금 해야할 것은

1. JS에서 체크 된 것을 확인하고 10진수로 만들기

2. Python에서 bit연산자를 통해 2진수의 각각의 자릿수가 1인지 아닌지 체크하기

 

 

해결책.

 

1. 매우간단하다. 

str[i] * (2 ^ i) 이렇게 해주면 매우 간단하게 10진수로 변환

 

2. 

str & (1 << i) 이렇게 하면 1인지 아닌지 확인 가능하다.

 

그러면서 간단하게 비트연산자를 찾아보기도 했는데, 결국 간단한 함수들을 어떻게 활용하는지가 제일 중요한듯

 

https://dojang.io/mod/page/view.php?id=173 

 

C 언어 코딩 도장: 23.1 비트 AND, OR, XOR 연산자 사용하기

이제 비트 연산자를 사용하여 값을 계산해보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요. a & b a | b a ^ b bitwise_and_or_xor_operator.c #include int main() { unsigned char num1 = 1; // 0000 00

dojang.io

 

1.TypeChecker

함수에 넣을때 들어가는 파라미터가 지정해둔 정수형으로 들어가는지 체크함

아니면 바로 에러구문 표시

from inspect import getfullargspec


def type_checker(default=None):
    def get_decorator(decorated):
        spec = getfullargspec(decorated)
        argNames = spec.args
        annotations = spec.annotations

        def decorator(*args, **kwargs):
            for idx, val in enumerate(args):
                argName = argNames[idx]
                if (argName in annotations and type(val) is not annotations[argName]):
                    return default
            for key, val in kwargs.items():
                if (key in annotations and type(val) is not annotations[key]):
                    return default

            return decorated(*args, **kwargs)

        return decorator

    return get_decorator

데코레이터를 활용해서 이렇게 구현했음

@type_checker(((1, "잘못된 데이터"), None))
def send_message_api(session, phone_number: str):

이건 예시

 

2. Import All

파이썬에서 폴더를 모듈화 시키고 안에 있는 모든 함수들을 import할때 사용하려고 했음

from .operation import *
from .operation import 변수
from .operation import 함수
from .operation import 클래스

주로 이렇게 사용한다.

 

하지만 testing 폴더에 __init__.py를 생성하고

from .operation import *    # 현재 패키지의 operation 모듈에서 모든 변수, 함수, 클래스를 가져옴
from .geometry import *     # 현재 패키지의 geometry 모듈에서 모든 변수, 함수, 클래스를 가져옴

이렇게 작성해준다.

 

그럼 이제 다른 곳에서는 

import testing    # testing 패키지만 가져옴
 
print(testing.add(10, 20))   # 패키지.함수 형식으로 operation 모듈의 add 함수 사용
print(testing.mul(10, 20))   # 패키지.함수 형식으로 operation 모듈의 mul 함수 사용
 
print(testing.triangle_area(30, 40)) # 패키지.함수 형식으로 geometry 모듈의 triangle_area 함수 사용
print(testing.rectangle_area(30, 40))# 패키지.함수 형식으로 geometry 모듈의 rectangle_area 함수 사용

이렇게 testing만 import해서 하위에 있는 모든 것들을 import 가능함

 

그리고 __init__.py에서 

__all__ = ['add', 'triangle_area']    # calcpkg 패키지에서 add, triangle_area 함수만 공개

이렇게 해주면 모든 것을 공개하는게 아니라 add와 triangle_area만 공개할 수 있음

 

 

참고 : https://dojang.io/mod/page/view.php?id=2450 

 

파이썬 코딩 도장: 45.4 패키지에서 from import 응용하기

지금까지 calcpkg 패키지의 모듈을 가져올 때 import calcpkg.operation처럼 import 패키지.모듈 형식으로 가져왔습니다. 그러면 import calcpkg처럼 import 패키지 형식으로 패키지만 가져와서 모듈을 사용할 수

dojang.io

https://umbum.dev/176

 

[python] import 관련 : 모듈, 패키지, __init__.py, __all__

모듈을 싱글턴 처럼 쓸 수는 있지만 이렇게 쓰는건 별로다. 파이썬 모듈은 참조된 횟수에 상관없이 단 하나의 복사본만 불러온다. 따라서 모듈 자체를 하나의 싱글턴으로 사용할 수 있다. 그래

umbum.dev

https://nesoy.github.io/articles/2018-07/Python-init-all

 

Python의 __init__, __all__ 란?

 

nesoy.github.io

 

1. Python Filter 활용하기

 

활용 : 리스트에서 None 값을 제거하고 싶을떄

 

기존에는 For문을 돌려서 None일때 remove를 해줬는데, 이렇게 되면 가끔 안지워지는 것도 있고, 깨끗한 코드가 아니였다.

sample_list = ['', 'a', '', 'abc', 'qdsf']
sample_list = list(filter(None, sample_list))
sample_list # ['a', 'abc', 'qdsf']

이렇게 Filter를 None 빼주는 것으로 처리해주면, 다 없어진다.

 

좀더 찾아보니 이렇게도 가능한데, 내머리로는 아직 생각하기 힘든듯

sample_list = ['', 'a', '', 'abc', 'qdsf']
sample_list = [v for v in sample_list if v]
sample_list # ['a', 'abc', 'qdsf']

 

 

2. Python List와 String

 

문제 상황 : 밑에 사진처럼 결과값이 여러개 받을떄, js에서 배열로 넘겨줘서 방아서 True, False를 판단해주려고 했다.

그래서 Postman에서 어떻게 보내야 되나 고민하고 있었는데, 그냥 String -> List만 할줄알면되었다.

 

그것도 모르고 문제해결할때 1,0,0,0,0,0 이렇게 보내주고, split으로 잘라서 list를 만들었다.

 

해결 :

str = 'Hello world!'
list = list(str)

print(str)
print(list)

#결과값 
Hello world!
['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!']

만약에 숫자로 바꿔주려면 list(map(int, list(str)))를 넣어주면된다.

 

3. Git 협업

 

얼마전에 이런 상황이 있었다.

1. 내가 먼저 main에서 branch A를 파서 코드를 짜고 있었다.

2. 다른 팀원이 main을 수정했다.

3. 나는 그걸 모르고, branch A를 merge하였다.

4. 어떻게 된지는 모르겠는데 main이 두개가 되고, 이전에 팀원이 수정한 main, branch A가 나온 main 두개가 되었다.

 

이런 경우는 어떻게 해야될까?

 

git pull로 main을 계속 업데이트 해줘야한다.

아니면 

git reset --hard origin/main --> main으로 모든 파일을 하드리셋한다.

python *args

 

여러개의 인자를 함수로 받을 때 사용

*args라고 받아도 되고 앞에 *만 붙이면 어떤 단어든 가능하다.

 

def testcode(*args):
	for i in args:
    	print(i[0])
 
 testcode("abc", "cde")

*args를 인자로 받으면 리스트를 인자로 받은 것처럼 사용할 수 있음

 

참고

https://3months.tistory.com/347

https://brunch.co.kr/@princox/180

 

 

python에서 자료형 convert 함수

def convert(data, convertType, default=None, min_len=None, max_len=None):
    try:
        result = convertType(data)
        cmp_val = result if convertType in (int, float) else len(result)

        if ((min_len is not None and cmp_val < min_len) or
                (max_len is not None and max_len < cmp_val)):
            result = default
        return result
    except:
        return default

data의 값을 convertType 자료형으로 변경하고, default와 최솟값, 최댓값을 설정할 수 있는 함수

 

 

django 세팅

 

프로젝트 생성

django-admin startproject myproject(프로젝트 이름)

- myproject만 변경해주면 됨

 

앱폴더 생성 (manage.py가 있는 폴더에서 실행)

python manage.py startapp myapp(앱 이름)

-myapp만 원하는 값으로 변경해주면 됨

 

참고 :

https://seongonion.tistory.com/58

+ Recent posts