1. 설정

그래이들

implementation 'org.springframework.boot:spring-boot-starter-cache'

config 설정

@Configuration
@EnableCaching
public class CacheConfig {
}

 

2. 사용

캐시 할 내용에 @Cacheable

캐시 삭제시 @CacheEvict

캐시 업데이트 시 @Cacheput

 

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class CacheService {

    private final CacheManager cacheManager;

    public CacheService(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    @Cacheable(value = "random", key = "#id")
    public String cacheRandom( String id) {
        Random random = new Random();
        return id + "_" + random.nextInt(100);
    }

    @CacheEvict(value = "random", key = "#id")
    public void cacheRandomEvict(String id) {

    }

    public void cacheAll() {
        Collection<String> cacheNames = cacheManager.getCacheNames();
        for (String cacheName : cacheNames) {
            System.out.println("cacheName = " + cacheName);
        }
        Cache random = cacheManager.getCache("random");
        System.out.println("random = " + random);

        for (String cacheName : cacheNames) {
            Cache cache = cacheManager.getCache(cacheName);

            if (cache != null) {
                ConcurrentHashMap nativeCache = (ConcurrentHashMap) cache.getNativeCache();
                System.out.println("nativeCache = " + nativeCache);
                System.out.println("nativeCache type = " + nativeCache.getClass().getName() );
                ConcurrentHashMap cacheMap = (ConcurrentHashMap) nativeCache;
                cacheMap.forEach((strKey, strValue)->{
                    System.out.println( strKey +" : "+ strValue );
                });
            }
        }

    }
}

CacheManger (구현체 ConcurrentMapCacheManager )를 통해서 캐시 이름 목록을 가져오고

다시 이름으로 Cache 를 가져오고

가져온 캐시를 ConcurrentHashMap으로 변환 후 순회한다.

1) 포트 사용 에러

 

오류: 에이전트에 예외사항이 발생했습니다. : java.rmi.server.ExportException: Port already in use: 35199; nested exception is: 
java.net.BindException: Address already in use: JVM_Bind

 

실행 중지를 하지 않고 다시 실행하는 경우 위와 같은 에러가 종종 발생한다.

 

사용하려는 포트가 이미 사용중이라는 말로 사용중인 포트의 프로세스아이디를 찾아서 해당 프로세스를 죽여줘야 한다.

 

윈도우키+r -> cmd -> netstat 명령어로 사용중인 포트의 프로세스아이디를 찾아 킬하면 됩니다.

 

8080 사용 프로세스 검색 및 프로세스 종료시키기

 

cmd > netstat -ano | findstr 8080

실행을 하면 8080포트를 사용하는 프로세스 목록이 나옵니다.

가장 오른쪽의 프로세스 아이디를 킬해주면 됩니다.

cmd > taskkill /F /PID 8964

 

리소스 모니터에서 해당 프로세스 종료하기

작업관리자의 리소스모니터에서 해당 프로세스를 종료할 수 도 있습니다.

SpringBoot + Thymeleaf 로 작업 시 

 

html 변경이 바로 적용되지 않는 문제가 있다.

html 부분이나 스크립트 부분이나 고치면서 계속 확인 해야 하는 작업이 필요한 경우 

재실행하는거는 여간 귀찮은 일이 아니다.

 

applicatoin.properties에 아래와 같이 설정을 하면 바로 변경된 html을 확인 할 수 있다.

 

spring.thymeleaf.cache=false
spring.thymeleaf.prefix=file:src/main/resources/templates/

 

인텔리제이 Community 버전도 잘 된다.

 

 

 

tomcat을 로컬에 설치해서 여러가지 버전별로 테스트를 해볼때가 있다.

 

요즘은 거의 SpringBoot 라서 직접 톰캣을 올리는 경우는 거의 없지만

레거시 프로젝트 유지보수를 위해서는 어쩔수 없이 플젝 자바 버전에 맞는 톰캣을 올리는 수밖에..

 

우선 윈도우에서는 톰캣 폴더의 /bin/ 폴더 아래에 startup.bat 을 실행시키면

같은 폴더에 catalina.bat 을 실행하게 된다. 리눅스 같긴 하지만.

 

catalina.bat 파일의 주석 아래부분에 JAVA_HOME과 JRE_HOME을 설정해 주면 된다.

rem ---------------------------------------------------------------------------

setlocal

set "JAVA_HOME=C:\util\JAVA\jdk-17.0.2"
set "JRE_HOME=C:\util\JAVA\jdk-17.0.2"

set "JAVA_HOME=C:\util\JAVA\jdk-17.0.2"
set "JRE_HOME=C:\util\JAVA\jdk-17.0.2"

 

자바스크립트에서 날짜 관련 핸들링은 항상 어렵다.

 

월단위로 데이터를 검색하는 경우 검색 조건 통제를 위한 자바스크립트로 월단위를 더하는 방식을 알아본다.

 

// 한자리면 0붙이기

function pad(n) {

    return n < 10 ? '0'+n : ''+n

}

// 월 더하기
function addMonth(d, n) {
    d.setMonth(d.getMonth() + n);
    return d.getFullYear() + '/' + pad(d.getMonth()+1) + '/' + pad(d.getDate());    
}

// 실행

console.log(addMonth(new Date('2022/01/01'), 1)); // '2022/02/01'

console.log(addMonth(new Date('2022/01/15'), 1)); // '2022/02/15'

console.log(addMonth(new Date('2022/01/31'), 1)); // '2022/03/03' ??????????????

 

이는 자바스크립트에서 setMonth 함수로 월을 셋팅하면 일은 그대로고 월만 변경 되기 때문에

2022/02/31 이 된다. 2월은 28일 까지 있으므로 자바스크립트 자체에서 2월28일에서 3일을 더해 3월3일이 되는 것이다.

이에 대한 예외 처리를 해줘야 한다.

// 1자리면 0 붙이기

function pad(n) {
    return n < 10 ? '0'+n : ''+n
}

// 윤년인지여부
function isLeapYear(year) {
    return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); 
}

// 해당년월의 말일 구하기
function getLastDate(year, month) {
    return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}

// 월 더하기
function addMonth(d, n) {
    var date = d.getDate();
    d.setDate(1); // 1일로 설정
    d.setMonth(d.getMonth() + n); // 개월수 더하기
    //d.setDate(d.getDate() - 1); 
    return d.getFullYear() + '/' + pad(d.getMonth()+1) + '/' + pad(Math.min(date, getLastDate(d.getYear(), d.getMonth())));    
}
// 실행
console.log(addMonth(new Date('2022/01/01'), 1)); // '2022/02/01'
console.log(addMonth(new Date('2022/01/15'), 1)); // '2022/02/15'

console.log(addMonth(new Date('2022/01/31'), 1)); // '2022/02/28'

제대로 나오는거 같다.

Thymeleaf 적용한 프로젝트에서 title 부분을 전체 똑같이 적용해 달라는 요청이 있었다.

 

Thymeleaf Layout 이 적용된 상태에서

 

layout.html 

의 <title> 부분이 없는 상태였고

각 페이지에서 <title> 값을 설정한 상태였다.

layout.html 에 <title>LAYOUT</title> 을 추가해도

각 페이지의 <title> 이 layout.html 의 title을 대체하게 된다.

 

layout:title-pattern 속성을 이용하면 전체 페이지의 title을 패턴화 할수 있다.

lauout.html 에 아래 태그를 추가하면

<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">MY SITE</title>

$LAYOUT_TITLE - 레이아웃의 타이틀 (구버전 : $DECORATOR_TITLE 는 deprecated 됨)

$CONTENT_TITLE - 각 페이지의 타이틀

 

실제 각 페이지에서는

<title>MY SITE - 각페이지 타이틀</title> 과 같이 된다.

 

해당 요청 사항은

<title layout:title-pattern="$LAYOUT_TITLE">MY SITE</title>

로 해결했다.

 

참고 : title-pattern - Thymeleaf Layout Dialect (ultraq.github.io)

오라클은 삭제 기능을 제공하지 않는다.

친절하지 않기 때문이 아니라 친절하기 때문이다.

만약 unintaller 를 제공한다면.. 누군가 실수로 더블클릭 한번으로 시스템에서 가장 중요한

DB가 날라가는것이다. 

상상만 해도 온몸에 소름이 돋는 일이다.

 

아무튼 학습용으로 로컬에 깔은 오라클 버전을 올리거나 리소스 문제로 삭제는 해야 하니

수동으로 삭제하는 방법은 아래와 같다.

 

1. 서비스에서  Oracle관련 서비스 삭제
윈도우키에서 서비스 입력 또는 윈도우+r에서 services.msc 실행하면 서비스 관리창 나옴.
Oracle 시작하는 모든 서비스 중지

2. 레지스트리 삭제
윈도우키에서 레지스트리 입력 또는 윈도우+r에서 regedit.exe 실행하면 서비스 관리창 나옴.
HKEY_LOCAL_MACHINE/SOFTWARE/Oracle*
HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Oracle*
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Oracle*

3. 컴퓨터 재부팅 후 Oracle 설치 폴더 삭제
C:\Oracle or ORACLE_BASE
C:\Program Files\Oracle
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Oracle - OraDB19Home1
C:\Users Oracle-related folders.

 

이상.

sql developer 에서 문자열에 & 를 입력하여 쿼리를 실행하는데

파라미터 값을 넣으라고 입력창이 뜬다.

set define off 를 실행하면 쿼리가 문자열로 실행된다.

sql > set define off

이후 다시 파라미터를 이용하려면

set define on 을 실행하면 된다.

톰캣 실행 시 

org.apache.catalina.webresources.cache.getresource unable to add the resource at

오류는

 

톰캣에 캐시 메모리가 부족하기 때문에 발생한다.

특별한 설정을 하지 않으면 기본 10240(10MB) 가 디폴트값이다.

 

캐시를 늘려주는 설정을 하면 된다.

톰캣/conf/context.xml 에

<Resources cachingAllowed="true" cacheMaxSize="102400" />

를 추가해 주면 된다.

 

 

스프링부트 로컬에서 여러개 띄울때 세션 끊어지는 것 방지

 

application.properties에

server.session.cookie.name=특정단어

를 추가하면 된다.

+ Recent posts