commrtr
parent
a7eb835b98
commit
163d107250
@ -0,0 +1,330 @@
|
||||
package com.rehome.serialportcommjava.config;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.function.*;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupport;
|
||||
import org.hibernate.dialect.pagination.AbstractLimitHandler;
|
||||
import org.hibernate.dialect.pagination.LimitHandler;
|
||||
import org.hibernate.dialect.pagination.LimitHelper;
|
||||
import org.hibernate.dialect.unique.DefaultUniqueDelegate;
|
||||
import org.hibernate.dialect.unique.UniqueDelegate;
|
||||
import org.hibernate.engine.spi.RowSelection;
|
||||
import org.hibernate.exception.DataException;
|
||||
import org.hibernate.exception.JDBCConnectionException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
public class SQLiteDialect extends Dialect {
|
||||
private final UniqueDelegate uniqueDelegate;
|
||||
|
||||
public SQLiteDialect() {
|
||||
registerColumnType(Types.BIT, "boolean");
|
||||
registerColumnType(Types.FLOAT, "float");
|
||||
registerColumnType(Types.DOUBLE, "double");
|
||||
registerColumnType(Types.DECIMAL, "decimal");
|
||||
registerColumnType(Types.CHAR, "char");
|
||||
registerColumnType(Types.LONGVARCHAR, "longvarchar");
|
||||
registerColumnType(Types.TIMESTAMP, "datetime");
|
||||
registerColumnType(Types.BINARY, "blob");
|
||||
registerColumnType(Types.VARBINARY, "blob");
|
||||
registerColumnType(Types.LONGVARBINARY, "blob");
|
||||
|
||||
registerFunction("concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", ""));
|
||||
registerFunction("mod", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1 % ?2"));
|
||||
registerFunction("quote", new StandardSQLFunction("quote", StandardBasicTypes.STRING));
|
||||
registerFunction("random", new NoArgSQLFunction("random", StandardBasicTypes.INTEGER));
|
||||
registerFunction("round", new StandardSQLFunction("round"));
|
||||
registerFunction("substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING));
|
||||
registerFunction("trim", new AbstractAnsiTrimEmulationFunction() {
|
||||
@Override
|
||||
protected SQLFunction resolveBothSpaceTrimFunction() {
|
||||
return new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?1)");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SQLFunction resolveBothSpaceTrimFromFunction() {
|
||||
return new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?2)");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SQLFunction resolveLeadingSpaceTrimFunction() {
|
||||
return new SQLFunctionTemplate(StandardBasicTypes.STRING, "ltrim(?1)");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SQLFunction resolveTrailingSpaceTrimFunction() {
|
||||
return new SQLFunctionTemplate(StandardBasicTypes.STRING, "rtrim(?1)");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SQLFunction resolveBothTrimFunction() {
|
||||
return new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?1, ?2)");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SQLFunction resolveLeadingTrimFunction() {
|
||||
return new SQLFunctionTemplate(StandardBasicTypes.STRING, "ltrim(?1, ?2)");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SQLFunction resolveTrailingTrimFunction() {
|
||||
return new SQLFunctionTemplate(StandardBasicTypes.STRING, "rtrim(?1, ?2)");
|
||||
}
|
||||
});
|
||||
uniqueDelegate = new SQLiteUniqueDelegate(this);
|
||||
}
|
||||
|
||||
// database type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/*@Override
|
||||
public String getCastTypeName(int code) {
|
||||
// http://sqlite.org/lang_expr.html#castexpr
|
||||
return super.getCastTypeName( code );
|
||||
}*/
|
||||
|
||||
// IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
private static final SQLiteDialectIdentityColumnSupport IDENTITY_COLUMN_SUPPORT = new
|
||||
SQLiteDialectIdentityColumnSupport(new SQLiteDialect());
|
||||
|
||||
|
||||
@Override
|
||||
public IdentityColumnSupport getIdentityColumnSupport() {
|
||||
return IDENTITY_COLUMN_SUPPORT;
|
||||
}
|
||||
|
||||
// limit/offset support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
private static final AbstractLimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
|
||||
@Override
|
||||
public String processSql(String sql, RowSelection selection) {
|
||||
final boolean hasOffset = LimitHelper.hasFirstRow(selection);
|
||||
return sql + (hasOffset ? " limit ? offset ?" : " limit ?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLimit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bindLimitParametersInReverseOrder() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public LimitHandler getLimitHandler() {
|
||||
return LIMIT_HANDLER;
|
||||
}
|
||||
|
||||
// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@Override
|
||||
public boolean supportsLockTimeouts() {
|
||||
// may be http://sqlite.org/c3ref/db_mutex.html ?
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getForUpdateString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOuterJoinForUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsCurrentTimestampSelection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrentTimestampSelectStringCallable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentTimestampSelectString() {
|
||||
return "select current_timestamp";
|
||||
}
|
||||
|
||||
// SQLException support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
private static final int SQLITE_BUSY = 5;
|
||||
private static final int SQLITE_LOCKED = 6;
|
||||
private static final int SQLITE_IOERR = 10;
|
||||
private static final int SQLITE_CORRUPT = 11;
|
||||
private static final int SQLITE_NOTFOUND = 12;
|
||||
private static final int SQLITE_FULL = 13;
|
||||
private static final int SQLITE_CANTOPEN = 14;
|
||||
private static final int SQLITE_PROTOCOL = 15;
|
||||
private static final int SQLITE_TOOBIG = 18;
|
||||
private static final int SQLITE_CONSTRAINT = 19;
|
||||
private static final int SQLITE_MISMATCH = 20;
|
||||
private static final int SQLITE_NOTADB = 26;
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return new SQLExceptionConversionDelegate() {
|
||||
@Override
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode(sqlException) & 0xFF;
|
||||
if (errorCode == SQLITE_TOOBIG || errorCode == SQLITE_MISMATCH) {
|
||||
return new DataException(message, sqlException, sql);
|
||||
} else if (errorCode == SQLITE_BUSY || errorCode == SQLITE_LOCKED) {
|
||||
return new LockAcquisitionException(message, sqlException, sql);
|
||||
} else if ((errorCode >= SQLITE_IOERR && errorCode <= SQLITE_PROTOCOL) || errorCode == SQLITE_NOTADB) {
|
||||
return new JDBCConnectionException(message, sqlException, sql);
|
||||
}
|
||||
|
||||
// returning null allows other delegates to operate
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
|
||||
return EXTRACTER;
|
||||
}
|
||||
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode(sqle) & 0xFF;
|
||||
if (errorCode == SQLITE_CONSTRAINT) {
|
||||
return extractUsingTemplate("constraint ", " failed", sqle.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// union subclass support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean supportsUnionAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public boolean canCreateSchema() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAlterTable() {
|
||||
// As specified in NHibernate dialect
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dropConstraints() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean qualifyIndexName() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddColumnString() {
|
||||
return "add column";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDropForeignKeyString() {
|
||||
throw new UnsupportedOperationException("No drop foreign key syntax supported by SQLiteDialect");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddForeignKeyConstraintString(String constraintName,
|
||||
String[] foreignKey, String referencedTable, String[] primaryKey,
|
||||
boolean referencesPrimaryKey) {
|
||||
throw new UnsupportedOperationException("No add foreign key syntax supported by SQLiteDialect");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAddPrimaryKeyConstraintString(String constraintName) {
|
||||
throw new UnsupportedOperationException("No add primary key syntax supported by SQLiteDialect");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCommentOn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIfExistsBeforeTableName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* not case insensitive for unicode characters by default (ICU extension needed)
|
||||
public boolean supportsCaseInsensitiveLike() {
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean doesReadCommittedCauseWritersToBlockReaders() {
|
||||
// TODO Validate (WAL mode...)
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesRepeatableReadCauseReadersToBlockWriters() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTupleDistinctCounts() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInExpressionCountLimit() {
|
||||
// Compile/runtime time option: http://sqlite.org/limits.html#max_variable_number
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueDelegate getUniqueDelegate() {
|
||||
return uniqueDelegate;
|
||||
}
|
||||
|
||||
private static class SQLiteUniqueDelegate extends DefaultUniqueDelegate {
|
||||
public SQLiteUniqueDelegate(Dialect dialect) {
|
||||
super(dialect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnDefinitionUniquenessFragment(Column column) {
|
||||
return " unique";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectGUIDString() {
|
||||
return "select hex(randomblob(16))";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScrollMode defaultScrollMode() {
|
||||
return ScrollMode.FORWARD_ONLY;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.rehome.serialportcommjava.config;
|
||||
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.identity.IdentityColumnSupportImpl;
|
||||
|
||||
|
||||
public class SQLiteDialectIdentityColumnSupport extends IdentityColumnSupportImpl {
|
||||
public SQLiteDialectIdentityColumnSupport(Dialect dialect) {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsIdentityColumns() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
public boolean supportsInsertSelectIdentity() {
|
||||
return true; // As specified in NHibernate dialect
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean hasDataTypeInIdentityColumn() {
|
||||
// As specified in NHibernate dialect
|
||||
// FIXME true
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
public String appendIdentitySelectToInsert(String insertString) {
|
||||
return new StringBuffer(insertString.length()+30). // As specified in NHibernate dialect
|
||||
append(insertString).
|
||||
append("; ").append(getIdentitySelectString()).
|
||||
toString();
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public String getIdentitySelectString(String table, String column, int type) {
|
||||
return "select last_insert_rowid()";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentityColumnString(int type) {
|
||||
// return "integer primary key autoincrement";
|
||||
// FIXME "autoincrement"
|
||||
return "integer";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.rehome.serialportcommjava.config;
|
||||
|
||||
|
||||
|
||||
import org.hibernate.boot.MetadataBuilder;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.spi.MetadataBuilderInitializer;
|
||||
import org.hibernate.engine.jdbc.dialect.internal.DialectResolverSet;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DialectResolver;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* SQLite工具
|
||||
*/
|
||||
public class SQLiteMetadataBuilderInitializer implements MetadataBuilderInitializer {
|
||||
|
||||
private final static Logger logger = Logger.getLogger(SQLiteMetadataBuilderInitializer.class);
|
||||
|
||||
@Override
|
||||
public void contribute(MetadataBuilder metadataBuilder, StandardServiceRegistry serviceRegistry) {
|
||||
DialectResolver dialectResolver = serviceRegistry.getService(DialectResolver.class);
|
||||
|
||||
if (!(dialectResolver instanceof DialectResolverSet)) {
|
||||
logger.warnf("DialectResolver '%s' is not an instance of DialectResolverSet, not registering SQLiteDialect",
|
||||
dialectResolver);
|
||||
return;
|
||||
}
|
||||
|
||||
((DialectResolverSet) dialectResolver).addResolver(resolver);
|
||||
}
|
||||
|
||||
static private final SQLiteDialect dialect = new SQLiteDialect();
|
||||
|
||||
static private final DialectResolver resolver = (DialectResolver) info -> {
|
||||
if (info.getDatabaseName().equals("SQLite")) {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
spring.application.name=SerialPortCommJava
|
||||
@ -0,0 +1,26 @@
|
||||
server:
|
||||
port: 8070
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:sqlite:SerialPortCommJava.db
|
||||
#url: jdbc:sqlite:/Users/admin/springboot-sqlite-jpa-temperature.db
|
||||
#url: jdbc:sqlite:/root/temperature/springboot-sqlite-jpa-temperature.db
|
||||
driver-class-name: org.sqlite.JDBC
|
||||
username:
|
||||
password:
|
||||
jpa:
|
||||
database-platform: com.rehome.serialportcommjava.config.SQLiteDialect
|
||||
show-sql: true # ???????? SQL ?????
|
||||
open-in-view: true
|
||||
hibernate:
|
||||
ddl-auto: update # ?????create ???update?????????????
|
||||
servlet:
|
||||
multipart:
|
||||
# ?? multipart ????
|
||||
enabled: true
|
||||
# ?????????
|
||||
file-size-threshold: 2KB
|
||||
# ??????
|
||||
max-file-size: 200MB
|
||||
# ??????
|
||||
max-request-size: 215MB
|
||||
Loading…
Reference in New Issue