提交 ebac0706 编写于 作者: 鲸落和鲨掉's avatar 鲸落和鲨掉

策略概率装配

上级 a75995b6
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
...@@ -101,6 +101,11 @@ ...@@ -101,6 +101,11 @@
<artifactId>commons-codec</artifactId> <artifactId>commons-codec</artifactId>
<version>1.15</version> <version>1.15</version>
</dependency> </dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.4</version>
</dependency>
<!-- 工程模块 --> <!-- 工程模块 -->
<dependency> <dependency>
......
24-11-13.22:15:50.764 [main ] ERROR HikariPool - HikariPool-1 - Exception during pool initialization.
java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:906)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:831)
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80)
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67)
at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:337)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:86)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:89)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
at com.sun.proxy.$Proxy79.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80)
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:152)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
at com.sun.proxy.$Proxy82.queryAwardList(Unknown Source)
at cn.bugstack.test.infrastructure.AwardDaoTest.Test_queryAwardList(AwardDaoTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: com.mysql.cj.exceptions.CJException: Unknown database 'big_market'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:129)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:792)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:717)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:685)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:134)
at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:469)
at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:174)
at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1348)
at com.mysql.cj.NativeSession.connect(NativeSession.java:157)
at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:850)
... 71 common frames omitted
24-11-13.22:17:02.261 [main ] ERROR HikariPool - HikariPool-1 - Exception during pool initialization.
java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:906)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:831)
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80)
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67)
at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:337)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:86)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:89)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
at com.sun.proxy.$Proxy79.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80)
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:152)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
at com.sun.proxy.$Proxy82.queryAwardList(Unknown Source)
at cn.bugstack.test.infrastructure.AwardDaoTest.Test_queryAwardList(AwardDaoTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: com.mysql.cj.exceptions.CJException: Unknown database 'big_market'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:129)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:792)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:717)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:685)
at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:134)
at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:469)
at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:174)
at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1348)
at com.mysql.cj.NativeSession.connect(NativeSession.java:157)
at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:850)
... 71 common frames omitted
...@@ -78,6 +78,10 @@ ...@@ -78,6 +78,10 @@
<artifactId>converter-gson</artifactId> <artifactId>converter-gson</artifactId>
<version>2.9.0</version> <version>2.9.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
<!-- 工程模块;启动依赖 trigger->domain, infrastructure--> <!-- 工程模块;启动依赖 trigger->domain, infrastructure-->
<dependency> <dependency>
......
package cn.bugstack.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.BaseCodec;
import org.redisson.client.protocol.Decoder;
import org.redisson.client.protocol.Encoder;
import org.redisson.config.Config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
/**
* @ClassName: RedisClientConfig
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/14 17:40
*/
@Configuration
@EnableConfigurationProperties(RedisClientConfigProperties.class)
public class RedisClientConfig {
@Bean("redissonClient")
public RedissonClient redissonClient(ConfigurableApplicationContext applicationContext, RedisClientConfigProperties properties) {
Config config = new Config();
// 根据需要可以设定编解码器;https://github.com/redisson/redisson/wiki/4.-%E6%95%B0%E6%8D%AE%E5%BA%8F%E5%88%97%E5%8C%96
// config.setCodec(new RedisCodec());
config.useSingleServer()
.setAddress("redis://" + properties.getHost() + ":" + properties.getPort())
// .setPassword(properties.getPassword())
.setConnectionPoolSize(properties.getPoolSize())
.setConnectionMinimumIdleSize(properties.getMinIdleSize())
.setIdleConnectionTimeout(properties.getIdleTimeout())
.setConnectTimeout(properties.getConnectTimeout())
.setRetryAttempts(properties.getRetryAttempts())
.setRetryInterval(properties.getRetryInterval())
.setPingConnectionInterval(properties.getPingInterval())
.setKeepAlive(properties.isKeepAlive())
;
return Redisson.create(config);
}
static class RedisCodec extends BaseCodec {
private final Encoder encoder = in -> {
ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
try {
ByteBufOutputStream os = new ByteBufOutputStream(out);
JSON.writeJSONString(os, in, SerializerFeature.WriteClassName);
return os.buffer();
} catch (IOException e) {
out.release();
throw e;
} catch (Exception e) {
out.release();
throw new IOException(e);
}
};
private final Decoder<Object> decoder = (buf, state) -> JSON.parseObject(new ByteBufInputStream(buf), Object.class);
@Override
public Decoder<Object> getValueDecoder() {
return decoder;
}
@Override
public Encoder getValueEncoder() {
return encoder;
}
}
}
package cn.bugstack.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @ClassName: RedisClientConfigProperties
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/14 17:40
*/
@Data
@ConfigurationProperties(prefix = "redis.sdk.config", ignoreInvalidFields = true)
public class RedisClientConfigProperties {
/** host:ip */
private String host;
/** 端口 */
private int port;
/** 账密 */
private String password;
/** 设置连接池的大小,默认为64 */
private int poolSize = 64;
/** 设置连接池的最小空闲连接数,默认为10 */
private int minIdleSize = 10;
/** 设置连接的最大空闲时间(单位:毫秒),超过该时间的空闲连接将被关闭,默认为10000 */
private int idleTimeout = 10000;
/** 设置连接超时时间(单位:毫秒),默认为10000 */
private int connectTimeout = 10000;
/** 设置连接重试次数,默认为3 */
private int retryAttempts = 3;
/** 设置连接重试的间隔时间(单位:毫秒),默认为1000 */
private int retryInterval = 1000;
/** 设置定期检查连接是否可用的时间间隔(单位:毫秒),默认为0,表示不进行定期检查 */
private int pingInterval = 0;
/** 设置是否保持长连接,默认为true */
private boolean keepAlive = true;
}
...@@ -34,6 +34,21 @@ mybatis: ...@@ -34,6 +34,21 @@ mybatis:
mapper-locations: classpath:/mybatis/mapper/*.xml mapper-locations: classpath:/mybatis/mapper/*.xml
config-location: classpath:/mybatis/config/mybatis-config.xml config-location: classpath:/mybatis/config/mybatis-config.xml
# Redis
redis:
sdk:
config:
host: 127.0.0.1
port: 6379
pool-size: 10
min-idle-size: 5
idle-timeout: 30000
connect-timeout: 5000
retry-attempts: 3
retry-interval: 1000
ping-interval: 60000
keep-alive: true
# 日志 # 日志
logging: logging:
level: level:
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bugstack.infrastructure.dao.IAwardDao"> <mapper namespace="cn.bugstack.infrastructure.persistent.dao.IAwardDao">
<resultMap id="dataMap" type="cn.bugstack.infrastructure.dao.po.Award"> <resultMap id="dataMap" type="cn.bugstack.infrastructure.persistent.po.Award">
<id column="id" property="id"/> <id column="id" property="id"/>
<result column="award_id" property="awardId"/> <result column="award_id" property="awardId"/>
<result column="award_key" property="awardKey"/> <result column="award_key" property="awardKey"/>
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bugstack.infrastructure.dao.IStrategyAwardDao"> <mapper namespace="cn.bugstack.infrastructure.persistent.dao.IStrategyAwardDao">
<resultMap id="dataMap" type="cn.bugstack.infrastructure.dao.po.StrategyAward"> <resultMap id="dataMap" type="cn.bugstack.infrastructure.persistent.po.StrategyAward">
<id column="id" property="id"/> <id column="id" property="id"/>
<result column="strategy_id" property="strategyId"/> <result column="strategy_id" property="strategyId"/>
<result column="award_id" property="awardId"/> <result column="award_id" property="awardId"/>
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
from strategy_award from strategy_award
limit 10 limit 10
</select> </select>
<select id="queryStrategyAwardListByStrategyId" parameterType="java.lang.Long" resultMap="dataMap">
select strategy_id, award_id, award_count, award_count_surplus, award_rate
from strategy_award
where strategy_id = #{strategy_id}
</select>
</mapper> </mapper>
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bugstack.infrastructure.dao.IStrategyDao"> <mapper namespace="cn.bugstack.infrastructure.persistent.dao.IStrategyDao">
<resultMap id="dataMap" type="cn.bugstack.infrastructure.dao.po.Strategy"> <resultMap id="dataMap" type="cn.bugstack.infrastructure.persistent.po.Strategy">
<id column="id" property="id"/> <id column="id" property="id"/>
<result column="strategy_id" property="strategyId"/> <result column="strategy_id" property="strategyId"/>
<result column="strategy_desc" property="strategyDesc"/> <result column="strategy_desc" property="strategyDesc"/>
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.bugstack.infrastructure.dao.IStrategyRuleDao"> <mapper namespace="cn.bugstack.infrastructure.persistent.dao.IStrategyRuleDao">
<resultMap id="dataMap" type="cn.bugstack.infrastructure.dao.po.StrategyRule"> <resultMap id="dataMap" type="cn.bugstack.infrastructure.persistent.po.StrategyRule">
<id column="id" property="id"/> <id column="id" property="id"/>
<result column="strategy_id" property="strategyId"/> <result column="strategy_id" property="strategyId"/>
<result column="award_id" property="awardId"/> <result column="award_id" property="awardId"/>
......
package cn.bugstack.test.domain;
import cn.bugstack.domain.strategy.service.armory.IStrategyArmory;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* @ClassName: StrategyArmoryTest
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/14 20:28
*/
@SpringBootTest
@Slf4j
@RunWith(SpringRunner.class)
public class StrategyArmoryTest {
@Resource
private IStrategyArmory strategyArmory;
@Test
public void test_strategyArmory(){
strategyArmory.assembleLotteryStrategy(100002L);
}
/**
* 从装配的策略中随机获取奖品ID值
*/
@Test
public void test_getAssembleRandomVal() {
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
log.info("测试结果:{} - 奖品ID值", strategyArmory.getRandomAwardId(100002L));
}
}
package cn.bugstack.test.infrastructure; package cn.bugstack.test.infrastructure;
import cn.bugstack.infrastructure.dao.IAwardDao; import cn.bugstack.infrastructure.persistent.dao.IAwardDao;
import cn.bugstack.infrastructure.dao.po.Award; import cn.bugstack.infrastructure.persistent.po.Award;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.junit.Test; import org.junit.Test;
......
package cn.bugstack.domain.strategy.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName: AwardEntity
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/14 19:37
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AwardEntity {
/** 用户ID */
private String userId;
/** 奖品ID */
private Integer awardId;
}
package cn.bugstack.domain.strategy.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @ClassName: StrategyAwardEntity
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/14 19:32
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StrategyAwardEntity {
/** 抽奖策略ID */
private Long strategyId;
/** 抽奖奖品ID - 内部流转使用 */
private Integer awardId;
/** 奖品库存总量 */
private Integer awardCount;
/** 奖品库存剩余 */
private Integer awardCountSurplus;
/** 奖品中奖概率 */
private BigDecimal awardRate;
}
package cn.bugstack.domain.strategy.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName: StrategyConditionEntity
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/14 19:37
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StrategyConditionEntity {
/** 用户ID */
private String userId;
/** 策略ID */
private Integer strategyId;
}
package cn.bugstack.domain.strategy.repository;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import java.util.List;
import java.util.Map;
public interface IStrategyRepository {
List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId);
void storeStrategyAwardSearchRateTable(Long strategyId, Integer rateRange, Map<Integer, Integer> strategyAwardSearchRateTable);
Integer getStrategyAwardAssemble(Long strategyId, Integer rateKey);
int getRateRange(Long strategyId);
}
package cn.bugstack.domain.strategy.service.armory;
public interface IStrategyArmory {
/**
* 装配抽奖策略配置「触发的时机可以为活动审核通过后进行调用」
*
* @param strategyId 策略ID
* @return 装配结果
*/
boolean assembleLotteryStrategy(Long strategyId);
/**
* 获取抽奖策略装配的随机结果
*
* @param strategyId 策略ID
* @return 抽奖结果
*/
Integer getRandomAwardId(Long strategyId);
}
package cn.bugstack.domain.strategy.service.armory;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.SecureRandom;
import java.util.*;
/**
* @ClassName: StrategyArmory
* @Description: 策略装配库(兵工厂),负责初始化策略计算
* @Author: zhaoyongfeng
* @Date: 2024/11/14 17:39
*/
@Slf4j
@Service
public class StrategyArmory implements IStrategyArmory{
@Resource
private IStrategyRepository repository;
@Override
public boolean assembleLotteryStrategy(Long strategyId) {
//1. 查询策略配置
List<StrategyAwardEntity> strategyAwardEntities = repository.queryStrategyAwardList(strategyId);
// 获取最小概率值
BigDecimal minAwardRate = strategyAwardEntities.stream()
.map(StrategyAwardEntity::getAwardRate)
.min(BigDecimal::compareTo)
.orElse(BigDecimal.ZERO);
// 3. 获取概率值总和
BigDecimal totalAwardRate = strategyAwardEntities.stream()
.map(StrategyAwardEntity::getAwardRate)
.reduce(BigDecimal.ZERO, BigDecimal::add);
//TODO 需要修改问题
// 4. 用 1 % 0.0001 获得概率范围,百分位、千分位、万分位
BigDecimal rateRange = totalAwardRate.divide(minAwardRate, 0, RoundingMode.CEILING);
// 5. 生成策略奖品概率查找表「这里指需要在list集合中,存放上对应的奖品占位即可,占位越多等于概率越高」
ArrayList<Integer> strategyAwardSearchRateTables = new ArrayList<>(rateRange.intValue());
for(StrategyAwardEntity strategyAward: strategyAwardEntities){
Integer awardId = strategyAward.getAwardId();
BigDecimal awardRate = strategyAward.getAwardRate();
// 计算出每个概率值需要存放到查找表的数量,循环填充
for (int i = 0; i < rateRange.multiply(awardRate).setScale(0, RoundingMode.CEILING).intValue(); i++) {
strategyAwardSearchRateTables.add(awardId);
}
}
// 6. 对存储的奖品进行乱序操作
Collections.shuffle(strategyAwardSearchRateTables);
// 7. 生成出Map集合,key值,对应的就是后续的概率值。通过概率来获得对应的奖品ID
Map<Integer, Integer> shuffleStrategyAwardSearchRateTable = new LinkedHashMap<>();
for (int i = 0; i < strategyAwardSearchRateTables.size(); i++) {
shuffleStrategyAwardSearchRateTable.put(i, strategyAwardSearchRateTables.get(i));
}
// 8. 存放到 Redis
repository.storeStrategyAwardSearchRateTable(strategyId, shuffleStrategyAwardSearchRateTable.size(), shuffleStrategyAwardSearchRateTable);
return true;
}
@Override
public Integer getRandomAwardId(Long strategyId) {
// 分布式部署下,不一定为当前应用做的策略装配。也就是值不一定会保存到本应用,而是分布式应用,所以需要从 Redis 中获取。
int rateRange = repository.getRateRange(strategyId);
// 通过生成的随机值,获取概率值奖品查找表的结果
return repository.getStrategyAwardAssemble(strategyId, new SecureRandom().nextInt(rateRange));
}
}
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
<!-- 系统模块 --> <!-- 系统模块 -->
<dependency> <dependency>
<groupId>cn.bugstack</groupId> <groupId>cn.bugstack</groupId>
......
package cn.bugstack.infrastructure.dao;
import cn.bugstack.infrastructure.dao.po.Award;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface IStrategyAwardDao {
List<Award> queryStrategyAwardList();
}
package cn.bugstack.infrastructure.dao; package cn.bugstack.infrastructure.persistent.dao;
import cn.bugstack.infrastructure.dao.po.Award; import cn.bugstack.infrastructure.persistent.po.Award;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;
......
package cn.bugstack.infrastructure.persistent.dao;
import cn.bugstack.infrastructure.persistent.po.Award;
import cn.bugstack.infrastructure.persistent.po.StrategyAward;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface IStrategyAwardDao {
List<StrategyAward> queryStrategyAwardList();
List<StrategyAward> queryStrategyAwardListByStrategyId(Long strategyId);
}
package cn.bugstack.infrastructure.dao; package cn.bugstack.infrastructure.persistent.dao;
import cn.bugstack.infrastructure.dao.po.Award; import cn.bugstack.infrastructure.persistent.po.Award;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;
......
package cn.bugstack.infrastructure.dao; package cn.bugstack.infrastructure.persistent.dao;
import cn.bugstack.infrastructure.dao.po.Award; import cn.bugstack.infrastructure.persistent.po.Award;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;
......
package cn.bugstack.infrastructure.persistent.redis;
import org.redisson.api.*;
/*
* @return
* @author zhaoyongfeng
* @description
* Redis服务
* @param null
*/
public interface IRedisService {
/**
* 设置指定 key 的值
*
* @param key 键
* @param value 值
*/
<T> void setValue(String key, T value);
/**
* 设置指定 key 的值
*
* @param key 键
* @param value 值
* @param expired 过期时间
*/
<T> void setValue(String key, T value, long expired);
/**
* 获取指定 key 的值
*
* @param key 键
* @return 值
*/
<T> T getValue(String key);
/**
* 获取队列
*
* @param key 键
* @param <T> 泛型
* @return 队列
*/
<T> RQueue<T> getQueue(String key);
/**
* 加锁队列
*
* @param key 键
* @param <T> 泛型
* @return 队列
*/
<T> RBlockingQueue<T> getBlockingQueue(String key);
/**
* 延迟队列
*
* @param rBlockingQueue 加锁队列
* @param <T> 泛型
* @return 队列
*/
<T> RDelayedQueue<T> getDelayedQueue(RBlockingQueue<T> rBlockingQueue);
/**
* 自增 Key 的值;1、2、3、4
*
* @param key 键
* @return 自增后的值
*/
long incr(String key);
/**
* 指定值,自增 Key 的值;1、2、3、4
*
* @param key 键
* @return 自增后的值
*/
long incrBy(String key, long delta);
/**
* 自减 Key 的值;1、2、3、4
*
* @param key 键
* @return 自增后的值
*/
long decr(String key);
/**
* 指定值,自增 Key 的值;1、2、3、4
*
* @param key 键
* @return 自增后的值
*/
long decrBy(String key, long delta);
/**
* 移除指定 key 的值
*
* @param key 键
*/
void remove(String key);
/**
* 判断指定 key 的值是否存在
*
* @param key 键
* @return true/false
*/
boolean isExists(String key);
/**
* 将指定的值添加到集合中
*
* @param key 键
* @param value 值
*/
void addToSet(String key, String value);
/**
* 判断指定的值是否是集合的成员
*
* @param key 键
* @param value 值
* @return 如果是集合的成员返回 true,否则返回 false
*/
boolean isSetMember(String key, String value);
/**
* 将指定的值添加到列表中
*
* @param key 键
* @param value 值
*/
void addToList(String key, String value);
/**
* 获取列表中指定索引的值
*
* @param key 键
* @param index 索引
* @return 值
*/
String getFromList(String key, int index);
/**
* 获取Map
*
* @param key 键
* @return 值
*/
<K, V> RMap<K, V> getMap(String key);
/**
* 将指定的键值对添加到哈希表中
*
* @param key 键
* @param field 字段
* @param value 值
*/
void addToMap(String key, String field, String value);
/**
* 获取哈希表中指定字段的值
*
* @param key 键
* @param field 字段
* @return 值
*/
String getFromMap(String key, String field);
/**
* 获取哈希表中指定字段的值
*
* @param key 键
* @param field 字段
* @return 值
*/
<K, V> V getFromMap(String key, K field);
/**
* 将指定的值添加到有序集合中
*
* @param key 键
* @param value 值
*/
void addToSortedSet(String key, String value);
/**
* 获取 Redis 锁(可重入锁)
*
* @param key 键
* @return Lock
*/
RLock getLock(String key);
/**
* 获取 Redis 锁(公平锁)
*
* @param key 键
* @return Lock
*/
RLock getFairLock(String key);
/**
* 获取 Redis 锁(读写锁)
*
* @param key 键
* @return RReadWriteLock
*/
RReadWriteLock getReadWriteLock(String key);
/**
* 获取 Redis 信号量
*
* @param key 键
* @return RSemaphore
*/
RSemaphore getSemaphore(String key);
/**
* 获取 Redis 过期信号量
* <p>
* 基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。
* 同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。
*
* @param key 键
* @return RPermitExpirableSemaphore
*/
RPermitExpirableSemaphore getPermitExpirableSemaphore(String key);
/**
* 闭锁
*
* @param key 键
* @return RCountDownLatch
*/
RCountDownLatch getCountDownLatch(String key);
/**
* 布隆过滤器
*
* @param key 键
* @param <T> 存放对象
* @return 返回结果
*/
<T> RBloomFilter<T> getBloomFilter(String key);
}
package cn.bugstack.infrastructure.persistent.redis;
import org.redisson.api.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.Duration;
/**
* @ClassName: RedissonService
* @Description:
* @Author: zhaoyongfeng
* @Date: 2024/11/14 17:49
*/
@Service("redissonService")
public class RedissonService implements IRedisService {
@Resource
private RedissonClient redissonClient;
public <T> void setValue(String key, T value) {
redissonClient.<T>getBucket(key).set(value);
}
@Override
public <T> void setValue(String key, T value, long expired) {
RBucket<T> bucket = redissonClient.getBucket(key);
bucket.set(value, Duration.ofMillis(expired));
}
public <T> T getValue(String key) {
return redissonClient.<T>getBucket(key).get();
}
@Override
public <T> RQueue<T> getQueue(String key) {
return redissonClient.getQueue(key);
}
@Override
public <T> RBlockingQueue<T> getBlockingQueue(String key) {
return redissonClient.getBlockingQueue(key);
}
@Override
public <T> RDelayedQueue<T> getDelayedQueue(RBlockingQueue<T> rBlockingQueue) {
return redissonClient.getDelayedQueue(rBlockingQueue);
}
@Override
public long incr(String key) {
return redissonClient.getAtomicLong(key).incrementAndGet();
}
@Override
public long incrBy(String key, long delta) {
return redissonClient.getAtomicLong(key).addAndGet(delta);
}
@Override
public long decr(String key) {
return redissonClient.getAtomicLong(key).decrementAndGet();
}
@Override
public long decrBy(String key, long delta) {
return redissonClient.getAtomicLong(key).addAndGet(-delta);
}
@Override
public void remove(String key) {
redissonClient.getBucket(key).delete();
}
@Override
public boolean isExists(String key) {
return redissonClient.getBucket(key).isExists();
}
public void addToSet(String key, String value) {
RSet<String> set = redissonClient.getSet(key);
set.add(value);
}
public boolean isSetMember(String key, String value) {
RSet<String> set = redissonClient.getSet(key);
return set.contains(value);
}
public void addToList(String key, String value) {
RList<String> list = redissonClient.getList(key);
list.add(value);
}
public String getFromList(String key, int index) {
RList<String> list = redissonClient.getList(key);
return list.get(index);
}
@Override
public <K, V> RMap<K, V> getMap(String key) {
return redissonClient.getMap(key);
}
public void addToMap(String key, String field, String value) {
RMap<String, String> map = redissonClient.getMap(key);
map.put(field, value);
}
public String getFromMap(String key, String field) {
RMap<String, String> map = redissonClient.getMap(key);
return map.get(field);
}
@Override
public <K, V> V getFromMap(String key, K field) {
return redissonClient.<K, V>getMap(key).get(field);
}
public void addToSortedSet(String key, String value) {
RSortedSet<String> sortedSet = redissonClient.getSortedSet(key);
sortedSet.add(value);
}
@Override
public RLock getLock(String key) {
return redissonClient.getLock(key);
}
@Override
public RLock getFairLock(String key) {
return redissonClient.getFairLock(key);
}
@Override
public RReadWriteLock getReadWriteLock(String key) {
return redissonClient.getReadWriteLock(key);
}
@Override
public RSemaphore getSemaphore(String key) {
return redissonClient.getSemaphore(key);
}
@Override
public RPermitExpirableSemaphore getPermitExpirableSemaphore(String key) {
return redissonClient.getPermitExpirableSemaphore(key);
}
@Override
public RCountDownLatch getCountDownLatch(String key) {
return redissonClient.getCountDownLatch(key);
}
@Override
public <T> RBloomFilter<T> getBloomFilter(String key) {
return redissonClient.getBloomFilter(key);
}
}
package cn.bugstack.infrastructure.persistent.repository;
import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.infrastructure.persistent.dao.IStrategyAwardDao;
import cn.bugstack.infrastructure.persistent.po.StrategyAward;
import cn.bugstack.infrastructure.persistent.redis.IRedisService;
import cn.bugstack.types.common.Constants;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName: StrategyRepository
* @Description: 策略服务仓储实现
* @Author: zhaoyongfeng
* @Date: 2024/11/14 19:27
*/
@Repository
public class StrategyRepository implements IStrategyRepository {
@Resource
private IStrategyAwardDao strategyAwardDao;
@Resource
private IRedisService redisService;
@Override
public List<StrategyAwardEntity> queryStrategyAwardList(Long strategyId) {
// 优先从缓存获取
String cacheKey = Constants.RedisKey.STRATEGY_AWARD_KEY + strategyId;
List<StrategyAwardEntity> strategyAwardEntities = redisService.getValue(cacheKey);
if (null != strategyAwardEntities && !strategyAwardEntities.isEmpty()) return strategyAwardEntities;
// 从库中获取数据
List<StrategyAward> strategyAwards = strategyAwardDao.queryStrategyAwardListByStrategyId(strategyId);
strategyAwardEntities = new ArrayList<>(strategyAwards.size());
for (StrategyAward strategyAward : strategyAwards) {
StrategyAwardEntity strategyAwardEntity = StrategyAwardEntity.builder()
.strategyId(strategyAward.getStrategyId())
.awardId(strategyAward.getAwardId())
.awardCount(strategyAward.getAwardCount())
.awardCountSurplus(strategyAward.getAwardCountSurplus())
.awardRate(strategyAward.getAwardRate())
.build();
strategyAwardEntities.add(strategyAwardEntity);
}
redisService.setValue(cacheKey, strategyAwardEntities);
return strategyAwardEntities;
}
@Override
public void storeStrategyAwardSearchRateTable(Long strategyId, Integer rateRange, Map<Integer, Integer> strategyAwardSearchRateTable) {
// 1. 存储抽奖策略范围值,如10000,用于生成1000以内的随机数
redisService.setValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + strategyId, rateRange);
// 2. 存储概率查找表
Map<Integer, Integer> cacheRateTable = redisService.getMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + strategyId);
cacheRateTable.putAll(strategyAwardSearchRateTable);
}
@Override
public Integer getStrategyAwardAssemble(Long strategyId, Integer rateKey) {
return redisService.getFromMap(Constants.RedisKey.STRATEGY_RATE_TABLE_KEY + strategyId, rateKey);
}
@Override
public int getRateRange(Long strategyId) {
return redisService.getValue(Constants.RedisKey.STRATEGY_RATE_RANGE_KEY + strategyId);
}
}
/**
* 提供redis链接配置
*/
package cn.bugstack.infrastructure.redis;
\ No newline at end of file
...@@ -4,4 +4,11 @@ public class Constants { ...@@ -4,4 +4,11 @@ public class Constants {
public final static String SPLIT = ","; public final static String SPLIT = ",";
public static class RedisKey {
public static String STRATEGY_AWARD_KEY = "big_market_strategy_award_key_";
public static String STRATEGY_RATE_TABLE_KEY = "big_market_strategy_rate_table_key_";
public static String STRATEGY_RATE_RANGE_KEY = "big_market_strategy_rate_range_key_";
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册