From 5c29de08c91b2b40f5e6915f309d633babd89feb Mon Sep 17 00:00:00 2001 From: hwf453 Date: Tue, 17 Sep 2024 20:25:04 +0800 Subject: [PATCH] change db to sqlite --- .idea/workspace.xml | 211 +++-------- pom.xml | 9 +- .../AdminClientTemperatureApplication.java | 13 +- .../config/SQLiteDialect.java | 330 ++++++++++++++++++ .../SQLiteDialectIdentityColumnSupport.java | 51 +++ .../SQLiteMetadataBuilderInitializer.java | 41 +++ src/main/resources/application.yml | 17 +- 7 files changed, 476 insertions(+), 196 deletions(-) create mode 100644 src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialect.java create mode 100644 src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialectIdentityColumnSupport.java create mode 100644 src/main/java/com/rehome/mqttclienttemperature/config/SQLiteMetadataBuilderInitializer.java diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 9bf1f06..745225c 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,131 +5,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + @@ -139,23 +34,36 @@ - + { + "associatedIndex": 0 +} - { + "keyToString": { + "ASKED_ADD_EXTERNAL_FILES": "true", + "RequestMappingsPanelOrder0": "0", + "RequestMappingsPanelOrder1": "1", + "RequestMappingsPanelWidth0": "75", + "RequestMappingsPanelWidth1": "75", + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true", + "WebServerToolWindowFactoryState": "false", + "last_opened_file_path": "/Users/admin/IdeaProjects/admin-client-temperature", + "node.js.detected.package.eslint": "true", + "node.js.detected.package.tslint": "true", + "node.js.selected.package.eslint": "(autodetect)", + "node.js.selected.package.tslint": "(autodetect)", + "project.structure.last.edited": "Project", + "project.structure.proportion": "0.0", + "project.structure.side.proportion": "0.0", + "settings.editor.selected.configurable": "reference.projectsettings.compiler.javacompiler", + "vue.rearranger.settings.migration": "true" } -}]]> +} @@ -189,48 +97,13 @@ + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/pom.xml b/pom.xml index a3aef7f..0d00219 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ com.rehome admin-client-temperature 1.0.0 - war + jar admin-client-temperature admin-client-temperature @@ -32,10 +32,11 @@ mybatis-spring-boot-starter 2.1.4 + - mysql - mysql-connector-java - runtime + org.xerial + sqlite-jdbc + 3.45.1.0 org.springframework.boot diff --git a/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java b/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java index d7d7027..f073db6 100644 --- a/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java +++ b/src/main/java/com/rehome/mqttclienttemperature/AdminClientTemperatureApplication.java @@ -20,7 +20,7 @@ import java.util.Map; @EnableJpaAuditing @EnableScheduling @SpringBootApplication -public class AdminClientTemperatureApplication extends SpringBootServletInitializer implements CommandLineRunner, ApplicationContextAware { +public class AdminClientTemperatureApplication implements CommandLineRunner, ApplicationContextAware { /** * 获取Spring框架的上下文 @@ -36,17 +36,6 @@ public class AdminClientTemperatureApplication extends SpringBootServletInitiali SpringApplication.run(AdminClientTemperatureApplication.class, args); } - /** - * @date 2021-05-18 09:20 - * @description: 容器配置,springboot打war包布署必须添加这个配置 为了打包springboot项目 - * @Param: SpringApplicationBuilder - */ - @Override - protected SpringApplicationBuilder configure( - SpringApplicationBuilder builder) { - return builder.sources(AdminClientTemperatureApplication.class); - } - /** * 调用 applicationContext(不能在main中使用,main是static的,不能调用) * @param args diff --git a/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialect.java b/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialect.java new file mode 100644 index 0000000..08bde1a --- /dev/null +++ b/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialect.java @@ -0,0 +1,330 @@ +package com.rehome.mqttclienttemperature.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; + } +} \ No newline at end of file diff --git a/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialectIdentityColumnSupport.java b/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialectIdentityColumnSupport.java new file mode 100644 index 0000000..c0b399e --- /dev/null +++ b/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteDialectIdentityColumnSupport.java @@ -0,0 +1,51 @@ +package com.rehome.mqttclienttemperature.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"; + } +} \ No newline at end of file diff --git a/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteMetadataBuilderInitializer.java b/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteMetadataBuilderInitializer.java new file mode 100644 index 0000000..02661c0 --- /dev/null +++ b/src/main/java/com/rehome/mqttclienttemperature/config/SQLiteMetadataBuilderInitializer.java @@ -0,0 +1,41 @@ +package com.rehome.mqttclienttemperature.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; + }; +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 53f29af..126b9f0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,18 +2,13 @@ server: port: 8873 spring: datasource: - type: com.zaxxer.hikari.HikariDataSource -# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver -# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=appserver;encrypt=false; -# username: sa -# password: Skyinno251, - url: jdbc:mysql://127.0.0.1:3306/appserver?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true - driverClassName: com.mysql.cj.jdbc.Driver #com.mysql.cj.jdbc.Driver com.mysql.jdbc.Driver - #url: jdbc:mysql://192.168.2.18:3306/appserver?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true - username: root - password: Skyinno251, + #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: mysql # 配置 DBMS 类型 + database-platform: com.rehome.mqttclienttemperature.config.SQLiteDialect show-sql: true # 配置是否将执行的 SQL 输出到日志 open-in-view: true hibernate: