Mirai Hibernate 前置插件,用于 Hibernate ORM 框架的初始化,历史消息持久化
-
Mirai Hibernate Plugin
Mirai Hibernate 前置插件
Mirai Console 的前置插件,用于 Hibernate ORM 框架的初始化
插件自带聊天记录器 MiraiHibernateRecorder,
会记录群聊/私聊
的内容到数据库方便其他插件使用,默认是h2database
数据库(since2.2.0+
)
数据库配置在config/xyz.cssxsh.mirai.plugin.mirai-hibernate-plugin/hibernate.properties
2.2.0
之前的版本的 默认数据库 为sqlite
, 你可以直接删掉hibernate.properties
, 让其重新生成h2database
配置数据库支持
本插件打包了以下版本的数据库驱动和连接池
mysql:mysql-connector-java:8.0.29
org.xerial:sqlite-jdbc:3.36.0.3
org.postgresql:postgresql:42.3.5
com.h2database:h2:2.1.212
com.zaxxer:HikariCP:5.0.1
需要其他数据库驱动支持请将 数据库驱动Jar包 放到
plugins
目录中一同被mirai-console
加载在插件项目中引用
repositories { mavenCentral() } dependencies { compileOnly("xyz.cssxsh.mirai:mirai-hibernate-plugin:${version}") }
一些方法和类说明
-
MiraiHibernateConfiguration
配置的,对应于JvmPlugin
的SessionFactory
默认将会读取(生成)在configFolder
目录下的hibernate.properties
作为配置文件
并且自动扫描加载JvmPlugin
所在类包下的被javax.persistence.Entity
标记的实体类 -
MiraiHibernateRecorder
是本插件自带的消息记录器,通过对MessageEvent
和MessagePostSendEvent
记录,保存消息历史到数据库 -
CriteriaBuilder.rand
MiraiHibernateConfiguration
中会对 Sqlite 的random
进行别名注册为rand
统一SQL语句的中的随机函数名
示例代码
安装
MCL 指令安装
./mcl --update-package xyz.cssxsh.mirai:mirai-hibernate-plugin --channel stable --type plugin
手动安装
- 运行 Mirai Console 生成
plugins
文件夹 - 从 Releases 下载
jar
并将其放入plugins
文件夹中
-
cssxsh
-
版本:2.2.3
配置文件:hibernate.connection.url=jdbc:mysql://localhost:3306/hibernate?autoReconnect=true hibernate.connection.driver_class=com.mysql.cj.jdbc.Driver hibernate.connection.CharSet=utf8mb4 hibernate.connection.useUnicode=true hibernate.connection.username=hibernate hibernate.connection.password=hibernate hibernate.dialect=org.hibernate.dialect.MySQL5Dialect hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider hibernate.hbm2ddl.auto=none hibernate-connection-autocommit=true hibernate.connection.show_sql=false hibernate.autoReconnect=true
错误日志:
2022-05-29 13:27:31 V/Bot.1234567890: [五字群名(123456798)] 昵称(123456789) -> [mirai:image:{8A9EA3CD-6F62-8D71-464A-B1311DCC7F98}.jpg] 2022-05-29 13:27:31 W/stderr: ERROR SqlExceptionHelper Table 'hibernate.message_record' doesn't exist 2022-05-29 13:27:31 W/stderr: ERROR SqlExceptionHelper Table 'hibernate.face_record' doesn't exist 2022-05-29 13:27:31 W/mirai-hibernate-plugin: SQLException in Recorder java.sql.SQLSyntaxErrorException: Table 'hibernate.message_record' doesn't exist at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009) at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320) at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994) at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:58) at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:43) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3279) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3885) at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84) at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645) at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282) at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263) at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317) at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330) at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287) at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123) at org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:271) at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:243) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:175) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:829) at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:816) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder$merge$1.invoke(MiraiHibernateRecorder.kt:29) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder$merge$1.invoke(MiraiHibernateRecorder.kt:29) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateUtilsKt.useSession(MiraiHibernateUtils.kt:28) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder.merge(MiraiHibernateRecorder.kt:29) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder.access$merge(MiraiHibernateRecorder.kt:27) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder$record$1.invokeSuspend(MiraiHibernateRecorder.kt:35) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) 2022-05-29 13:27:31 W/mirai-hibernate-plugin: SQLException in Recorder java.sql.SQLSyntaxErrorException: Table 'hibernate.face_record' doesn't exist at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:972) at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) at org.hibernate.loader.Loader.getResultSet(Loader.java:2322) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2075) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2037) at org.hibernate.loader.Loader.doQuery(Loader.java:956) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:327) at org.hibernate.loader.Loader.loadEntity(Loader.java:2440) at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:77) at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:61) at org.hibernate.persister.entity.AbstractEntityPersister.doLoad(AbstractEntityPersister.java:4521) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4511) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:571) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:539) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:208) at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:327) at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:108) at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:74) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118) at org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1231) at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1220) at org.hibernate.internal.SessionImpl.access$2100(SessionImpl.java:202) at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.doLoad(SessionImpl.java:2835) at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.lambda$load$1(SessionImpl.java:2812) at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.perform(SessionImpl.java:2768) at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2812) at org.hibernate.internal.SessionImpl.get(SessionImpl.java:1024) at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:306) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:172) at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:70) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:829) at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:816) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder$merge$1.invoke(MiraiHibernateRecorder.kt:29) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder$merge$1.invoke(MiraiHibernateRecorder.kt:29) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateUtilsKt.useSession(MiraiHibernateUtils.kt:28) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder.merge(MiraiHibernateRecorder.kt:29) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder.access$merge(MiraiHibernateRecorder.kt:27) at mirai-hibernate-plugin-2.2.3.jar//xyz.cssxsh.mirai.hibernate.MiraiHibernateRecorder$record$2.invokeSuspend(MiraiHibernateRecorder.kt:40) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
从报错来看是数据库中没有这两个表,手动试了下,是能够正常创建表的……
以前一直用的sqlite,升级到最新版之后每次启动都提示sqlite不支持多线程什么的,就想着干脆换成mysql -
@SnowMoonSS 在 Mirai Hibernate 前置插件,用于 Hibernate ORM 框架的初始化,历史消息持久化 中说:
hibernate.hbm2ddl.auto=none
改成
hibernate.hbm2ddl.auto=update
这样才会在没有表的时候创建表
推荐创建完表之后 改回none
-
@cssxsh 哦哦,感谢!
-
@cssxsh 直接下周release的话怎么配置自己的mysql url密码等信息哈
-
我的想法是下载源码,然后新建\src\main\resources\hibernate.properties文件,copy上面的配置信息,改url等为自己的?在打包新的jar,复制粘贴到plugins文件下?
-
@hellostronger 在 Mirai Hibernate 前置插件,用于 Hibernate ORM 框架的初始化,历史消息持久化 中说:
\src\main\resources\hibernate.properties
hibernate.properties 保存在
mcl\config\xyz.cssxsh.mirai.plugin.mirai-hibernate-plugin
你直接建好放进去,或者生成之后修改 -
你好,我下在的源码好像没这个路径哈
-
解决了,不是项目代码目录,是D:\Program Files\mirai-compose\config\xyz.cssxsh.mirai.plugin.mirai-hibernate-plugin,我用可视化界面,是那个软件下的某个目录,谢谢大佬的开源代码,牛
-
好奇就是图片那种,我要还原的话,在数据库里面持久化是{"type":"Image","imageId":"{CB648044-6933-13B4-7237-EDB07190E978}.jpg"}这样的,感觉还原不回去
-
cssxsh