1. SQLite란?
공식 사이트 : https://sqlite.org/index.html
SQLite는 클라이언트 응용 프로그램에 임베디드 되어 동작하는 DBMS 소프트웨어로서 퍼블릭 도메인 오픈 소스 소프트웨어로 android, iOS, macOS에 기본적으로 포함되어 있습니다.
그래서 SQL에서 하는 기능이 SQLite에선 '경량화'의 이유로 제한되는 경우가 많습니다. 예를 들자면, 프로토콜 조작을 통해 네트워크에 접근할 수는 있지만, 동시 접근은 제한됩니다. 또한 복잡하거나 큰 데이터를 보관하는 데에는 적절하지 않습니다.
또한 데이터베이스 이름 그대로 'lite'이기 때문에 성능은 기대를 하지 않는 것이 좋고, 한 번에 한 명의 사용자만이 데이터베이스를 사용할 수 있어서 멀티 유저를 지원하려면 proxy 계층을 도입해야 합니다.
2. spring boot jpa에서 SQLite 사용하는 방법
2.1. dependency 설정
여기에서 항상 최신 버전을 확인 하실 수 있습니다.
2.1.1. maven
<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.39.3.0</version>
</dependency>
2.1.2 gradle
// https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc
implementation 'org.xerial:sqlite-jdbc:3.39.3.0'
2.2. Dialect 추가
JPA의 구현체인 hibernate에는 Dialect를 이용해서 다양한 DB의 sql 문법의 차이를 개발자가 신경 쓰지 않도록 변환해줍니다. 그런데 hibernate는 SQLite를 위한 Dialect가 없습니다.
그래서 SQLite를 위한 Dialect를 별도로 추가해야합니다.
import java.sql.Types;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.dialect.identity.IdentityColumnSupport;
import org.hibernate.type.StringType;
public class SQLDialect extends Dialect {
public SQLDialect() {
registerColumnType(Types.BIT, "integer");
registerColumnType(Types.TINYINT, "tinyint");
registerColumnType(Types.SMALLINT, "smallint");
registerColumnType(Types.INTEGER, "integer");
registerColumnType(Types.BIGINT, "bigint");
registerColumnType(Types.FLOAT, "float");
registerColumnType(Types.REAL, "real");
registerColumnType(Types.DOUBLE, "double");
registerColumnType(Types.NUMERIC, "numeric");
registerColumnType(Types.DECIMAL, "decimal");
registerColumnType(Types.CHAR, "char");
registerColumnType(Types.VARCHAR, "varchar");
registerColumnType(Types.LONGVARCHAR, "longvarchar");
registerColumnType(Types.DATE, "date");
registerColumnType(Types.TIME, "time");
registerColumnType(Types.TIMESTAMP, "timestamp");
registerColumnType(Types.BINARY, "blob");
registerColumnType(Types.VARBINARY, "blob");
registerColumnType(Types.LONGVARBINARY, "blob");
// registerColumnType(Types.NULL, "null");
registerColumnType(Types.BLOB, "blob");
registerColumnType(Types.CLOB, "clob");
registerColumnType(Types.BOOLEAN, "integer");
registerFunction("concat",
new VarArgsSQLFunction(StringType.INSTANCE, "", "||", ""));
registerFunction("mod",
new SQLFunctionTemplate(StringType.INSTANCE, "?1 % ?2"));
registerFunction("substr",
new StandardSQLFunction("substr", StringType.INSTANCE));
registerFunction("substring",
new StandardSQLFunction("substr", StringType.INSTANCE));
}
public boolean supportsIdentityColumns() {
return true;
}
public boolean hasDataTypeInIdentityColumn() {
return false; // As specify in NHibernate dialect
}
@Override
public IdentityColumnSupport getIdentityColumnSupport() {
return new SQLiteIdentityColumnSupport();
}
public String getIdentityColumnString() {
// return "integer primary key autoincrement";
return "integer";
}
public String getIdentitySelectString() {
return "select last_insert_rowid()";
}
public boolean supportsLimit() {
return true;
}
protected String getLimitString(String query, boolean hasOffset) {
return new StringBuffer(query.length() + 20).append(query)
.append(hasOffset ? " limit ?, ?" : " limit ?")
.toString();
}
public boolean supportsTemporaryTables() {
return true;
}
public String getCreateTemporaryTableString() {
return "create temporary table if not exists";
}
public boolean dropTemporaryTableAfterUse() {
return false;
}
public boolean supportsCurrentTimestampSelection() {
return true;
}
public boolean isCurrentTimestampSelectStringCallable() {
return false;
}
public String getCurrentTimestampSelectString() {
return "select current_timestamp";
}
public boolean supportsUnionAll() {
return true;
}
public boolean hasAlterTable() {
return false; // As specify in NHibernate dialect
}
public boolean dropConstraints() {
return false;
}
public String getAddColumnString() {
return "add column";
}
public String getForUpdateString() {
return "";
}
public boolean supportsOuterJoinForUpdate() {
return false;
}
public boolean supportsIfExistsBeforeTableName() {
return true;
}
public boolean supportsCascadeDelete() {
return false;
}
@Override
public String getDropForeignKeyString() {
return "";
}
@Override
public String getAddForeignKeyConstraintString(String cn,
String[] fk, String t, String[] pk, boolean rpk) {
return "";
}
@Override
public String getAddPrimaryKeyConstraintString(String constraintName) {
return "";
}
}
2.3. DB 설정 추가
application.application에 다음과 같이 옵션을 설정합니다.
# SQLite Dialect 지정
spring.jpa.database-platform=com.test.config.SQLDialect
spring.datasource.url=jdbc:sqlite:mydb.db
spring.datasource.driver-class-name=org.sqlite.JDBC
3. Reference
SQLite - 나무위키
이 저작물은 CC BY-NC-SA 2.0 KR에 따라 이용할 수 있습니다. (단, 라이선스가 명시된 일부 문서 및 삽화 제외) 기여하신 문서의 저작권은 각 기여자에게 있으며, 각 기여자는 기여하신 부분의 저작권
namu.wiki
[spring] spring boot에서 SQLite를 JPA로 사용하기
1. 개요 spring data jpa를 이용하는 Spring boot 프로젝트에서 SQLite를 사용하는 방법에 대해 작성합니다. 2. SQLite란? 공식사이트 : https://sqlite.org/index.html DB-engines(H2 vs SQLite) : https://db-e..
skagh.tistory.com
https://www.baeldung.com/spring-boot-sqlite
Spring Boot With SQLite | Baeldung
Configure a Spring Boot application with SQLite persistence
www.baeldung.com
'back end > java' 카테고리의 다른 글
spring pageable를 이용한 페이징 처리 (0) | 2022.10.13 |
---|---|
[Spring boot] Restful API 쉽게 호출하는 방법 by using RestTemplate (2) | 2022.10.11 |
Java Bean Validation 사용방법 - ControllerAdvice (0) | 2022.10.03 |
java에서 천단위 쉼표, 소수점 반올림 하는 방법 (0) | 2022.09.05 |
Mac OS에서 Openjdk 11 설치하는 방법(adoptopenjdk11) (0) | 2022.08.13 |