initial commit: lottery 项目集(三工程统一管理)
- apps/lotteryServer, lotteryCapture, lotteryOpen 三个业务工程 - 忽略 archive/, tools/, infra/data/ 大目录与敏感配置文件 - 移除 lotteryServer 原嵌套 git,并入顶层统一管理
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre7">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>lotteryOpen_sell</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
@@ -0,0 +1,13 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -0,0 +1,4 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
@@ -0,0 +1,272 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>lotteryOpen</groupId>
|
||||
<artifactId>lotteryOpen</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>lotteryOpen</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-utils</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.10</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>4.1.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>4.1.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>4.1.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>4.1.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>4.1.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aspects</artifactId>
|
||||
<version>4.1.0.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>4.2.13.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-c3p0</artifactId>
|
||||
<version>4.2.13.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<version>4.2.13.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.json-lib</groupId>
|
||||
<artifactId>json-lib</artifactId>
|
||||
<version>2.4</version>
|
||||
<classifier>jdk15</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xom</groupId>
|
||||
<artifactId>xom</artifactId>
|
||||
<version>1.2.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.htmlparser</groupId>
|
||||
<artifactId>htmlparser</artifactId>
|
||||
<version>1.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.0.31</version>
|
||||
</dependency>
|
||||
|
||||
<!-- LOGGING begins -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 代码直接调用log4j会被桥接到slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- 代码直接调用common-logging会被桥接到slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- 代码直接调用java.util.logging会被桥接到slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jul-to-slf4j</artifactId>
|
||||
<version>1.7.7</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- LOGGING ends -->
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>2.6.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.28</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.contrapunctus.lzma</groupId>
|
||||
<artifactId>lzma-4.63-jio-0.95.jar</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}\src\main\resources\lib\lzma-4.63-jio-0.95.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>lotteryOpen</finalName>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<configuration>
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<versionRange>[2.0,)</versionRange>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
<ignore />
|
||||
</action>
|
||||
</pluginExecution>
|
||||
</pluginExecutions>
|
||||
</lifecycleMappingMetadata>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<!-- 设置源文件编码方式 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
<mainClass>lottery.bin.StartUp</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 拷贝依赖的jar包到lib目录 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>
|
||||
${project.build.directory}/lib
|
||||
</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- 解决资源文件的编码问题 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,7 @@
|
||||
#!/bin/startup.sh
|
||||
jarName=LotteryOpen.jar
|
||||
ps -ef|grep -v grep|grep $jarName|while read u p o
|
||||
do
|
||||
kill -9 $p
|
||||
done
|
||||
exec java -jar -Xms512m -Xmx1024m $jarName &
|
||||
@@ -0,0 +1,40 @@
|
||||
package javautils;
|
||||
|
||||
public class ObjectUtil {
|
||||
|
||||
public static double toDouble(Object object) {
|
||||
if(object != null && object instanceof Number) {
|
||||
return ((Number) object).doubleValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int toInt(Object object) {
|
||||
if(object != null && object instanceof Number) {
|
||||
return ((Number) object).intValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static long toLong(Object object) {
|
||||
if(object != null && object instanceof Number) {
|
||||
return ((Number) object).longValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static float toFloat(Object object) {
|
||||
if(object != null && object instanceof Number) {
|
||||
return ((Number) object).floatValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static short toShort(Object object) {
|
||||
if(object != null && object instanceof Number) {
|
||||
return ((Number) object).shortValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,507 @@
|
||||
package javautils;
|
||||
|
||||
import javautils.date.Moment;
|
||||
import javautils.math.MathUtil;
|
||||
import javautils.regex.RegexUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class StringUtil {
|
||||
|
||||
/**
|
||||
* 判断字符串是否为空
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNotNull(String s) {
|
||||
if(s == null) return false;
|
||||
if(s.trim().length() == 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串能否转成int
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInteger(String s) {
|
||||
try {
|
||||
Integer.parseInt(s);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串能否转成double
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isDouble(String s) {
|
||||
try {
|
||||
Double.parseDouble(s);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串能否转成float
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isFloat(String s) {
|
||||
try {
|
||||
Float.parseFloat(s);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串能否转成boolean
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isBoolean(String s) {
|
||||
try {
|
||||
Boolean.parseBoolean(s);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断能否转成short
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isShort(String s) {
|
||||
try {
|
||||
Short.parseShort(s);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断能否转成long
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isLong(String s) {
|
||||
try {
|
||||
Long.parseLong(s);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动转类型
|
||||
* @param s
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Object transObject(String s, Class<?> clazz) {
|
||||
if(clazz != null) {
|
||||
if(clazz == Integer.class) {
|
||||
if(isInteger(s)) {
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(clazz == Double.class) {
|
||||
if(isDouble(s)) {
|
||||
return Double.parseDouble(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(clazz == Float.class) {
|
||||
if(isFloat(s)) {
|
||||
return Float.parseFloat(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(clazz == Boolean.class) {
|
||||
if(isBoolean(s)) {
|
||||
return Boolean.parseBoolean(s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(clazz == Short.class) {
|
||||
if(isShort(s)) {
|
||||
return Short.parseShort(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(clazz == Long.class) {
|
||||
if(isLong(s)) {
|
||||
return Long.parseLong(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public static String transArrayToString(Object[] array) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, j = array.length; i < j; i++) {
|
||||
sb.append(array[i].toString());
|
||||
if(i < j - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String transArrayToString(Object[] array, String p) {
|
||||
String tempStr = new String();
|
||||
for (Object value : array) {
|
||||
tempStr += p + value.toString() + p + ",";
|
||||
}
|
||||
tempStr = tempStr.substring(0, tempStr.length() - 2);
|
||||
return tempStr;
|
||||
}
|
||||
|
||||
public static int[] transStringToIntArray(String string, String regex) {
|
||||
if (isNotNull(string)) {
|
||||
String[] sArray = string.split(regex);
|
||||
int[] intArray = new int[sArray.length];
|
||||
for (int i = 0; i < sArray.length; i++) {
|
||||
if(isIntegerString(sArray[i])) {
|
||||
intArray[i] = Integer.parseInt(sArray[i]);
|
||||
}
|
||||
}
|
||||
return intArray;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换文件大小
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static String transDataLong(long b) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
long KB = 1024;
|
||||
long MB = KB * 1024;
|
||||
long GB = MB * 1024;
|
||||
long TB = GB * 1024;
|
||||
if(b >= TB) {
|
||||
sb.append(MathUtil.doubleFormat((double)b/TB, 2) + "TB");
|
||||
} else if(b >= GB) {
|
||||
sb.append(MathUtil.doubleFormat((double)b/GB, 2) + "GB");
|
||||
} else if(b >= MB) {
|
||||
sb.append(MathUtil.doubleFormat((double)b/MB, 2) + "MB");
|
||||
} else if(b >= KB) {
|
||||
sb.append(MathUtil.doubleFormat((double)b/KB, 2) + "KB");
|
||||
} else {
|
||||
sb.append(b + "B");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断是否是int类型字符串
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static boolean isIntegerString(String str) {
|
||||
boolean flag = false;
|
||||
if(RegexUtil.isMatcher(str, RegexUtil.integer_regex)) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static boolean isDoubleString(String str) {
|
||||
boolean flag = false;
|
||||
if(RegexUtil.isMatcher(str, RegexUtil.rational_numbers_regex)) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static boolean isFloatString(String str) {
|
||||
boolean flag = false;
|
||||
if(RegexUtil.isMatcher(str, RegexUtil.rational_numbers_regex)) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否是日期yyyy-MM-dd格式
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static boolean isDateString(String str) {
|
||||
try {
|
||||
if(str.length() != 10) {
|
||||
return false;
|
||||
}
|
||||
new SimpleDateFormat("yyyy-MM-dd").parse(str);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String markWithSymbol(Object obj, String symbol) {
|
||||
return symbol + obj.toString() + symbol;
|
||||
}
|
||||
|
||||
//123456789
|
||||
public static Object[] split(String s) {
|
||||
char[] carr = s.toCharArray();
|
||||
Object[] arr = new Object[carr.length];
|
||||
for (int i = 0; i < carr.length; i++) {
|
||||
arr[i] = carr[i];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
//123456789
|
||||
public static String[] splitToStr(String s) {
|
||||
char[] carr = s.toCharArray();
|
||||
String[] arr = new String[carr.length];
|
||||
for (int i = 0; i < carr.length; i++) {
|
||||
arr[i] = carr[i] + "";
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
//123456789
|
||||
public static String[] splitDistinct(String s) {
|
||||
String[] strs = splitToStr(s);
|
||||
|
||||
HashSet<String> distinct = new HashSet<>();
|
||||
for (String str : strs) {
|
||||
distinct.add(str);
|
||||
}
|
||||
|
||||
return distinct.toArray(new String[]{});
|
||||
}
|
||||
|
||||
public static String substring(String s, String start, String end, boolean isInSub) {
|
||||
int idx = s.indexOf(start);
|
||||
int edx = s.indexOf(end);
|
||||
idx = idx == -1 ? 0 : idx + (isInSub ? 0 : start.length());
|
||||
edx = edx == -1 ? s.length() : edx + (isInSub ? end.length() : 0);
|
||||
return s.substring(idx, edx);
|
||||
}
|
||||
|
||||
public static String doubleFormat(double d) {
|
||||
DecimalFormat decimalformat = new DecimalFormat("#0.00");
|
||||
return decimalformat.format(d);
|
||||
}
|
||||
|
||||
public static String fromInputStream(InputStream inputStream) {
|
||||
try {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
byte[] bytes = new byte[1024];
|
||||
int len;
|
||||
while ((len = inputStream.read(bytes)) != -1) {
|
||||
sb.append(new String(bytes, 0, len));
|
||||
}
|
||||
inputStream.close();
|
||||
return sb.toString();
|
||||
} catch (Exception e) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证是否是服务时间
|
||||
* @param moment
|
||||
* @param times 格式为12:00~2:00
|
||||
* @return
|
||||
*/
|
||||
public static boolean isServiceTime(Moment moment, String times) {
|
||||
int thisMins = moment.hour() * 60 + moment.minute();
|
||||
String[] timeArr = times.split("~");
|
||||
int startMins = Integer.parseInt(timeArr[0].split(":")[0]) * 60 + Integer.parseInt(timeArr[0].split(":")[1]);
|
||||
int endMins = Integer.parseInt(timeArr[1].split(":")[0]) * 60 + Integer.parseInt(timeArr[1].split(":")[1]);
|
||||
if(startMins < endMins) {
|
||||
// 不在服务内的时间是 0 - start 和 end - 24
|
||||
if((thisMins > 0 && thisMins < startMins) || (thisMins > endMins && thisMins < 24 * 60)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// 不在服务内的时间是 end - start
|
||||
if(thisMins > endMins && thisMins < startMins) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//姓名只能包含中文
|
||||
public static boolean isNameChn(String name){
|
||||
boolean result = true;
|
||||
int num = 0;
|
||||
for(int i=0;i<name.length();i++){
|
||||
if(!Pattern.matches(RegexUtil.name_input_chn, name.substring(i, i + 1))){
|
||||
num++;
|
||||
}
|
||||
}
|
||||
if(num > 0){
|
||||
result = false;;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String join(String str, String separator) {
|
||||
if (isNotNull(str)) {
|
||||
return StringUtils.join(split(str), separator);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按位置进行替换,如String str = replaceAt("[√,√,√,-,-]", '√', new char[]{'1', '2'}, new int[]{1, 3});
|
||||
* @param str 要替换的字符串
|
||||
* @param search 查找字符
|
||||
* @param withs 依次替换成指定字符
|
||||
* @param ats 匹配第n次出现的时候按指定字符进行替换
|
||||
* @return
|
||||
*/
|
||||
public static String replaceAt(String str, char search, char[] withs, int[] ats) {
|
||||
if (isNotNull(str)) {
|
||||
char[] chars = str.toCharArray();
|
||||
int appearN = 0;
|
||||
int withN = 0;
|
||||
int atN = 0;
|
||||
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
|
||||
if (withN >= withs.length || atN >= ats.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
char aChar = chars[i];
|
||||
if (aChar == search) {
|
||||
// 第n次出现
|
||||
appearN++;
|
||||
|
||||
if (appearN == ats[atN]) {
|
||||
chars[i] = withs[withN++];
|
||||
atN++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计每个字符串出现的次数,并按照从大到小进行排序
|
||||
*/
|
||||
public static Map<String, Integer> countChars(String str) {
|
||||
char[] chars = str.toCharArray();
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
|
||||
for (char aChar : chars) {
|
||||
String _char = aChar + "";
|
||||
Integer count = map.get(_char);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
count++;
|
||||
map.put(_char, count);
|
||||
}
|
||||
|
||||
Map<String, Integer> sortedMap = new LinkedHashMap<>();
|
||||
if (map != null && !map.isEmpty()) {
|
||||
List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
|
||||
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
|
||||
@Override
|
||||
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
|
||||
return o2.getValue().compareTo(o1.getValue());
|
||||
}
|
||||
});
|
||||
Iterator<Map.Entry<String, Integer>> iter = entryList.iterator();
|
||||
Map.Entry<String, Integer> tmpEntry;
|
||||
while (iter.hasNext()) {
|
||||
tmpEntry = iter.next();
|
||||
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
|
||||
}
|
||||
}
|
||||
return sortedMap;
|
||||
}
|
||||
/**
|
||||
* 统计每个字符串出现的次数,并按照从大到小进行排序
|
||||
*/
|
||||
public static Map<String, Integer> countChars(String[] str) {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
|
||||
for (String aChar : str) {
|
||||
String _char = aChar;
|
||||
Integer count = map.get(_char);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
count++;
|
||||
map.put(_char, count);
|
||||
}
|
||||
|
||||
return sortByValueMap(map);
|
||||
}
|
||||
|
||||
private static Map<String, Integer> sortByValueMap(Map<String, Integer> map) {
|
||||
Map<String, Integer> sortedMap = new LinkedHashMap<>();
|
||||
if (map != null && !map.isEmpty()) {
|
||||
List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
|
||||
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
|
||||
@Override
|
||||
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
|
||||
return o2.getValue().compareTo(o1.getValue());
|
||||
}
|
||||
});
|
||||
Iterator<Map.Entry<String, Integer>> iter = entryList.iterator();
|
||||
Map.Entry<String, Integer> tmpEntry;
|
||||
while (iter.hasNext()) {
|
||||
tmpEntry = iter.next();
|
||||
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
|
||||
}
|
||||
}
|
||||
return sortedMap;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// String str = replaceAt("√,√,√,√,√", '√', new char[]{'1', '2', '3'}, new int[]{1, 2, 5});
|
||||
// System.out.println(str);
|
||||
|
||||
// Map<String, Integer> stringIntegerMap = countChars("002003006007009022023026027029033036103703906606706907707910992232262272292332362372392662672692772792993363373393663673693773793996676696776796997797991");
|
||||
// for (String s : stringIntegerMap.keySet()) {
|
||||
// System.out.println(s + " = " + stringIntegerMap.get(s));
|
||||
// }
|
||||
|
||||
Map<String, Integer> stringIntegerMap = countChars(new String[]{"2", "1", "2", "1", "1"});
|
||||
Collection<Integer> values = stringIntegerMap.values();
|
||||
Integer[] integers = values.toArray(new Integer[]{});
|
||||
System.out.println(integers[0]);
|
||||
System.out.println(integers[1]);
|
||||
|
||||
// Map<String, Integer> stringIntegerMap = countChars("0112223333555555");
|
||||
// for (Map.Entry<String, Integer> stringIntegerEntry : stringIntegerMap.entrySet()) {
|
||||
// System.out.println(stringIntegerEntry.getKey() + "=" + stringIntegerEntry.getValue());
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
package javautils.array;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ArrayUtils {
|
||||
public static boolean hasSame(String... vals) {
|
||||
Set<String> set = new HashSet<>();
|
||||
set.addAll(Arrays.asList(vals));
|
||||
|
||||
return vals.length != set.size();
|
||||
}
|
||||
|
||||
public static int Combination(int n, int m) {
|
||||
if(m < 0 || n < 0) {
|
||||
return 0;
|
||||
}
|
||||
if(m == 0 || n == 0) {
|
||||
return 1;
|
||||
}
|
||||
if(m > n) {
|
||||
return 0;
|
||||
}
|
||||
if(m > n /2.0) {
|
||||
m = n - m;
|
||||
}
|
||||
double result = 0.0;
|
||||
for (int i = n; i >= (n - m + 1); i--) {
|
||||
result += Math.log(i);
|
||||
}
|
||||
for (int i = m; i >= 1; i--) {
|
||||
result -= Math.log(i);
|
||||
}
|
||||
result = Math.exp(result);
|
||||
return (int) Math.round(result);
|
||||
}
|
||||
|
||||
public static List<Object[]> CombinationValue(List<Object[]> source, int m, int x) {
|
||||
int n = source.size();
|
||||
List<Object[]> list = new ArrayList<>();
|
||||
int start = 0;
|
||||
while (m > 0) {
|
||||
if (m == 1) {
|
||||
list.add(source.get(start + x));
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i <= n - m; i++) {
|
||||
int cnm = (int) Combination(n - 1 - i, m - 1);
|
||||
if (x <= cnm - 1) {
|
||||
list.add(source.get(start + i));
|
||||
start = start + (i + 1);
|
||||
n = n - (i + 1);
|
||||
m--;
|
||||
break;
|
||||
} else {
|
||||
x = x - cnm;
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对数据库in
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public static String transInIds(int[] ids) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, j = ids.length; i < j; i++) {
|
||||
sb.append(ids[i]);
|
||||
if(i < j - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String transInIds(Integer[] ids) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, j = ids.length; i < j; i++) {
|
||||
sb.append(ids[i].intValue());
|
||||
if(i < j - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 针对数据库in
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public static String transInIds(List<Integer> ids) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, j = ids.size(); i < j; i++) {
|
||||
sb.append(ids.get(i).intValue());
|
||||
if(i < j - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 存进数据库
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public static String transInsertIds(int[] ids) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, j = ids.length; i < j; i++) {
|
||||
sb.append("[" + ids[i] + "]");
|
||||
if(i < j - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取id的时候,解析成id数组
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
public static int[] transGetIds(String ids) {
|
||||
String[] tmp = ids.replaceAll("\\[|\\]", "").split(",");
|
||||
int[] arr = new int[tmp.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = Integer.parseInt(tmp[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成字符串
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static String toString(List<Integer> list) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, j = list.size(); i < j; i++) {
|
||||
sb.append(list.get(i));
|
||||
if(i < j - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String toString(Object[] objs) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (Object obj : objs) {
|
||||
sb.append(obj.toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速排序<br>
|
||||
* 算法的思想在于分而治之:先找一个元素(一般来说都是数组头元素),把比它大的都放到右边,把比它小的都放到左边;<br>
|
||||
* 然后再按照这样的思想去处理两个子数组; 下面说的子数组头元素通指用来划分数组的元素;<br>
|
||||
* <br>
|
||||
* 下面程序关键点就在于!forward, low0++, high0--这些运算; 这三个运算使得a[low0],a[high0]里面总有一个指向子数组头元素; <br>
|
||||
* 可以用极端的情况来方便理解这三个值的运作: <br>
|
||||
* 假如我的数列为0123456789, 初始时forward=false,0作为子数组划分依据,很显然第一轮的时候不会发生任何交换,low0一直指向0,<br>
|
||||
* high0逐渐下降直到它指向0为止; 同理可思考9876543210这个例子;<br>
|
||||
* <br>
|
||||
* 时间复杂度: 平均:O(nlogn),最好:O(nlogn);最坏:O(n^2);
|
||||
* 空间复杂度: O(logn);要为递归栈提供空间
|
||||
* @param a 待排序数组<br>
|
||||
* @param low 子数组开始的下标;<br>
|
||||
* @param high 子数组结束的下标;<br>
|
||||
*/
|
||||
public static void quickSortDouble(Double[] a, int low, int high){
|
||||
if(low>=high){
|
||||
return;
|
||||
}
|
||||
int low0 = low;
|
||||
int high0 = high;
|
||||
boolean forward = false;
|
||||
while(low0!=high0){
|
||||
if(a[low0]>a[high0]){
|
||||
double tmp = a[low0];
|
||||
a[low0] = a[high0];
|
||||
a[high0] = tmp;
|
||||
forward = !forward;
|
||||
}
|
||||
if(forward){
|
||||
low0++;
|
||||
}
|
||||
else{
|
||||
high0--;
|
||||
}
|
||||
}
|
||||
low0--;
|
||||
high0++;
|
||||
quickSortDouble(a, low, low0);
|
||||
quickSortDouble(a, high0, high);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速排序的简单调用形式<br>
|
||||
* 方便测试和调用<br>
|
||||
* @param a
|
||||
*/
|
||||
public static void quickSortDouble(Double[] a){
|
||||
quickSortDouble(a, 0, a.length-1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 快速排序<br>
|
||||
* 算法的思想在于分而治之:先找一个元素(一般来说都是数组头元素),把比它大的都放到右边,把比它小的都放到左边;<br>
|
||||
* 然后再按照这样的思想去处理两个子数组; 下面说的子数组头元素通指用来划分数组的元素;<br>
|
||||
* <br>
|
||||
* 下面程序关键点就在于!forward, low0++, high0--这些运算; 这三个运算使得a[low0],a[high0]里面总有一个指向子数组头元素; <br>
|
||||
* 可以用极端的情况来方便理解这三个值的运作: <br>
|
||||
* 假如我的数列为0123456789, 初始时forward=false,0作为子数组划分依据,很显然第一轮的时候不会发生任何交换,low0一直指向0,<br>
|
||||
* high0逐渐下降直到它指向0为止; 同理可思考9876543210这个例子;<br>
|
||||
* <br>
|
||||
* 时间复杂度: 平均:O(nlogn),最好:O(nlogn);最坏:O(n^2);
|
||||
* 空间复杂度: O(logn);要为递归栈提供空间
|
||||
* @param a 待排序数组<br>
|
||||
* @param low 子数组开始的下标;<br>
|
||||
* @param high 子数组结束的下标;<br>
|
||||
*/
|
||||
public static void quickSortString(String[] a, int low, int high){
|
||||
if(low>=high){
|
||||
return;
|
||||
}
|
||||
int low0 = low;
|
||||
int high0 = high;
|
||||
boolean forward = false;
|
||||
while(low0!=high0){
|
||||
if(a[low0].compareTo(a[high0]) > 0){
|
||||
String tmp = a[low0];
|
||||
a[low0] = a[high0];
|
||||
a[high0] = tmp;
|
||||
forward = !forward;
|
||||
}
|
||||
if(forward){
|
||||
low0++;
|
||||
}
|
||||
else{
|
||||
high0--;
|
||||
}
|
||||
}
|
||||
low0--;
|
||||
high0++;
|
||||
quickSortString(a, low, low0);
|
||||
quickSortString(a, high0, high);
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速排序的简单调用形式<br>
|
||||
* 方便测试和调用<br>
|
||||
* @param a
|
||||
*/
|
||||
public static void quickSortString(String[] a){
|
||||
quickSortString(a, 0, a.length-1);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// ConcurrentHashMap<String, Double> prizeCodes = new ConcurrentHashMap<>();
|
||||
// prizeCodes.put("1000000", 2000000d);
|
||||
// prizeCodes.put("0", 2d);
|
||||
// for (int i = 1; i <= 100000; i++) {
|
||||
// // prizeCodes.put(i + "", 0.01954);
|
||||
// prizeCodes.put(i + "", Integer.valueOf(RandomUtils.nextInt(200000)+5).doubleValue());
|
||||
// }
|
||||
//
|
||||
// long start = System.currentTimeMillis();
|
||||
//
|
||||
//
|
||||
// // Double[] prizes = prizeCodes.values().toArray(new Double[]{});
|
||||
// HashSet<Double> values = new HashSet<>(prizeCodes.values());
|
||||
// Double[] prizes = values.toArray(new Double[]{});
|
||||
//
|
||||
// ArrayUtils.quickSortDouble(prizes);
|
||||
// // Arrays.sort(prizes);
|
||||
// double minPrize = prizes[0];
|
||||
// double maxPrize = prizes[prizes.length-1];
|
||||
//
|
||||
// System.out.println("最小" + minPrize);
|
||||
// System.out.println("最大" + maxPrize);
|
||||
//
|
||||
// long spend = System.currentTimeMillis() - start;
|
||||
// System.out.println("耗时" + spend);
|
||||
|
||||
// System.out.println(Combination(5, 11));
|
||||
|
||||
// Double[] ds = {200d, 100d, 200d, 300d, 400d, 500d, 600d, 700d ,800d, 200d, 20d, 20d, 30d};
|
||||
//
|
||||
// quickSortDouble(ds);
|
||||
//
|
||||
// System.out.println(ds[0]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package javautils.datasource;
|
||||
|
||||
import com.alibaba.druid.filter.logging.Log4jFilter;
|
||||
import com.alibaba.druid.filter.stat.StatFilter;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2016/07/06
|
||||
*/
|
||||
public class ConfigDruidDataSource {
|
||||
public static Log4jFilter configLog4jFilter() {
|
||||
Log4jFilter filter = new Log4jFilter();
|
||||
filter.setStatementExecuteQueryAfterLogEnabled(false);
|
||||
filter.setStatementExecuteUpdateAfterLogEnabled(false);
|
||||
filter.setStatementExecuteBatchAfterLogEnabled(false);
|
||||
filter.setStatementExecuteAfterLogEnabled(false);
|
||||
filter.setStatementExecutableSqlLogEnable(false);
|
||||
filter.setStatementParameterSetLogEnabled(false);
|
||||
filter.setStatementParameterClearLogEnable(false);
|
||||
filter.setStatementCreateAfterLogEnabled(false);
|
||||
filter.setStatementCloseAfterLogEnabled(false);
|
||||
filter.setStatementPrepareAfterLogEnabled(false);
|
||||
filter.setStatementPrepareCallAfterLogEnabled(false);
|
||||
filter.setStatementLogEnabled(false);
|
||||
filter.setStatementLogErrorEnabled(false);
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static StatFilter configStatFilter() {
|
||||
StatFilter filter = new StatFilter();
|
||||
filter.setSlowSqlMillis(5000);
|
||||
filter.setLogSlowSql(true);
|
||||
filter.setMergeSql(true);
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package javautils.datasource;
|
||||
|
||||
import com.alibaba.druid.filter.Filter;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2016/07/06
|
||||
*/
|
||||
public class CustomDruidDataSource extends DruidDataSource {
|
||||
@Override
|
||||
public List<Filter> getProxyFilters() {
|
||||
List<Filter> proxyFilters = new ArrayList<>();
|
||||
proxyFilters.add(ConfigDruidDataSource.configLog4jFilter());
|
||||
proxyFilters.add(ConfigDruidDataSource.configStatFilter());
|
||||
return proxyFilters;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package javautils.date;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 依赖于Moment.java
|
||||
*/
|
||||
public class DateRangeUtil {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String[] days = listDate("2014-01-01", "2014-01-15");
|
||||
for (String string : days) {
|
||||
System.out.println(string);
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] listDate(String sDate, String eDate) {
|
||||
Moment sMoment = new Moment().fromDate(sDate);
|
||||
Moment eMoment = new Moment().fromDate(eDate);
|
||||
List<String> list = new ArrayList<>();
|
||||
if(sMoment.le(eMoment)) {
|
||||
list.add(sMoment.toSimpleDate());
|
||||
int days = eMoment.difference(sMoment, "day");
|
||||
for (int i = 0; i < days - 1; i++) {
|
||||
list.add(sMoment.add(1, "days").toSimpleDate());
|
||||
}
|
||||
}
|
||||
String[] array = new String[list.size()];
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,421 @@
|
||||
package javautils.date;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
public class DateUtil {
|
||||
|
||||
/**
|
||||
* 获取当前时间
|
||||
* @return
|
||||
*/
|
||||
public static String getCurrentTime() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return dateToString(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期
|
||||
* @return
|
||||
*/
|
||||
public static String getCurrentDate() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return dateToStringSim(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取昨天日期
|
||||
* @return
|
||||
*/
|
||||
public static String getYesterday() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
g.set(Calendar.DATE, g.get(Calendar.DATE) - 1);
|
||||
return dateToStringSim(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取明天日期
|
||||
* @return
|
||||
*/
|
||||
public static String getTomorrow() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
g.set(Calendar.DATE, g.get(Calendar.DATE) + 1);
|
||||
return dateToStringSim(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成时间
|
||||
* @param ms
|
||||
* @return
|
||||
*/
|
||||
public static String getTime(long ms) {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
g.setTimeInMillis(ms);
|
||||
return dateToString(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间获取GregorianCalendar
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
private static GregorianCalendar getCalendarByTime(String time, String format) {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
try {
|
||||
g.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time));
|
||||
} catch (ParseException e) {
|
||||
g = null;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算时间
|
||||
* @param g
|
||||
* @param seconds
|
||||
* @return
|
||||
*/
|
||||
private static String calcDate(GregorianCalendar g, int seconds) {
|
||||
if(g == null) {
|
||||
g = new GregorianCalendar();
|
||||
}
|
||||
g.add(Calendar.SECOND, seconds);
|
||||
return dateToString(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期转字符串
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String dateToString(Date date) {
|
||||
try {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String s = formatter.format(date);
|
||||
return s;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转日期
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static Date stringToDate(String date) {
|
||||
try {
|
||||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date d = (Date) formatter.parse(date);
|
||||
return d;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串转日期, 自定义格式
|
||||
* @param date
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static Date stringToDate(String date, String format) {
|
||||
try {
|
||||
DateFormat formatter = new SimpleDateFormat(format);
|
||||
Date d = (Date) formatter.parse(date);
|
||||
return d;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日期相差毫秒数
|
||||
* @param subDate
|
||||
* @param minDate
|
||||
* @return
|
||||
*/
|
||||
public static long calcDate(String subDate, String minDate) {
|
||||
long lSubDate = getCalendarByTime(subDate, "yyyy-MM-dd HH:mm:ss").getTimeInMillis();
|
||||
long lMinDate = getCalendarByTime(minDate, "yyyy-MM-dd HH:mm:ss").getTimeInMillis();
|
||||
return (lSubDate - lMinDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据日期计算相差天数,忽略时分秒
|
||||
* @param date1
|
||||
* @param date2
|
||||
* @return
|
||||
*/
|
||||
public static int calcDays(Date date1, Date date2) {
|
||||
Calendar date1Calendar = Calendar.getInstance();
|
||||
date1Calendar.setTime(date1);
|
||||
|
||||
Calendar date2Calendar = Calendar.getInstance();
|
||||
date2Calendar.setTime(date2);
|
||||
|
||||
int day1 = date1Calendar.get(Calendar.DAY_OF_YEAR);
|
||||
int day2 = date2Calendar.get(Calendar.DAY_OF_YEAR);
|
||||
|
||||
return day1 - day2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据差值计算出新的时间
|
||||
* @param time
|
||||
* @param seconds
|
||||
* @return
|
||||
*/
|
||||
public static String calcDateByTime(String time, int seconds) {
|
||||
GregorianCalendar g = getCalendarByTime(time, "yyyy-MM-dd HH:mm:ss");
|
||||
return calcDate(g, seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据天数计算出新的日期
|
||||
* @param date
|
||||
* @param days
|
||||
* @return
|
||||
*/
|
||||
public static String calcNewDay(String date, int days) {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
g.setTimeInMillis(formatTime(date, "yyyy-MM-dd"));
|
||||
g.set(Calendar.DATE, g.get(Calendar.DATE) + days);
|
||||
return dateToStringSim(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下一天
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String calcNextDay(String date) {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
g.setTimeInMillis(formatTime(date, "yyyy-MM-dd"));
|
||||
g.set(Calendar.DATE, g.get(Calendar.DATE) + 1);
|
||||
return dateToStringSim(g);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上一天
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String calcLastDay(String date) {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
g.setTimeInMillis(formatTime(date, "yyyy-MM-dd"));
|
||||
g.set(Calendar.DATE, g.get(Calendar.DATE) - 1);
|
||||
return dateToStringSim(g);
|
||||
}
|
||||
|
||||
private static Calendar getDateOfMonth(Calendar date, int num, boolean flag) {
|
||||
Calendar lastDate = (Calendar) date.clone();
|
||||
if(flag) {
|
||||
lastDate.add(Calendar.MONTH, num);
|
||||
}else {
|
||||
lastDate.add(Calendar.MONTH, -num);
|
||||
}
|
||||
|
||||
return lastDate;
|
||||
}
|
||||
|
||||
private static Calendar getDateOfLastMonth(String dateStr, int num, boolean flag) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
Date date = sdf.parse(dateStr);
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(date);
|
||||
return getDateOfMonth(c, num, flag);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid date format(yyyyMMdd): " + dateStr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上个月的同一天
|
||||
* @param date
|
||||
* @param num
|
||||
* @param flag
|
||||
* @return
|
||||
*/
|
||||
public static String getSameDateOfLastMonth(String date, int num, boolean flag) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String lastDate = sdf.format(getDateOfLastMonth(date, num, flag).getTime());
|
||||
return lastDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* GregorianCalendar转成字符串
|
||||
* @param g
|
||||
* @return
|
||||
*/
|
||||
private static String dateToString(GregorianCalendar g) {
|
||||
String year = String.valueOf(g.get(Calendar.YEAR));
|
||||
String month = String.format("%02d", g.get(Calendar.MONTH) + 1);
|
||||
String day =String.format("%02d", g.get(Calendar.DAY_OF_MONTH));
|
||||
String hours = String.format("%02d", g.get(Calendar.HOUR_OF_DAY));
|
||||
String minutes = String.format("%02d", g.get(Calendar.MINUTE));
|
||||
String seconds = String.format("%02d", g.get(Calendar.SECOND));
|
||||
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间转成MS
|
||||
* @param time
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static long stringToLong(String time, String format) {
|
||||
return stringToDate(time, format).getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* GregorianCalendar转成日期格式
|
||||
* @param g
|
||||
* @return
|
||||
*/
|
||||
public static String dateToStringSim(GregorianCalendar g) {
|
||||
String year = String.valueOf(g.get(Calendar.YEAR));
|
||||
String month = String.format("%02d", g.get(Calendar.MONTH) + 1);
|
||||
String day = String.format("%02d", g.get(Calendar.DAY_OF_MONTH));
|
||||
return year + "-" + month + "-" + day;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间
|
||||
* @return
|
||||
*/
|
||||
public static String getCurTimeStr() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
String year = String.valueOf(g.get(Calendar.YEAR));
|
||||
String month = String.format("%02d", g.get(Calendar.MONTH) + 1);
|
||||
String day = String.format("%02d", g.get(Calendar.DAY_OF_MONTH));
|
||||
String hours = String.format("%02d", g.get(Calendar.HOUR_OF_DAY));
|
||||
String minutes = String.format("%02d", g.get(Calendar.MINUTE));
|
||||
String seconds = String.format("%02d", g.get(Calendar.SECOND));
|
||||
|
||||
return year + month + day + hours + minutes + seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* @param time
|
||||
* @param oldFormat
|
||||
* @param newFormat
|
||||
* @return
|
||||
*/
|
||||
public static String formatTime(String time, String oldFormat,
|
||||
String newFormat) {
|
||||
return new SimpleDateFormat(newFormat).format(stringToDate(time,
|
||||
oldFormat));
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
* @param date
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String formatTime(Date date, String format) {
|
||||
return new SimpleDateFormat(format).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* @param time
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static String formatTime(long time, String format) {
|
||||
return formatTime(getTime(time), "yyyy-MM-dd HH:mm:ss", format);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间, 根据格式化参数
|
||||
* @param time
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static long formatTime(String time, String format) {
|
||||
return stringToDate(time, format).getTime();
|
||||
}
|
||||
|
||||
public static String dateForm(String date, String config) {
|
||||
if ("MM/dd/yyyy".equals(config)) {
|
||||
String[] dateStrs = date.split("/");
|
||||
return dateStrs[2] + "-" + dateStrs[0] + "-" + dateStrs[1];
|
||||
}
|
||||
if ("MM-dd-yyyy".equals(config)) {
|
||||
String[] dateStrs = date.split("-");
|
||||
return dateStrs[2] + "-" + dateStrs[0] + "-" + dateStrs[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getYear(String time) {
|
||||
return Integer.parseInt(time.substring(0, 4));
|
||||
}
|
||||
|
||||
public static int getMonth(String time) {
|
||||
return Integer.parseInt(time.substring(5, 7));
|
||||
}
|
||||
|
||||
public static int getDay(String time) {
|
||||
return Integer.parseInt(time.substring(8, 10));
|
||||
}
|
||||
|
||||
public static int getHours(String time) {
|
||||
return Integer.parseInt(time.substring(11, 13));
|
||||
}
|
||||
|
||||
public static int getMinutes(String time) {
|
||||
return Integer.parseInt(time.substring(14, 16));
|
||||
}
|
||||
|
||||
public static int getSeconds(String time) {
|
||||
return Integer.parseInt(time.substring(17));
|
||||
}
|
||||
|
||||
public static int getYear() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return g.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public static int getMonth() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return g.get(Calendar.MONTH) + 1;
|
||||
}
|
||||
|
||||
public static int getDay() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return g.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
public static int getHours() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return g.get(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
|
||||
public static int getMinutes() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return g.get(Calendar.MINUTE);
|
||||
}
|
||||
|
||||
public static int getSeconds() {
|
||||
GregorianCalendar g = new GregorianCalendar();
|
||||
return g.get(Calendar.SECOND);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,846 @@
|
||||
package javautils.date;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class Moment {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Moment moment = new Moment();
|
||||
System.out.println(moment.difference(new Moment().fromDate("2015-01-18"), "hour"));
|
||||
}
|
||||
|
||||
static {
|
||||
TimeZone china = TimeZone.getTimeZone("Asia/Shanghai");
|
||||
TimeZone.setDefault(china);
|
||||
}
|
||||
|
||||
public GregorianCalendar gc;
|
||||
|
||||
public Moment() {
|
||||
gc = new GregorianCalendar();
|
||||
gc.setFirstDayOfWeek(Calendar.MONDAY);
|
||||
}
|
||||
|
||||
public Moment(GregorianCalendar gc) {
|
||||
this.gc = gc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据日期获取对象
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public Moment fromDate(String date) {
|
||||
try {
|
||||
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date d = format.parse(date);
|
||||
gc.setTime(d);
|
||||
} catch (Exception e) {}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从日期转换
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public Moment fromDate(Date date) {
|
||||
gc.setTime(date);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间获取对象
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public Moment fromTime(String time) {
|
||||
try {
|
||||
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date d = format.parse(time);
|
||||
gc.setTime(d);
|
||||
} catch (Exception e) {}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间+format
|
||||
* @param time
|
||||
* @param formatStr
|
||||
* @return
|
||||
*/
|
||||
public Moment fromTime(String time, String formatStr) {
|
||||
try {
|
||||
DateFormat format = new SimpleDateFormat(formatStr);
|
||||
Date d = format.parse(time);
|
||||
gc.setTime(d);
|
||||
} catch (Exception e) {}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成普通时间 1900-01-01 12:00:00
|
||||
* @return
|
||||
*/
|
||||
public String toSimpleTime() {
|
||||
return year() + "-" + months() + "-" + days() + " " + hours() + ":" + minutes() + ":" + seconds();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成完整时间1900-01-01 12:00:00.000
|
||||
* @return
|
||||
*/
|
||||
public String toFullTime() {
|
||||
return toSimpleTime() + "." + milliseconds();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成日期格式1900-01-01
|
||||
* @return
|
||||
*/
|
||||
public String toSimpleDate() {
|
||||
return year() + "-" + months() + "-" + days();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取date对象
|
||||
* @return
|
||||
*/
|
||||
public Date toDate() {
|
||||
return gc.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数格式化
|
||||
* y年
|
||||
* M月
|
||||
* d日
|
||||
* H时
|
||||
* m分
|
||||
* s秒
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public String format(String format) {
|
||||
return new SimpleDateFormat(format).format(toDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取年份
|
||||
*
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
public int year() {
|
||||
return gc.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置年份
|
||||
*
|
||||
* @param year
|
||||
*/
|
||||
public Moment year(int year) {
|
||||
gc.set(Calendar.YEAR, year);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取月份
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int month() {
|
||||
return gc.get(Calendar.MONTH) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整月份
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String months() {
|
||||
return String.format("%02d", month());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置月份
|
||||
*
|
||||
* @param month
|
||||
* @return
|
||||
*/
|
||||
public Moment month(int month) {
|
||||
if (month > 0 && month <= 12) {
|
||||
gc.set(Calendar.MONTH, month - 1);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置月份
|
||||
*
|
||||
* @param month
|
||||
* @return
|
||||
*/
|
||||
public Moment month(String month) {
|
||||
month(Integer.parseInt(month));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取天
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int day() {
|
||||
return gc.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取完整天
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String days() {
|
||||
return String.format("%02d", day());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置天
|
||||
*
|
||||
* @param day
|
||||
* @return
|
||||
*/
|
||||
public Moment day(int day) {
|
||||
if (day > 0 && day <= 31) {
|
||||
gc.set(Calendar.DAY_OF_MONTH, day);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置天
|
||||
*
|
||||
* @param day
|
||||
* @return
|
||||
*/
|
||||
public Moment day(String day) {
|
||||
day(Integer.parseInt(day));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小时
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int hour() {
|
||||
return gc.get(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取小时
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String hours() {
|
||||
return String.format("%02d", hour());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置小时
|
||||
*
|
||||
* @param hour
|
||||
* @return
|
||||
*/
|
||||
public Moment hour(int hour) {
|
||||
if (hour >= 0 && hour < 24) {
|
||||
gc.set(Calendar.HOUR_OF_DAY, hour);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置小时
|
||||
*
|
||||
* @param hour
|
||||
* @return
|
||||
*/
|
||||
public Moment hour(String hour) {
|
||||
hour(Integer.parseInt(hour));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分钟
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int minute() {
|
||||
return gc.get(Calendar.MINUTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分钟
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String minutes() {
|
||||
return String.format("%02d", minute());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分钟
|
||||
*
|
||||
* @param minute
|
||||
* @return
|
||||
*/
|
||||
public Moment minute(int minute) {
|
||||
if (minute >= 0 && minute < 60) {
|
||||
gc.set(Calendar.MINUTE, minute);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分钟
|
||||
*
|
||||
* @param minute
|
||||
* @return
|
||||
*/
|
||||
public Moment minute(String minute) {
|
||||
minute(Integer.parseInt(minute));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取秒
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int second() {
|
||||
return gc.get(Calendar.SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取秒
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String seconds() {
|
||||
return String.format("%02d", second());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置秒
|
||||
*
|
||||
* @param second
|
||||
* @return
|
||||
*/
|
||||
public Moment second(int second) {
|
||||
if (second >= 0 && second < 60) {
|
||||
gc.set(Calendar.SECOND, second);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置秒
|
||||
*
|
||||
* @param second
|
||||
* @return
|
||||
*/
|
||||
public Moment second(String second) {
|
||||
second(Integer.parseInt(second));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取毫秒
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int millisecond() {
|
||||
return gc.get(Calendar.MILLISECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取毫秒
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String milliseconds() {
|
||||
return String.format("%03d", millisecond());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置毫秒
|
||||
*
|
||||
* @param millisecond
|
||||
* @return
|
||||
*/
|
||||
public Moment millisecond(int millisecond) {
|
||||
if (millisecond >= 0 && millisecond < 1000) {
|
||||
gc.set(Calendar.MILLISECOND, millisecond);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置毫秒
|
||||
*
|
||||
* @param millisecond
|
||||
* @return
|
||||
*/
|
||||
public Moment millisecond(String millisecond) {
|
||||
millisecond(Integer.parseInt(millisecond));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期在本月的第几周
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int weekOfMonth() {
|
||||
return gc.get(Calendar.WEEK_OF_MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期在本年的第几周
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int weekOfYear() {
|
||||
return gc.get(Calendar.WEEK_OF_YEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取星期几
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int dayOfWeek() {
|
||||
int field = gc.get(Calendar.DAY_OF_WEEK);
|
||||
switch (field) {
|
||||
case Calendar.SUNDAY:
|
||||
return 7;
|
||||
case Calendar.MONDAY:
|
||||
return 1;
|
||||
case Calendar.TUESDAY:
|
||||
return 2;
|
||||
case Calendar.WEDNESDAY:
|
||||
return 3;
|
||||
case Calendar.THURSDAY:
|
||||
return 4;
|
||||
case Calendar.FRIDAY:
|
||||
return 5;
|
||||
case Calendar.SATURDAY:
|
||||
return 6;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return gc.getFirstDayOfWeek();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置星期几
|
||||
* @param week
|
||||
* @return
|
||||
*/
|
||||
public Moment dayOfWeek(int week) {
|
||||
switch (week) {
|
||||
case 7:
|
||||
gc.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
|
||||
break;
|
||||
case 1:
|
||||
gc.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||
break;
|
||||
case 2:
|
||||
gc.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
|
||||
break;
|
||||
case 3:
|
||||
gc.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
|
||||
break;
|
||||
case 4:
|
||||
gc.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
|
||||
break;
|
||||
case 5:
|
||||
gc.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
|
||||
break;
|
||||
case 6:
|
||||
gc.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期在本年的第几天
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int dayOfYear() {
|
||||
return gc.get(Calendar.DAY_OF_YEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置日期为本年的第几天
|
||||
*
|
||||
* @param day
|
||||
* @return
|
||||
*/
|
||||
public Moment dayOfYear(int day) {
|
||||
gc.set(Calendar.DAY_OF_YEAR, day);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期所在季度 1月~3月 第一季度 4月~6月 第二季度 7月~9月 第三季度 10月~12月 第四季度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int quarter() {
|
||||
int month = month();
|
||||
switch (month) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
return 1;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
return 2;
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
return 3;
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数获取
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public int get(String key) {
|
||||
switch (key) {
|
||||
case "year":
|
||||
return year();
|
||||
case "month":
|
||||
return month();
|
||||
case "day":
|
||||
case "date":
|
||||
return day();
|
||||
case "hour":
|
||||
return hour();
|
||||
case "minute":
|
||||
return minute();
|
||||
case "second":
|
||||
return second();
|
||||
case "millisecond":
|
||||
return millisecond();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数设置值
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public Moment set(String key, int value) {
|
||||
switch (key) {
|
||||
case "year":
|
||||
year(value);
|
||||
break;
|
||||
case "month":
|
||||
month(value);
|
||||
break;
|
||||
case "day":
|
||||
case "date":
|
||||
day(value);
|
||||
break;
|
||||
case "hour":
|
||||
hour(value);
|
||||
break;
|
||||
case "minute":
|
||||
minute(value);
|
||||
break;
|
||||
case "second":
|
||||
second(value);
|
||||
break;
|
||||
case "millisecond":
|
||||
millisecond(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取millis时间
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long millis() {
|
||||
return gc.getTimeInMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取其中时间最大的那个
|
||||
*
|
||||
* @param moment
|
||||
* @return
|
||||
*/
|
||||
public static Moment max(final Moment... moment) {
|
||||
Moment max = null;
|
||||
if (moment != null && moment.length > 0) {
|
||||
for (Moment tmp : moment) {
|
||||
if (max == null) {
|
||||
max = tmp;
|
||||
}
|
||||
if (max.millis() < tmp.millis()) {
|
||||
max = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取其中时间最小的那个
|
||||
*
|
||||
* @param moment
|
||||
* @return
|
||||
*/
|
||||
public static Moment min(final Moment... moment) {
|
||||
Moment min = null;
|
||||
if (moment != null && moment.length > 0) {
|
||||
for (Moment tmp : moment) {
|
||||
if (min == null) {
|
||||
min = tmp;
|
||||
}
|
||||
if (min.millis() > tmp.millis()) {
|
||||
min = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加指定key的时间
|
||||
* @param number
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Moment add(int amount, String key) {
|
||||
switch (key) {
|
||||
case "years":
|
||||
case "y":
|
||||
gc.add(Calendar.YEAR, amount);
|
||||
break;
|
||||
case "quarters":
|
||||
case "Q":
|
||||
gc.add(Calendar.MONTH, amount * 3);
|
||||
break;
|
||||
case "months":
|
||||
case "M":
|
||||
gc.add(Calendar.MONTH, amount);
|
||||
break;
|
||||
case "weeks":
|
||||
case "w":
|
||||
gc.add(Calendar.WEEK_OF_YEAR, amount);
|
||||
break;
|
||||
case "days":
|
||||
case "d":
|
||||
gc.add(Calendar.DAY_OF_MONTH, amount);
|
||||
break;
|
||||
case "hours":
|
||||
case "h":
|
||||
gc.add(Calendar.HOUR_OF_DAY, amount);
|
||||
break;
|
||||
case "minutes":
|
||||
case "m":
|
||||
gc.add(Calendar.MINUTE, amount);
|
||||
break;
|
||||
case "seconds":
|
||||
case "s":
|
||||
gc.add(Calendar.SECOND, amount);
|
||||
break;
|
||||
case "milliseconds":
|
||||
case "ms":
|
||||
gc.add(Calendar.MILLISECOND, amount);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 减去指定key的时间
|
||||
* @param number
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Moment subtract(int amount, String key) {
|
||||
return add(-amount, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key的开始时间
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Moment startOf(String key) {
|
||||
Moment moment = new Moment( (GregorianCalendar) this.gc.clone());
|
||||
switch (key) {
|
||||
case "year":
|
||||
moment.dayOfYear(1).hour(0).minute(0).second(0).millisecond(0);
|
||||
break;
|
||||
case "month":
|
||||
moment.day(1).hour(0).minute(0).second(0).millisecond(0);
|
||||
break;
|
||||
case "week":
|
||||
moment.dayOfWeek(1).hour(0).minute(0).second(0).millisecond(0);
|
||||
break;
|
||||
case "day":
|
||||
moment.hour(0).minute(0).second(0).millisecond(0);
|
||||
break;
|
||||
case "hour":
|
||||
moment.minute(0).second(0).millisecond(0);
|
||||
case "minute":
|
||||
moment.second(0).millisecond(0);
|
||||
break;
|
||||
case "second":
|
||||
moment.millisecond(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return moment;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key的结束时间
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Moment endOf(String key) {
|
||||
Moment moment = new Moment();
|
||||
switch (key) {
|
||||
case "year":
|
||||
return moment.startOf(key).add(1, "years").subtract(1, "days").hour(23).minute(59).second(59).millisecond(999);
|
||||
case "month":
|
||||
return moment.startOf(key).add(1, "months").subtract(1, "days").hour(23).minute(59).second(59).millisecond(999);
|
||||
case "week":
|
||||
return moment.startOf(key).add(1, "weeks").subtract(1, "days").hour(23).minute(59).second(59).millisecond(999);
|
||||
case "day":
|
||||
return moment.startOf(key).hour(23).minute(59).second(59).millisecond(999);
|
||||
case "hour":
|
||||
return moment.startOf(key).minute(59).second(59).millisecond(999);
|
||||
case "minute":
|
||||
return moment.startOf(key).second(59).millisecond(999);
|
||||
case "second":
|
||||
return moment.startOf(key).millisecond(999);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return moment;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间差值
|
||||
* @param moment
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public int difference(Moment moment, String key) {
|
||||
switch (key) {
|
||||
case "year":
|
||||
return this.year() - moment.year();
|
||||
case "month":
|
||||
return difference(moment, "year") * 12 + (this.month() - moment.month());
|
||||
case "day":
|
||||
return (int) ((this.millis() - moment.millis()) / (24 * 60 * 60 * 1000));
|
||||
case "hour":
|
||||
return (int) ((this.millis() - moment.millis()) / (60 * 60 * 1000));
|
||||
case "minute":
|
||||
return (int) ((this.millis() - moment.millis()) / (60 * 1000));
|
||||
case "second":
|
||||
return (int) ((this.millis() - moment.millis()) / (1000));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 大于另一个日期
|
||||
* @param moment
|
||||
* @return
|
||||
*/
|
||||
public boolean gt(Moment moment) {
|
||||
return (this.millis() > moment.millis()) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小于另一个日期
|
||||
* @param moment
|
||||
* @return
|
||||
*/
|
||||
public boolean lt(Moment moment) {
|
||||
return (this.millis() < moment.millis()) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 大于或者等于另一个日期
|
||||
* @param moment
|
||||
* @return
|
||||
*/
|
||||
public boolean ge(Moment moment) {
|
||||
return (this.millis() >= moment.millis()) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小于或者等于另一个日期
|
||||
* @param moment
|
||||
* @return
|
||||
*/
|
||||
public boolean le(Moment moment) {
|
||||
return (this.millis() <= moment.millis()) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在两个日期之间
|
||||
* @param sMoment
|
||||
* @param eMoment
|
||||
* @return
|
||||
*/
|
||||
public boolean between(Moment sMoment, Moment eMoment) {
|
||||
return (this.ge(sMoment) && this.le(eMoment)) ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package javautils.email;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.util.Properties;
|
||||
|
||||
public class SpringMailUtil {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpringMailUtil.class);
|
||||
|
||||
private String username;
|
||||
private String personal;
|
||||
private String password;
|
||||
private String host;
|
||||
private String defaultEncoding = "UTF-8";
|
||||
|
||||
public SpringMailUtil(String username, String personal, String password, String host) {
|
||||
this.username = username;
|
||||
this.personal = personal;
|
||||
this.password = password;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public boolean send(String to, String subject, String htmlText) {
|
||||
return sendInternal(to, subject, htmlText);
|
||||
}
|
||||
|
||||
public boolean sendInternal(String to, String subject, String htmlText) {
|
||||
try {
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
mailSender.setDefaultEncoding(defaultEncoding);
|
||||
mailSender.setHost(host);
|
||||
mailSender.setUsername(username);
|
||||
mailSender.setPassword(password);
|
||||
Properties properties = new Properties();
|
||||
properties.put("mail.smtp.auth", "true");
|
||||
properties.put("mail.smtp.starttls.enable", "true");
|
||||
properties.put("mail.smtp.host", host);
|
||||
properties.put("mail.smtp.user", username);
|
||||
properties.put("mail.smtp.password", password);
|
||||
properties.put("mail.smtp.port", "587");
|
||||
properties.put("mail.smtp.auth", "true");
|
||||
mailSender.setJavaMailProperties(properties);
|
||||
|
||||
MimeMessage mimeMessage = mailSender.createMimeMessage();
|
||||
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
|
||||
messageHelper.setTo(to);
|
||||
messageHelper.setFrom(username, personal);
|
||||
messageHelper.setSubject(subject);
|
||||
messageHelper.setText(htmlText, true);
|
||||
mailSender.send(mimeMessage);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
logger.error("发送邮件失败!", e == null ? "" : e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package javautils.encrypt;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* 对密码进行加密和验证的类
|
||||
*/
|
||||
public class CipherUtil {
|
||||
|
||||
// 十六进制下数字到字符的映射数组
|
||||
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
|
||||
|
||||
/** * 把inputString加密 */
|
||||
public static String generatePassword(String inputString) {
|
||||
return encodeByMD5(inputString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证输入的密码是否正确
|
||||
*
|
||||
* @param password
|
||||
* 加密后的密码
|
||||
* @param inputString
|
||||
* 输入的字符串
|
||||
* @return 验证结果,TRUE:正确 FALSE:错误
|
||||
*/
|
||||
public static boolean validatePassword(String password, String inputString) {
|
||||
if (password.equals(encodeByMD5(inputString))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** 对字符串进行MD5加密 */
|
||||
private static String encodeByMD5(String originString) {
|
||||
if (originString != null) {
|
||||
try {
|
||||
// 创建具有指定算法名称的信息摘要
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
// 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
|
||||
byte[] results = md.digest(originString.getBytes());
|
||||
// 将得到的字节数组变成字符串返回
|
||||
String resultString = byteArrayToHexString(results);
|
||||
return resultString.toUpperCase();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字节数组为十六进制字符串
|
||||
*
|
||||
* @param 字节数组
|
||||
* @return 十六进制字符串
|
||||
*/
|
||||
private static String byteArrayToHexString(byte[] b) {
|
||||
StringBuffer resultSb = new StringBuffer();
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
resultSb.append(byteToHexString(b[i]));
|
||||
}
|
||||
return resultSb.toString();
|
||||
}
|
||||
|
||||
/** 将一个字节转化成十六进制形式的字符串 */
|
||||
private static String byteToHexString(byte b) {
|
||||
int n = b;
|
||||
if (n < 0)
|
||||
n = 256 + n;
|
||||
int d1 = n / 16;
|
||||
int d2 = n % 16;
|
||||
return hexDigits[d1] + hexDigits[d2];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package javautils.encrypt;
|
||||
|
||||
import sun.misc.BASE64Decoder;
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import java.security.Key;
|
||||
|
||||
/**
|
||||
* DES加密工具类
|
||||
*/
|
||||
public class DESUtil {
|
||||
|
||||
private DESUtil() {
|
||||
|
||||
}
|
||||
|
||||
public static DESUtil getInstance() {
|
||||
return new DESUtil();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据参数生成 KEY
|
||||
*/
|
||||
public Key getKey(String strKey) {
|
||||
Key key = null;
|
||||
try {
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||
DESKeySpec keySpec = new DESKeySpec(strKey.getBytes());
|
||||
keyFactory.generateSecret(keySpec);
|
||||
key = keyFactory.generateSecret(keySpec);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密 String 明文输入 ,String 密文输出
|
||||
*/
|
||||
public String encryptStr(String strMing, String keyStr) {
|
||||
byte[] byteMi = null;
|
||||
byte[] byteMing = null;
|
||||
String strMi = "";
|
||||
BASE64Encoder base64en = new BASE64Encoder();
|
||||
try {
|
||||
byteMing = strMing.getBytes("UTF8");
|
||||
byteMi = encryptByte(byteMing, getKey(keyStr));
|
||||
strMi = base64en.encode(byteMi);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
base64en = null;
|
||||
byteMing = null;
|
||||
byteMi = null;
|
||||
}
|
||||
return strMi;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密 以 String 密文输入 ,String 明文输出
|
||||
*
|
||||
* @param strMi
|
||||
* @return
|
||||
*/
|
||||
public String decryptStr(String strMi, String keyStr) {
|
||||
byte[] byteMing = null;
|
||||
byte[] byteMi = null;
|
||||
String strMing = "";
|
||||
BASE64Decoder base64De = new BASE64Decoder();
|
||||
try {
|
||||
byteMi = base64De.decodeBuffer(strMi);
|
||||
byteMing = decryptByte(byteMi, getKey(keyStr));
|
||||
strMing = new String(byteMing, "UTF8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
base64De = null;
|
||||
byteMing = null;
|
||||
byteMi = null;
|
||||
}
|
||||
return strMing;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密以 byte[] 明文输入 ,byte[] 密文输出
|
||||
*
|
||||
* @param byteS
|
||||
* @return
|
||||
*/
|
||||
private byte[] encryptByte(byte[] byteS, Key key) {
|
||||
byte[] byteFina = null;
|
||||
Cipher cipher;
|
||||
try {
|
||||
cipher = Cipher.getInstance("DES");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
byteFina = cipher.doFinal(byteS);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
cipher = null;
|
||||
}
|
||||
return byteFina;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密以 byte[] 密文输入 , 以 byte[] 明文输出
|
||||
*
|
||||
* @param byteD
|
||||
* @return
|
||||
*/
|
||||
private byte[] decryptByte(byte[] byteD, Key key) {
|
||||
byte[] byteFina = null;
|
||||
Cipher cipher;
|
||||
try {
|
||||
cipher = Cipher.getInstance("DES");
|
||||
cipher.init(Cipher.DECRYPT_MODE, key);
|
||||
byteFina = cipher.doFinal(byteD);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
cipher = null;
|
||||
}
|
||||
return byteFina;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
package javautils.encrypt;
|
||||
|
||||
/**
|
||||
* protect the password user inputed
|
||||
*/
|
||||
public class SHACode {
|
||||
private static final long SH0 = 0x67452301L;
|
||||
private static final long SH1 = 0xefcdab89L;
|
||||
private static final long SH2 = 0x98badcfeL;
|
||||
private static final long SH3 = 0x10325476L;
|
||||
private static final long SH4 = 0xc3d2e1f0L;
|
||||
|
||||
private static final long K0 = 0x5a827999L;
|
||||
private static final long K1 = 0x6ed9eba1L;
|
||||
private static final long K2 = 0x8f1bbcdcL;
|
||||
private static final long K3 = 0xca62c1d6L;
|
||||
|
||||
// df debug 12.11
|
||||
private static long[] W;
|
||||
private static byte[] BW;
|
||||
|
||||
private static int p0, p1, p2, p3, p4;
|
||||
private static long A, B, C, D, E, temp;
|
||||
|
||||
private static long f0(long x, long y, long z) {
|
||||
return (z ^ (x & (y ^ z)));
|
||||
}
|
||||
|
||||
private static long f1(long x, long y, long z) {
|
||||
return (x ^ y ^ z);
|
||||
}
|
||||
|
||||
private static long f2(long x, long y, long z) {
|
||||
return ((x & y) | (z & (x | y)));
|
||||
}
|
||||
|
||||
private static long f3(long x, long y, long z) {
|
||||
return (x ^ y ^ z);
|
||||
}
|
||||
|
||||
private static long S(int n, long X) {
|
||||
long tem = 0;
|
||||
X = X & 0x00000000FFFFFFFF;
|
||||
|
||||
if (n == 1) {
|
||||
tem = ((X >> 31) & 0x00000001);
|
||||
|
||||
}
|
||||
if (n == 5)
|
||||
tem = ((X >> 27) & 0x0000001F);
|
||||
if (n == 30)
|
||||
tem = ((X >> 2) & 0x3FFFFFFF);
|
||||
|
||||
return ((X << n) | tem);
|
||||
|
||||
}
|
||||
|
||||
private static void r0(int f, long K) {
|
||||
|
||||
temp = S(5, A) + f0(B, C, D) + E + W[p0++] + K;
|
||||
E = D;
|
||||
D = C;
|
||||
C = S(30, B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
|
||||
private static void r1(int f, long K) {
|
||||
|
||||
temp = (W[p1++] ^ W[p2++] ^ W[p3++] ^ W[p4++]);
|
||||
|
||||
switch (f) {
|
||||
case 0:
|
||||
temp = S(5, A) + f0(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
|
||||
break;
|
||||
case 1:
|
||||
temp = S(5, A) + f1(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
|
||||
break;
|
||||
case 2:
|
||||
temp = S(5, A) + f2(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
|
||||
break;
|
||||
case 3:
|
||||
temp = S(5, A) + f3(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
|
||||
break;
|
||||
}
|
||||
|
||||
E = D;
|
||||
D = C;
|
||||
C = S(30, B);
|
||||
B = A;
|
||||
A = temp;
|
||||
}
|
||||
|
||||
public static long getCode(String mem) {
|
||||
int i, nread, nbits;
|
||||
int length = mem.toCharArray().length;
|
||||
int hi_length, lo_length;
|
||||
int padded;
|
||||
char[] s;
|
||||
int sp = 0;
|
||||
long h0, h1, h2, h3, h4;
|
||||
W = new long[80];
|
||||
BW = new byte[320];
|
||||
padded = 0;
|
||||
s = mem.toCharArray();
|
||||
h0 = SH0;
|
||||
h1 = SH1;
|
||||
h2 = SH2;
|
||||
h3 = SH3;
|
||||
h4 = SH4;
|
||||
for (hi_length = lo_length = 0;;) {
|
||||
if (length < 64)
|
||||
nread = length;
|
||||
else
|
||||
nread = 64;
|
||||
length -= nread;
|
||||
for (int m = 0; m < nread; m++)
|
||||
BW[m] = (byte) s[sp++];
|
||||
if (nread < 64) {
|
||||
nbits = nread * 8;
|
||||
|
||||
if ((lo_length += nbits) < (long) nbits)
|
||||
hi_length++;
|
||||
if ((nread < 64) && (padded == 0)) {
|
||||
BW[nread++] = (byte) 0x080;
|
||||
padded = 1;
|
||||
}
|
||||
|
||||
for (i = nread; i < 64; i++)
|
||||
BW[i] = 0;
|
||||
|
||||
byte[] tar = new byte[4];
|
||||
for (int z = 0; z < 64; z = z + 4) {
|
||||
for (int y = 0; y < 4; y++)
|
||||
tar[y] = BW[z + y];
|
||||
|
||||
W[z >> 2] = 0;
|
||||
W[z >> 2] = (W[z >> 2] | tar[0]) << 8;
|
||||
W[z >> 2] = (W[z >> 2] | (tar[1] & 0x00FF)) << 8;
|
||||
W[z >> 2] = ((W[z >> 2] | (tar[2] & 0x00FF)) << 8)
|
||||
| (tar[3] & 0x00FF);
|
||||
}
|
||||
|
||||
if (nread <= 56) {
|
||||
W[14] = hi_length;
|
||||
W[15] = lo_length;
|
||||
}
|
||||
} else {
|
||||
if ((lo_length += 512) < 512)
|
||||
hi_length++;
|
||||
|
||||
byte[] tar = new byte[4];
|
||||
for (int z = 0; z < 64; z = z + 4) {
|
||||
for (int y = 0; y < 4; y++)
|
||||
tar[y] = BW[z + y];
|
||||
|
||||
W[z >> 2] = 0;
|
||||
W[z >> 2] = (W[z >> 4] | tar[0]) << 8;
|
||||
W[z >> 2] = (W[z >> 2] | (tar[1] & 0x00FF)) << 8;
|
||||
W[z >> 2] = ((W[z >> 2] | (tar[2] & 0x00FF)) << 8)
|
||||
| (tar[3] & 0x00FF);
|
||||
}
|
||||
}
|
||||
p0 = 0;
|
||||
A = h0;
|
||||
B = h1;
|
||||
C = h2;
|
||||
D = h3;
|
||||
E = h4;
|
||||
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
r0(0, K0);
|
||||
|
||||
p1 = 13;
|
||||
p2 = 8;
|
||||
p3 = 2;
|
||||
p4 = 0;
|
||||
r1(0, K0);
|
||||
r1(0, K0);
|
||||
r1(0, K0);
|
||||
r1(0, K0);
|
||||
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
r1(1, K1);
|
||||
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
r1(2, K2);
|
||||
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
r1(3, K3);
|
||||
|
||||
h0 += A;
|
||||
h1 += B;
|
||||
h2 += C;
|
||||
h3 += D;
|
||||
h4 += E;
|
||||
|
||||
// System.gc();
|
||||
if (nread <= 56)
|
||||
break;
|
||||
}
|
||||
|
||||
W = null;
|
||||
BW = null;
|
||||
s = null;
|
||||
A = 0;
|
||||
B = 0;
|
||||
C = 0;
|
||||
D = 0;
|
||||
E = 0;
|
||||
temp = 0;
|
||||
h4 = 0;
|
||||
h3 = 0;
|
||||
h2 = 0;
|
||||
h1 = 0;
|
||||
p0 = 0;
|
||||
p1 = 0;
|
||||
p2 = 0;
|
||||
p3 = 0;
|
||||
p4 = 0;
|
||||
|
||||
int highBit, lowBit;
|
||||
|
||||
lowBit = (int) (h0 & 0x0FFFF);
|
||||
highBit = (int) ((h0 >> 16) & 0x0FFFFF);
|
||||
h0 = 0;
|
||||
String shaHigh = new String(Integer.toHexString(highBit));
|
||||
|
||||
int leng = shaHigh.length();
|
||||
if (leng > 4) {
|
||||
shaHigh = shaHigh.substring(leng - 4);
|
||||
|
||||
} else if (leng < 4) {
|
||||
for (int m = 0; m < 4 - leng; m++)
|
||||
shaHigh = "0" + shaHigh;
|
||||
}
|
||||
|
||||
String shaLow = new String(Integer.toHexString(lowBit));
|
||||
|
||||
leng = shaLow.length();
|
||||
if (leng > 4) {
|
||||
shaLow = shaLow.substring(leng - 4);
|
||||
|
||||
} else if (leng < 4) {
|
||||
for (int m = 0; m < 4 - leng; m++)
|
||||
shaLow = "0" + shaLow;
|
||||
}
|
||||
return Long.parseLong(shaHigh + shaLow, 16);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package javautils.encrypt;
|
||||
|
||||
import lottery.domains.content.entity.UserBetsOriginal;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang.RandomStringUtils;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/1/15.
|
||||
*/
|
||||
public class UserBetsEncrypt {
|
||||
private static final DESUtil DES = DESUtil.getInstance();
|
||||
private static final String DES_KEY = "#$ddw4FFWfg#GR0(DSFW@#?!@#!@#$C$$3GhyUhb";
|
||||
|
||||
public static String encryptCertification(String certification) {
|
||||
return DES.encryptStr(certification, DES_KEY);
|
||||
}
|
||||
|
||||
public static String getRandomCertification() {
|
||||
return RandomStringUtils.random(10, true, true);
|
||||
}
|
||||
|
||||
public static String getIdentification(UserBetsOriginal original, String certification) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
int point = Double.valueOf(original.getPoint()).intValue();
|
||||
int money = Double.valueOf(original.getMoney()).intValue();
|
||||
|
||||
sb.append(original.getId())
|
||||
.append(original.getBillno())
|
||||
.append(original.getUserId())
|
||||
.append(original.getType())
|
||||
.append(original.getLotteryId())
|
||||
.append(original.getExpect())
|
||||
.append(original.getRuleId())
|
||||
.append(DigestUtils.md5Hex(original.getCodes()))
|
||||
.append(original.getNums())
|
||||
.append(original.getModel())
|
||||
.append(original.getMultiple())
|
||||
.append(original.getCode())
|
||||
.append(point)
|
||||
.append(money)
|
||||
.append(original.getTime())
|
||||
.append(original.getStopTime())
|
||||
.append(original.getOpenTime())
|
||||
.append(original.getStatus())
|
||||
.append(original.getOpenCode())
|
||||
.append(original.getPrizeMoney())
|
||||
.append(original.getPrizeTime())
|
||||
.append(original.getChaseBillno())
|
||||
.append(original.getChaseBillno())
|
||||
.append(original.getPlanBillno())
|
||||
.append(original.getRewardMoney())
|
||||
.append(certification);
|
||||
|
||||
String thisData = sb.toString();
|
||||
return DigestUtils.md5Hex(thisData + certification);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package javautils.jdbc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页类
|
||||
* @author root
|
||||
*
|
||||
*/
|
||||
public class PageList {
|
||||
|
||||
private List<?> list;
|
||||
private int count;
|
||||
|
||||
public PageList() {
|
||||
this.list = new ArrayList<>();
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
public PageList(List<?> list, int count) {
|
||||
this.list = list;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package javautils.jdbc.helper;
|
||||
|
||||
import net.sf.json.JSONArray;
|
||||
import net.sf.json.JSONObject;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
|
||||
public class JDBCHelper {
|
||||
|
||||
public final static String MYSQL = "com.mysql.jdbc.Driver";
|
||||
|
||||
public static Connection openConnection(String url, String username,
|
||||
String password, String type) {
|
||||
Connection conn = null;
|
||||
try {
|
||||
Class.forName(type);
|
||||
conn = DriverManager.getConnection(url, username, password);
|
||||
} catch (Exception e) {}
|
||||
return conn;
|
||||
}
|
||||
|
||||
public static boolean executeUpdate(String sql, Connection conn) {
|
||||
boolean flag = false;
|
||||
if (conn != null) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = conn.prepareStatement(sql);
|
||||
int count = pst.executeUpdate();
|
||||
flag = count > 0 ? true : false;
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
try {
|
||||
if (pst != null) pst.close();
|
||||
if (conn != null) conn.close();
|
||||
} catch (SQLException e) {}
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static JSONArray executeQuery(String sql, Connection conn) {
|
||||
JSONArray list = null;
|
||||
if (conn != null) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = conn.prepareStatement(sql);
|
||||
ResultSet rs = pst.executeQuery();
|
||||
list = toJsonArray(rs);
|
||||
} catch (Exception e) {} finally {
|
||||
try {
|
||||
if (pst != null) pst.close();
|
||||
if (conn != null) conn.close();
|
||||
} catch (SQLException e) {}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static JSONArray toJsonArray(ResultSet rs) throws Exception {
|
||||
JSONArray list = new JSONArray();
|
||||
if (rs != null) {
|
||||
ResultSetMetaData metaData = rs.getMetaData();
|
||||
int columnCount = metaData.getColumnCount();
|
||||
while (rs.next()) {
|
||||
JSONObject obj = new JSONObject();
|
||||
for (int i = 0; i < columnCount; i++) {
|
||||
String columnName = metaData.getColumnLabel(i + 1);
|
||||
String value = rs.getString(columnName);
|
||||
obj.put(columnName, value);
|
||||
}
|
||||
list.add(obj);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* java:comp/env/jdbc/books
|
||||
* @param jndi
|
||||
* @return
|
||||
*/
|
||||
public static Connection openConnection(String jndi) {
|
||||
Connection conn = null;
|
||||
try {
|
||||
Context context = new InitialContext();
|
||||
DataSource source = (DataSource) context.lookup(jndi);
|
||||
conn = source.getConnection();
|
||||
} catch (Exception e) {}
|
||||
return conn;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String url = "jdbc:mysql://192.168.1.111:3306/test?useUnicode=true&characterEncoding=utf-8";
|
||||
String username = "root";
|
||||
String password = "root";
|
||||
Connection conn = JDBCHelper.openConnection(url, username, password, JDBCHelper.MYSQL);
|
||||
String sql = "select * from user";
|
||||
JDBCHelper.executeQuery(sql, conn);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,605 @@
|
||||
package javautils.jdbc.hibernate;
|
||||
|
||||
import javautils.jdbc.PageList;
|
||||
import javautils.jdbc.util.BatchSQLUtil;
|
||||
import org.hibernate.*;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
import org.hibernate.criterion.Projection;
|
||||
import org.hibernate.criterion.Projections;
|
||||
import org.hibernate.jdbc.Work;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@SuppressWarnings("unchecked")
|
||||
public class HibernateSuperDao<T> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HibernateSuperDao.class);
|
||||
|
||||
@Autowired
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
public Session getCurrentSession() {
|
||||
return sessionFactory.getCurrentSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
public boolean save(final Object entity) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
getCurrentSession().save(entity);
|
||||
flag = true;
|
||||
} catch (Exception e) {
|
||||
logger.error("保存实体类异常", e);
|
||||
throw e;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
public boolean update(final Object entity) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
getCurrentSession().update(entity);
|
||||
flag = true;
|
||||
} catch (Exception e) {
|
||||
logger.error("更新实体类异常", e);
|
||||
throw e;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* @param sql sql
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
public int updateBySql(final String sql) {
|
||||
try {
|
||||
SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
|
||||
return sqlQuery.executeUpdate();
|
||||
} catch (Exception e) {
|
||||
logger.error("更新实体类异常", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
* @param hql
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
public boolean update(final String hql, final Object[] values) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
query.setParameter(String.valueOf(i), values[i]);
|
||||
}
|
||||
int result = query.executeUpdate();
|
||||
flag = result > 0 ? true : false;
|
||||
} catch (Exception e) {
|
||||
logger.error("更新实体类异常", e);
|
||||
throw e;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int updateByHql(final String hql) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
int result = query.executeUpdate();
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
logger.error("更新实体类异常", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public boolean delete(final Object entity) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
getCurrentSession().delete(entity);
|
||||
flag = true;
|
||||
} catch (Exception e) {
|
||||
logger.error("删除实体类异常", e);
|
||||
throw e;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param hql
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
public boolean delete(final String hql, final Object[] values) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
query.setParameter(String.valueOf(i), values[i]);
|
||||
}
|
||||
int result = query.executeUpdate();
|
||||
flag = result > 0 ? true : false;
|
||||
} catch (Exception e) {
|
||||
logger.error("删除实体类异常", e);
|
||||
throw e;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param hql
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> list(final String hql) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param hql
|
||||
* @param start
|
||||
* @param limit
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> list(final String hql, final int start, final int limit) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
if(start >= 0 && limit > 0) {
|
||||
query.setFirstResult(start);
|
||||
query.setMaxResults(limit);
|
||||
}
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 唯一结果查询
|
||||
* @param hql
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Object unique(final String hql) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
return query.uniqueResult();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 唯一结果查询
|
||||
* @param hql
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Object unique(final String hql, final Object[] values) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
query.setParameter(String.valueOf(i), values[i]);
|
||||
}
|
||||
return query.uniqueResult();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param hql
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> list(final String hql, final Object[] values) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
query.setParameter(String.valueOf(i), values[i]);
|
||||
}
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param hql
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<?> listObject(final String hql, final Object[] values, final int start, final int limit) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
query.setParameter(String.valueOf(i), values[i]);
|
||||
}
|
||||
if(start >= 0 && limit > 0) {
|
||||
query.setFirstResult(start);
|
||||
query.setMaxResults(limit);
|
||||
}
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param hql
|
||||
* @param values
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<?> listObject(final String hql, final Object[] values) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
query.setParameter(String.valueOf(i), values[i]);
|
||||
}
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询
|
||||
* @param hql
|
||||
* @param values
|
||||
* @param start
|
||||
* @param limit
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> list(final String hql, final Object[] values, final int start, final int limit) {
|
||||
try {
|
||||
Query query = getCurrentSession().createQuery(hql);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
query.setParameter(String.valueOf(i), values[i]);
|
||||
}
|
||||
if(start >= 0 && limit > 0) {
|
||||
query.setFirstResult(start);
|
||||
query.setMaxResults(limit);
|
||||
}
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL查询
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<?> findWithSql(final String sql) {
|
||||
try {
|
||||
SQLQuery query = getCurrentSession().createSQLQuery(sql);
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL查询
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Object uniqueWithSqlCount(final String sql) {
|
||||
try {
|
||||
SQLQuery query = getCurrentSession().createSQLQuery(sql);
|
||||
return query.uniqueResult();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param querySql
|
||||
* @param countSql
|
||||
* @param start
|
||||
* @param limit
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public PageList findPageList(final String querySql, final String countSql, final int start, final int limit) {
|
||||
try {
|
||||
PageList pList = new PageList();
|
||||
// 查询总数
|
||||
SQLQuery countQuery = getCurrentSession().createSQLQuery(countSql);
|
||||
Number result = (Number) countQuery.uniqueResult();
|
||||
int count = result.intValue();
|
||||
pList.setCount(count);
|
||||
// 查询集合
|
||||
SQLQuery listQuery = getCurrentSession().createSQLQuery(querySql);
|
||||
if(start >= 0 && limit > 0) {
|
||||
listQuery.setFirstResult(start);
|
||||
listQuery.setMaxResults(limit);
|
||||
}
|
||||
List<T> list = listQuery.list();
|
||||
pList.setList(list);
|
||||
return pList;
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param clazz
|
||||
* @param criterions
|
||||
* @param orders
|
||||
* @param start
|
||||
* @param limit
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public PageList findPageList(final Class<T> clazz, String propertyName, final List<Criterion> criterions, final List<Order> orders, final int start, final int limit) {
|
||||
try {
|
||||
PageList pList = new PageList();
|
||||
Criteria criteria = getCurrentSession().createCriteria(clazz);
|
||||
for (Criterion criterion : criterions) {
|
||||
criteria.add(criterion);
|
||||
}
|
||||
if (orders != null && orders.size() > 0) {
|
||||
for (Order order : orders) {
|
||||
criteria.addOrder(order);
|
||||
}
|
||||
}
|
||||
|
||||
// 查询总数
|
||||
criteria.setProjection(Projections.count(propertyName));
|
||||
Number result = (Number) criteria.uniqueResult();
|
||||
int count = result.intValue();
|
||||
pList.setCount(count);
|
||||
criteria.setProjection(null);
|
||||
// 查询集合
|
||||
if(start >= 0 && limit > 0) {
|
||||
criteria.setFirstResult(start);
|
||||
criteria.setMaxResults(limit);
|
||||
}
|
||||
List<T> list = criteria.list();
|
||||
pList.setList(list);
|
||||
return pList;
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public PageList findPageList(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final int start, final int limit) {
|
||||
try {
|
||||
PageList pList = new PageList();
|
||||
Criteria criteria = getCurrentSession().createCriteria(clazz);
|
||||
for (Criterion criterion : criterions) {
|
||||
criteria.add(criterion);
|
||||
}
|
||||
if (orders != null && orders.size() > 0) {
|
||||
for (Order order : orders) {
|
||||
criteria.addOrder(order);
|
||||
}
|
||||
}
|
||||
// 查询总数
|
||||
criteria.setProjection(Projections.rowCount());
|
||||
Number result = (Number) criteria.uniqueResult();
|
||||
int count = result.intValue();
|
||||
pList.setCount(count);
|
||||
criteria.setProjection(null);
|
||||
// 查询集合
|
||||
if(start >= 0 && limit > 0) {
|
||||
criteria.setFirstResult(start);
|
||||
criteria.setMaxResults(limit);
|
||||
}
|
||||
List<T> list = criteria.list();
|
||||
pList.setList(list);
|
||||
return pList;
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Criteria查询
|
||||
* @param clazz
|
||||
* @param criterions
|
||||
* @param orders
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders) {
|
||||
try {
|
||||
Criteria criteria = getCurrentSession().createCriteria(clazz);
|
||||
for (Criterion criterion : criterions) {
|
||||
criteria.add(criterion);
|
||||
}
|
||||
if (orders != null && orders.size() > 0) {
|
||||
for (Order order : orders) {
|
||||
criteria.addOrder(order);
|
||||
}
|
||||
}
|
||||
return criteria.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Criteria查询
|
||||
* @param clazz
|
||||
* @param criterions
|
||||
* @param orders
|
||||
* @param limit
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<T> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final int start, final int limit) {
|
||||
try {
|
||||
Criteria criteria = getCurrentSession().createCriteria(clazz);
|
||||
for (Criterion criterion : criterions) {
|
||||
criteria.add(criterion);
|
||||
}
|
||||
if (orders != null && orders.size() > 0) {
|
||||
for (Order order : orders) {
|
||||
criteria.addOrder(order);
|
||||
}
|
||||
}
|
||||
if(start >= 0 && limit > 0) {
|
||||
criteria.setFirstResult(start);
|
||||
criteria.setMaxResults(limit);
|
||||
}
|
||||
return criteria.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Criteria查询
|
||||
* @param clazz
|
||||
* @param criterions
|
||||
* @param orders
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<?> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final Projection projection) {
|
||||
try {
|
||||
Criteria criteria = getCurrentSession().createCriteria(clazz);
|
||||
for (Criterion criterion : criterions) {
|
||||
criteria.add(criterion);
|
||||
}
|
||||
if (orders != null && orders.size() > 0) {
|
||||
for (Order order : orders) {
|
||||
criteria.addOrder(order);
|
||||
}
|
||||
}
|
||||
criteria.setProjection(projection);
|
||||
return criteria.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Criteria查询
|
||||
* @param clazz
|
||||
* @param criterions
|
||||
* @param orders
|
||||
* @param projection
|
||||
* @param start
|
||||
* @param limit
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<?> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final Projection projection, final int start, final int limit) {
|
||||
try {
|
||||
Criteria criteria = getCurrentSession().createCriteria(clazz);
|
||||
for (Criterion criterion : criterions) {
|
||||
criteria.add(criterion);
|
||||
}
|
||||
if (orders != null && orders.size() > 0) {
|
||||
for (Order order : orders) {
|
||||
criteria.addOrder(order);
|
||||
}
|
||||
}
|
||||
criteria.setProjection(projection);
|
||||
if(start >= 0 && limit > 0) {
|
||||
criteria.setFirstResult(start);
|
||||
criteria.setMaxResults(limit);
|
||||
}
|
||||
return criteria.list();
|
||||
} catch (Exception e) {
|
||||
logger.error("查询出错", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public boolean doWork(final String sql, final List<Object[]> params) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
getCurrentSession().doWork(new Work() {
|
||||
@Override
|
||||
public void execute(Connection connection) throws SQLException {
|
||||
BatchSQLUtil sqlUtil = new BatchSQLUtil(connection, sql);
|
||||
for (Object[] param : params) {
|
||||
sqlUtil.addCount(param);
|
||||
}
|
||||
sqlUtil.commit();
|
||||
}
|
||||
});
|
||||
flag = true;
|
||||
} catch (Exception e) {
|
||||
logger.error("doWork出错", e);
|
||||
throw e;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package javautils.jdbc.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class BatchSQLUtil {
|
||||
|
||||
public static Logger logger = LoggerFactory.getLogger(BatchSQLUtil.class);
|
||||
|
||||
private Connection conn;
|
||||
private PreparedStatement ps;
|
||||
|
||||
public BatchSQLUtil(Connection conn, String sql) {
|
||||
try {
|
||||
this.conn = conn;
|
||||
this.conn.setAutoCommit(false);
|
||||
ps = this.conn.prepareStatement(sql);
|
||||
} catch (Exception e) {
|
||||
logger.error("BatchSQLUtil异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCount(Object[] param) {
|
||||
try {
|
||||
for (int i = 0; i < param.length; i++) {
|
||||
ps.setObject(i + 1, param[i]);
|
||||
}
|
||||
ps.addBatch();
|
||||
} catch (SQLException e) {
|
||||
logger.error("addCount异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
try {
|
||||
ps.executeBatch();
|
||||
conn.commit();
|
||||
ps.clearBatch();
|
||||
} catch (SQLException e) {
|
||||
logger.error("commit异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
ps.close();
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
logger.error("close异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package javautils.jdbc.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SQLUtil {
|
||||
|
||||
public static final Logger logger = LoggerFactory.getLogger(SQLUtil.class);
|
||||
|
||||
// ------------------------------- 增删改通用 -------------------------------//
|
||||
public boolean aduSql(Connection conn, String sql) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
if (conn != null) {
|
||||
PreparedStatement ps = conn.prepareStatement(sql);
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
flag = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("aduSql异常", e);
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static boolean aduSql(Connection conn, String sql, Object[] params) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
if (conn != null) {
|
||||
PreparedStatement ps = conn.prepareStatement(sql);
|
||||
if (params != null) {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
ps.setObject(i + 1, params[i]);
|
||||
}
|
||||
}
|
||||
ps.executeUpdate();
|
||||
flag = true;
|
||||
ps.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("aduSql异常", e);
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
public static List<Object[]> exList(Connection conn, String sql, Object params[]) {
|
||||
ArrayList<Object[]> list = new ArrayList<Object[]>();
|
||||
try {
|
||||
if (conn != null) {
|
||||
PreparedStatement ps = conn.prepareStatement(sql);
|
||||
if (params != null) {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
ps.setObject(i + 1, params[i]);
|
||||
}
|
||||
}
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
int columns = rs.getMetaData().getColumnCount();
|
||||
Object[] objArr = new Object[columns];
|
||||
for (int i = 0; i < columns; i++) {
|
||||
objArr[i] = rs.getObject(i + 1);
|
||||
}
|
||||
list.add(objArr);
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("exList异常", e);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package javautils.list;
|
||||
|
||||
import javautils.StringUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ListUtil {
|
||||
|
||||
/**
|
||||
* 高性能删除全部
|
||||
*/
|
||||
public static HashSet<String> transToHashSet(String[] strs){
|
||||
if (strs == null || strs.length <= 0) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
HashSet<String> results = new HashSet<>();
|
||||
for (int i = 0; i < strs.length; i++) {
|
||||
results.add(strs[i]);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* 高性能删除全部
|
||||
*/
|
||||
public static LinkedList removeAll(LinkedList src, LinkedList list){
|
||||
if (src == null || src.isEmpty() || list == null || list.isEmpty()) {
|
||||
return src;
|
||||
}
|
||||
|
||||
HashSet oth = new HashSet(list);
|
||||
return removeAll(src, oth);
|
||||
}
|
||||
|
||||
/**
|
||||
* 高性能删除全部
|
||||
*/
|
||||
public static LinkedList removeAll(LinkedList src, HashSet oth){
|
||||
if (src == null || src.isEmpty() || oth == null || oth.isEmpty()) {
|
||||
return src;
|
||||
}
|
||||
|
||||
Iterator iter = src.iterator();//采用Iterator迭代器进行数据的操作
|
||||
while(iter.hasNext()){
|
||||
if(oth.contains(iter.next())){
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 高性能取交集
|
||||
*/
|
||||
public static LinkedList<String> retainAll(LinkedList<String> list1, LinkedList<String> list2){
|
||||
if (list1 == null || list1.isEmpty()) {
|
||||
return new LinkedList();
|
||||
}
|
||||
if (list2 == null || list2.isEmpty()) {
|
||||
return new LinkedList();
|
||||
}
|
||||
|
||||
HashSet<String> retain = new HashSet<>();
|
||||
|
||||
Iterator<String> iter1 = list1.iterator();//采用Iterator迭代器进行数据的操作
|
||||
Iterator<String> iter2 = list2.iterator();//采用Iterator迭代器进行数据的操作
|
||||
HashSet<String> oth1 = new HashSet(list1);
|
||||
HashSet<String> oth2 = new HashSet(list2);
|
||||
|
||||
// list1在list2中有的
|
||||
while (iter1.hasNext()) {
|
||||
String val = iter1.next();
|
||||
if (oth2.contains(val)) {
|
||||
retain.add(val);
|
||||
}
|
||||
}
|
||||
// list2在list1中有的
|
||||
while (iter2.hasNext()) {
|
||||
String val = iter2.next();
|
||||
if (oth1.contains(val)) {
|
||||
retain.add(val);
|
||||
}
|
||||
}
|
||||
|
||||
return new LinkedList(retain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Object数组转int数组
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public static int[] transObjectToInt(Object[] o) {
|
||||
int[] t = new int[o.length];
|
||||
for (int i = 0; i < o.length; i++) {
|
||||
if(o[i] instanceof Integer) {
|
||||
t[i] = (Integer)o[i];
|
||||
}
|
||||
if(o[i] instanceof String) {
|
||||
String s = (String)o[i];
|
||||
if(StringUtil.isIntegerString(s)) {
|
||||
t[i] = Integer.parseInt(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 集合转成String
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static String transListToString(List<?> list) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (Object obj : list) {
|
||||
sb.append(String.valueOf(obj) + ", ");
|
||||
}
|
||||
if(list.size() > 0) {
|
||||
return sb.substring(0, sb.length() - 2);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,42 @@
|
||||
package javautils.map;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/3/6.
|
||||
*/
|
||||
public class MapUtil {
|
||||
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueAsc(Map<K, V> map) {
|
||||
List<Map.Entry<K, V>> list =
|
||||
new LinkedList<>(map.entrySet());
|
||||
Collections.sort(list, new Comparator<Map.Entry<K,V>>() {
|
||||
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
|
||||
return (o1.getValue()).compareTo(o2.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
Map<K, V> result = new LinkedHashMap<K, V>();
|
||||
for (Map.Entry<K, V> entry : list) {
|
||||
result.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueDesc(Map<K, V> map) {
|
||||
List<Map.Entry<K, V>> list =
|
||||
new LinkedList<>(map.entrySet());
|
||||
Collections.sort(list, new Comparator<Map.Entry<K,V>>() {
|
||||
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
|
||||
return (o2.getValue()).compareTo(o1.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
Map<K, V> result = new LinkedHashMap<K, V>();
|
||||
for (Map.Entry<K, V> entry : list) {
|
||||
result.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package javautils.math;
|
||||
|
||||
|
||||
import javautils.StringUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Description:组合算法 从M个数中取出N个数,无顺序
|
||||
* 二维Object数组
|
||||
* @author :royoan
|
||||
* @since :2014-6-12 下午10:22:22
|
||||
* @version :0.0.1
|
||||
*/
|
||||
public class CombinationAlgorithm {
|
||||
/* 原M个数据数组 */
|
||||
private Object[] src;
|
||||
|
||||
/* src数组的长度 */
|
||||
private int m;
|
||||
|
||||
/* 需要获取N个数 */
|
||||
private int n;
|
||||
|
||||
//临时变量,obj的行数
|
||||
private int objLineIndex;
|
||||
|
||||
/* 存放结果的二维数组 */
|
||||
public Object[][] obj;
|
||||
|
||||
public CombinationAlgorithm(Object[] src, int getNum) {
|
||||
this.src = src;
|
||||
m = src.length;
|
||||
n = getNum;
|
||||
|
||||
/* 初始化 */
|
||||
objLineIndex = 0;
|
||||
obj = new Object[combination(m,n)][n];
|
||||
|
||||
Object[] tmp = new Object[n];
|
||||
combine(src, 0, 0, n, tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 计算 C(m,n)个数 = (m!)/(n!*(m-n)!)
|
||||
* </p>
|
||||
* 从M个数中选N个数,函数返回有多少种选法 参数 m 必须大于等于 n m = 0; n = 0; retuan 1;
|
||||
*
|
||||
* @param m
|
||||
* @param n
|
||||
* @return
|
||||
* @since royoan 2014-6-13 下午8:25:33
|
||||
*/
|
||||
public int combination(int m, int n) {
|
||||
if (m < n)
|
||||
return 0; // 如果总数小于取出的数,直接返回0
|
||||
|
||||
int k = 1;
|
||||
int j = 1;
|
||||
// 该种算法约掉了分母的(m-n)!,这样分子相乘的个数就是有n个了
|
||||
for (int i = n; i >= 1; i--) {
|
||||
k = k * m;
|
||||
j = j * n;
|
||||
m--;
|
||||
n--;
|
||||
}
|
||||
return k / j;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> 递归算法,把结果写到obj二维数组对象 </p>
|
||||
* @param src
|
||||
* @param srcIndex
|
||||
* @param i
|
||||
* @param n
|
||||
* @param tmp
|
||||
* @since royoan 2014-6-15 上午11:22:24
|
||||
*/
|
||||
private void combine(Object src[], int srcIndex, int i, int n, Object[] tmp) {
|
||||
int j;
|
||||
for (j = srcIndex; j < src.length - (n - 1); j++ ) {
|
||||
tmp[i] = src[j];
|
||||
if (n == 1) {
|
||||
//System.out.println(Arrays.toString(tmp));
|
||||
System.arraycopy(tmp, 0, obj[objLineIndex], 0, tmp.length);
|
||||
//obj[objLineIndex] = tmp;
|
||||
objLineIndex ++;
|
||||
} else {
|
||||
n--;
|
||||
i++;
|
||||
combine(src, j+1, i, n, tmp);
|
||||
n++;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Object[][] getResutl() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用法实例
|
||||
* @param args
|
||||
* @throws Exception
|
||||
* @since royoan 2014-6-15 下午8:21:05
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Integer[] a = new Integer[]{1,2,3,4,5,6};
|
||||
// CombinationAlgorithm ca = new CombinationAlgorithm(a, 3);
|
||||
//
|
||||
// Object[][] c = ca.getResutl();
|
||||
// for (int i = 0; i < c.length; i++) {
|
||||
// System.out.println(Arrays.toString(c[i]));
|
||||
// }
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
String[] a = new String[]{"1", "2", "3", "4", "5"};
|
||||
CombinationAlgorithm ca = new CombinationAlgorithm(a, 3);
|
||||
|
||||
Object[][] c = ca.getResutl();
|
||||
}
|
||||
long spent = System.currentTimeMillis() - start;
|
||||
System.out.println("10万次耗时:" + spent);
|
||||
// for (int i = 0; i < c.length; i++) {
|
||||
// System.out.println(Arrays.toString(c[i]));
|
||||
// }
|
||||
|
||||
String[] a = new String[]{"1", "2", "3", "4", "5"};
|
||||
CombinationAlgorithm ca = new CombinationAlgorithm(a, 3);
|
||||
|
||||
Object[][] c = ca.getResutl();
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
System.out.println(StringUtil.transArrayToString(c[i]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package javautils.math;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
|
||||
public class MathUtil {
|
||||
|
||||
public static boolean inRound(double value, double min, double max) {
|
||||
return value >= min && value <= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* double 相加 +
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static double add(double a, double b) {
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(a));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(b));
|
||||
return b1.add(b2).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* double 相减 -
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static double subtract(double a, double b) {
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(a));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(b));
|
||||
return b1.subtract(b2).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* double 相乘 *
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static double multiply(double a, double b) {
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(a));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(b));
|
||||
return b1.multiply(b2).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* double 相除 /
|
||||
* @param v1
|
||||
* @param v2
|
||||
* @param scale
|
||||
* @return
|
||||
*/
|
||||
public static double divide(double v1, double v2, int scale) {
|
||||
BigDecimal b1 = new BigDecimal(Double.toString(v1));
|
||||
BigDecimal b2 = new BigDecimal(Double.toString(v2));
|
||||
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_DOWN).doubleValue();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(divide(1.2134,2312.23456,6));
|
||||
System.out.println(add(12.9, 0.101));
|
||||
|
||||
Double d = new Double(8.747470732E7);
|
||||
DecimalFormat format = new DecimalFormat("##.0000");
|
||||
System.out.println(format.format(d));
|
||||
}
|
||||
|
||||
public static double decimalFormat(BigDecimal bd, int point) {
|
||||
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).doubleValue();
|
||||
}
|
||||
|
||||
public static double doubleFormat(double d, int point) {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(d);
|
||||
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).doubleValue();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public static double StringFormat(String d, int point) {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(d);
|
||||
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).doubleValue();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return 0.00;
|
||||
}
|
||||
|
||||
public static float floatFormat(float f, int point) {
|
||||
try {
|
||||
BigDecimal bd = new BigDecimal(f);
|
||||
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).floatValue();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package javautils.math;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 排列算法
|
||||
* Created by Nick on 2016/11/27.
|
||||
*/
|
||||
public class PermutationUtil {
|
||||
public static void main(String args[]) throws Exception {
|
||||
// String[] str = {"-", "-", "1","2","3"};
|
||||
// List<Object[]> objects = permutation("799".split(""));
|
||||
// for (Object[] object : objects) {
|
||||
// System.out.println(Arrays.toString(object));
|
||||
// }
|
||||
// System.out.println(objects.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 求某一组元素的排列列表,如123,可以排成123 132 213 231 321 312,元素一般5个以内就好,不然有性能瓶颈
|
||||
*/
|
||||
public static List<Object[]> permutation(Object[] objs) {
|
||||
if (objs.length > 5) {
|
||||
System.out.println("PermutationUtil.permutation排列元素不要超过5个,会有性能瓶颈");
|
||||
}
|
||||
|
||||
return doPermutation(objs, 0, objs.length - 1);
|
||||
}
|
||||
|
||||
private static List<Object[]> doPermutation(Object[] objs , int first,int end) {
|
||||
if (objs == null || objs.length <= 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<Object[]> result = new ArrayList<>();
|
||||
//输出str[first..end]的所有排列方式
|
||||
if(first == end) { //输出一个排列方式
|
||||
Object[] permuration = new Object[objs.length];
|
||||
int count = 0;
|
||||
for(int j=0; j<= end ;j++) {
|
||||
permuration[count++] =objs[j];
|
||||
}
|
||||
result.add(permuration);
|
||||
}
|
||||
|
||||
for(int i = first; i <= end ; i++) {
|
||||
swap(objs, i, first);
|
||||
List<Object[]> subResult = doPermutation(objs, first + 1, end);//固定好当前一位,继续排列后面的
|
||||
result.addAll(subResult);
|
||||
swap(objs, i, first);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void swap(Object[] objs, int i, int first) {
|
||||
Object tmp;
|
||||
tmp = objs[first];
|
||||
objs[first] = objs[i];
|
||||
objs[i] = tmp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package javautils.random;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/3/11.
|
||||
*/
|
||||
public final class RandomUtil {
|
||||
private RandomUtil(){}
|
||||
|
||||
/**
|
||||
* 从min - max 里随机出n个不重复的数字
|
||||
* @param min 最小数值
|
||||
* @param max 最大数值
|
||||
* @param n 生成多少个
|
||||
*/
|
||||
public static List<Integer> randomUniqueNumbers(int min, int max, int n) {
|
||||
List<Integer> list = new ArrayList<>();
|
||||
for (int i=min; i<=max; i++) {
|
||||
list.add(new Integer(i));
|
||||
}
|
||||
Collections.shuffle(list);
|
||||
|
||||
List<Integer> result = new ArrayList<>();
|
||||
for (int i=0; i<n; i++) {
|
||||
Integer value = list.get(i);
|
||||
result.add(value);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int count = 10000;
|
||||
|
||||
List<Integer> result = randomUniqueNumbers(0, 99999, count);
|
||||
|
||||
HashSet<Integer> resultChecker = new HashSet<>(result);
|
||||
|
||||
System.out.println("是否是正确的结果"+ (resultChecker.size() == count));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 装载并执行Lua Script,
|
||||
*
|
||||
* 如果服务器上因为集群多台服务器或重启等原因没有装载script,会自动重新装载后重试。
|
||||
*
|
||||
* 因为涉及到的key未知,暂时不支持Sharding。
|
||||
*/
|
||||
public class JedisScriptExecutor {
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisScriptExecutor.class);
|
||||
|
||||
private JedisTemplate jedisTemplate;
|
||||
|
||||
private String script;
|
||||
private String sha1;
|
||||
|
||||
public JedisScriptExecutor(JedisPool jedisPool) {
|
||||
this.jedisTemplate = new JedisTemplate(jedisPool);
|
||||
}
|
||||
|
||||
public JedisScriptExecutor(JedisTemplate jedisTemplate) {
|
||||
this.jedisTemplate = jedisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 装载Lua Script。
|
||||
* 如果Script出错,抛出JedisDataException。
|
||||
*/
|
||||
public void load(final String scriptContent) throws JedisDataException {
|
||||
sha1 = jedisTemplate.execute(new JedisTemplate.JedisAction<String>() {
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.scriptLoad(scriptContent);
|
||||
}
|
||||
});
|
||||
script = scriptContent;
|
||||
|
||||
logger.debug("Script \"{}\" had been loaded as {}", scriptContent, sha1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件加载Lua Script, 文件路径格式为Spring Resource的格式.
|
||||
*/
|
||||
public void loadFromFile(final String scriptPath) throws JedisDataException {
|
||||
String scriptContent;
|
||||
try {
|
||||
Resource resource = new DefaultResourceLoader().getResource(scriptPath);
|
||||
scriptContent = FileUtils.readFileToString(resource.getFile(), "UTF-8");
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException(scriptPath + " is not exist.", e);
|
||||
}
|
||||
|
||||
load(scriptContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Lua Script, 如果Redis服务器上还没装载Script则自动装载并重试。
|
||||
* keys与args不允许为null.
|
||||
*/
|
||||
public Object execute(final String[] keys, final String[] args) throws IllegalArgumentException {
|
||||
Assert.notNull(keys, "keys can't be null.");
|
||||
Assert.notNull(args, "args can't be null.");
|
||||
return execute(Arrays.asList(keys), Arrays.asList(args));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行Lua Script, 如果Redis服务器上还没装载Script则自动装载并重试。
|
||||
* keys与args不允许为null.
|
||||
*/
|
||||
public Object execute(final List<String> keys, final List<String> args) throws IllegalArgumentException {
|
||||
Assert.notNull(keys, "keys can't be null.");
|
||||
Assert.notNull(args, "args can't be null.");
|
||||
|
||||
return jedisTemplate.execute(new JedisTemplate.JedisAction<Object>() {
|
||||
public Object action(Jedis jedis) {
|
||||
try {
|
||||
return jedis.evalsha(sha1, keys, args);
|
||||
} catch (JedisDataException e) {
|
||||
logger.warn(
|
||||
"Script {} is not loaded in server yet or the script is wrong, try to reload and run it again.",
|
||||
script, e);
|
||||
return jedis.eval(script, keys, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,714 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import redis.clients.jedis.Tuple;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
import redis.clients.util.Hashing;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* JedisShardTemplate is the JedisTemplate, which has key sharding feature.
|
||||
*
|
||||
* Pass more than one JedisPool to the it, it will calculate which jedisPool will handle the key. If
|
||||
* only one jedisPool passed, it won't do the calculation, so please use JedisShardedTemplate by default.
|
||||
*
|
||||
* But it doesn't support multi-key actions by default, like:
|
||||
* 1. Pipelined and Transaction process multi-keys
|
||||
* 2. Methods in @redis.clients.jedis.MultiKeyCommands like mget, rpoplpush....
|
||||
*
|
||||
* To support them, please use a common sharding key relate to these keys when invoke the APIs.
|
||||
*/
|
||||
public class JedisShardedTemplate {
|
||||
|
||||
private final Hashing algo = Hashing.MURMUR_HASH;
|
||||
private TreeMap<Long, JedisTemplate> nodes = new TreeMap<Long, JedisTemplate>();
|
||||
private JedisTemplate singleTemplate = null;
|
||||
|
||||
public JedisShardedTemplate(JedisPool... jedisPools) {
|
||||
if (jedisPools.length == 1) {
|
||||
singleTemplate = new JedisTemplate(jedisPools[0]);
|
||||
} else {
|
||||
initNodes(jedisPools);
|
||||
}
|
||||
}
|
||||
|
||||
public JedisShardedTemplate(List<JedisPool> jedisPools) {
|
||||
this(jedisPools.toArray(new JedisPool[jedisPools.size()]));
|
||||
}
|
||||
|
||||
private void initNodes(JedisPool... jedisPools) {
|
||||
for (int i = 0; i != jedisPools.length; i++) {
|
||||
// more entry the make the hash ring be more balance
|
||||
for (int n = 0; n < 128; n++) {
|
||||
final JedisPool jedisPool = jedisPools[i];
|
||||
nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), new JedisTemplate(jedisPool));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash the key and get the jedisTemplate from the hash ring. Get idea from Jedis's Sharded.java
|
||||
*/
|
||||
public JedisTemplate getShard(String key) {
|
||||
if (singleTemplate != null) {
|
||||
return singleTemplate;
|
||||
}
|
||||
|
||||
SortedMap<Long, JedisTemplate> tail = nodes.tailMap(algo.hash(key));
|
||||
if (tail.isEmpty()) {
|
||||
// the last node, back to first.
|
||||
return nodes.get(nodes.firstKey());
|
||||
}
|
||||
return tail.get(tail.firstKey());
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the action.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public <T> T execute(String key, JedisTemplate.JedisAction<T> jedisAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.execute(jedisAction);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the action.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public void execute(String key, JedisTemplate.JedisActionNoResult jedisAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.execute(jedisAction);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the pipeline.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public List<Object> execute(String key, JedisTemplate.PipelineAction pipelineAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.execute(pipelineAction);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the pipeline.
|
||||
*
|
||||
* @key the action must process only this key, or this key is a sharding key.
|
||||
*/
|
||||
public void execute(String key, JedisTemplate.PipelineActionNoResult pipelineAction) throws JedisException {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.execute(pipelineAction);
|
||||
}
|
||||
|
||||
// / Common Actions ///
|
||||
|
||||
public Boolean del(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.del(key);
|
||||
}
|
||||
|
||||
public Boolean del(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.del(key);
|
||||
}
|
||||
|
||||
// / String Actions ///
|
||||
|
||||
public String get(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.get(key);
|
||||
}
|
||||
|
||||
public String get(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.get(key);
|
||||
}
|
||||
|
||||
public Long getAsLong(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.getAsLong(key);
|
||||
}
|
||||
|
||||
public Long getAsLong(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.getAsLong(key);
|
||||
}
|
||||
|
||||
public Integer getAsInt(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.getAsInt(key);
|
||||
}
|
||||
|
||||
public Integer getAsInt(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.getAsInt(key);
|
||||
}
|
||||
|
||||
public void set(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.set(key, value);
|
||||
}
|
||||
|
||||
public void set(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.set(key, value);
|
||||
}
|
||||
|
||||
public void setex(final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.setex(key, value, seconds);
|
||||
}
|
||||
|
||||
public void setex(final String shardingKey, final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.setex(key, value, seconds);
|
||||
}
|
||||
|
||||
public Boolean setnx(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.setnx(key, value);
|
||||
}
|
||||
|
||||
public Boolean setnx(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.setnx(key, value);
|
||||
}
|
||||
|
||||
public Boolean setnxex(final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.setnxex(key, value, seconds);
|
||||
}
|
||||
|
||||
public Boolean setnxex(final String shardingKey, final String key, final String value, final int seconds) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.setnxex(key, value, seconds);
|
||||
}
|
||||
|
||||
public String getSet(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.getSet(key, value);
|
||||
}
|
||||
|
||||
public String getSet(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.getSet(key, value);
|
||||
}
|
||||
|
||||
public Long incr(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.incr(key);
|
||||
}
|
||||
|
||||
public Long incr(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.incr(key);
|
||||
}
|
||||
|
||||
public Long incrBy(final String key, final Long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.incrBy(key, increment);
|
||||
}
|
||||
|
||||
public Long incrBy(final String shardingKey, final String key, final Long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.incrBy(key, increment);
|
||||
}
|
||||
|
||||
public Double incrByFloat(final String key, final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.incrByFloat(key, increment);
|
||||
}
|
||||
|
||||
public Double incrByFloat(final String shardingKey, final String key, final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.incrByFloat(key, increment);
|
||||
}
|
||||
|
||||
public Long decr(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.decr(key);
|
||||
}
|
||||
|
||||
public Long decr(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.decr(key);
|
||||
}
|
||||
|
||||
public Long decrBy(final String key, final Long decrement) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.decrBy(key, decrement);
|
||||
}
|
||||
|
||||
public Long decrBy(final String shardingKey, final String key, final Long decrement) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.decrBy(key, decrement);
|
||||
}
|
||||
|
||||
// / Hash Actions ///
|
||||
|
||||
public String hget(final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hget(key, field);
|
||||
}
|
||||
|
||||
public String hget(final String shardingKey, final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hget(key, field);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hmget(key, field);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String key, final String[] fields) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hmget(key, fields);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String shardingKey, final String key, final String field) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hmget(key, field);
|
||||
}
|
||||
|
||||
public List<String> hmget(final String shardingKey, final String key, final String[] fields) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hmget(key, fields);
|
||||
}
|
||||
|
||||
public Map<String, String> hgetAll(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hgetAll(key);
|
||||
}
|
||||
|
||||
public Map<String, String> hgetAll(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hgetAll(key);
|
||||
}
|
||||
|
||||
public void hset(final String key, final String field, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.hset(key, field, value);
|
||||
}
|
||||
|
||||
public void hset(final String shardingKey, final String key, final String field, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.hset(key, field, value);
|
||||
}
|
||||
|
||||
public void hmset(final String key, final Map<String, String> map) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.hmset(key, map);
|
||||
}
|
||||
|
||||
public void hmset(final String shardingKey, final String key, final Map<String, String> map) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.hmset(key, map);
|
||||
}
|
||||
|
||||
public Boolean hsetnx(final String key, final String fieldName, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hsetnx(key, fieldName, value);
|
||||
}
|
||||
|
||||
public Boolean hsetnx(final String shardingKey, final String key, final String fieldName, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hsetnx(key, fieldName, value);
|
||||
}
|
||||
|
||||
public Long hincrBy(final String key, final String fieldName, final long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hincrBy(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Long hincrBy(final String shardingKey, final String key, final String fieldName, final long increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hincrBy(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Double hincrByFloat(final String key, final String fieldName, final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hincrByFloat(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Double hincrByFloat(final String shardingKey, final String key, final String fieldName,
|
||||
final double increment) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hincrByFloat(key, fieldName, increment);
|
||||
}
|
||||
|
||||
public Long hdel(final String key, final String fieldsName) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hdel(key, fieldsName);
|
||||
}
|
||||
|
||||
public Long hdel(final String key, final String[] fieldsNames) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hdel(key, fieldsNames);
|
||||
}
|
||||
|
||||
public Long hdel(final String shardingKey, final String key, final String fieldsName) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hdel(key, fieldsName);
|
||||
}
|
||||
|
||||
public Long hdel(final String shardingKey, final String key, final String[] fieldsNames) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hdel(key, fieldsNames);
|
||||
}
|
||||
|
||||
public Boolean hexists(final String key, final String fieldName) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hexists(key, fieldName);
|
||||
}
|
||||
|
||||
public Boolean hexists(final String shardingKey, final String key, final String fieldName) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hexists(key, fieldName);
|
||||
}
|
||||
|
||||
public Set<String> hkeys(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hkeys(key);
|
||||
}
|
||||
|
||||
public Set<String> hkeys(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hkeys(key);
|
||||
}
|
||||
|
||||
public Long hlen(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.hlen(key);
|
||||
}
|
||||
|
||||
public Long hlen(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.hlen(key);
|
||||
}
|
||||
|
||||
// / List Actions ///
|
||||
|
||||
public Long lpush(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lpush(key, value);
|
||||
}
|
||||
|
||||
public Long lpush(final String key, final String[] values) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lpush(key, values);
|
||||
}
|
||||
|
||||
public Long lpush(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lpush(key, value);
|
||||
}
|
||||
|
||||
public Long lpush(final String shardingKey, final String key, final String[] values) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lpush(key, values);
|
||||
}
|
||||
|
||||
public String rpop(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.rpop(key);
|
||||
}
|
||||
|
||||
public String rpop(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.rpop(key);
|
||||
}
|
||||
|
||||
public String brpop(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.brpop(key);
|
||||
}
|
||||
|
||||
public String brpop(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.brpop(key);
|
||||
}
|
||||
|
||||
public String brpop(final int timeout, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.brpop(timeout, key);
|
||||
}
|
||||
|
||||
public String brpop(final String shardingKey, final int timeout, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.brpop(timeout, key);
|
||||
}
|
||||
|
||||
public Long llen(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.llen(key);
|
||||
}
|
||||
|
||||
public Long llen(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.llen(key);
|
||||
}
|
||||
|
||||
public String lindex(final String key, final long index) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lindex(key, index);
|
||||
}
|
||||
|
||||
public String lindex(final String shardingKey, final String key, final long index) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lindex(key, index);
|
||||
}
|
||||
|
||||
public List<String> lrange(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lrange(key, start, end);
|
||||
}
|
||||
|
||||
public List<String> lrange(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lrange(key, start, end);
|
||||
}
|
||||
|
||||
public void ltrim(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.ltrim(key, start, end);
|
||||
}
|
||||
|
||||
public void ltrim(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.ltrim(key, start, end);
|
||||
}
|
||||
|
||||
public void ltrimFromLeft(final String key, final int size) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
jedisTemplate.ltrimFromLeft(key, size);
|
||||
}
|
||||
|
||||
public void ltrimFromLeft(final String shardingKey, final String key, final int size) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
jedisTemplate.ltrimFromLeft(key, size);
|
||||
}
|
||||
|
||||
public Boolean lremFirst(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lremFirst(key, value);
|
||||
}
|
||||
|
||||
public Boolean lremFirst(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lremFirst(key, value);
|
||||
}
|
||||
|
||||
public Boolean lremAll(final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.lremAll(key, value);
|
||||
}
|
||||
|
||||
public Boolean lremAll(final String shardingKey, final String key, final String value) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.lremAll(key, value);
|
||||
}
|
||||
|
||||
// / Set Actions ///
|
||||
public Boolean sadd(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.sadd(key, member);
|
||||
}
|
||||
|
||||
public Boolean sadd(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.sadd(key, member);
|
||||
}
|
||||
|
||||
public Set<String> smembers(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.smembers(key);
|
||||
}
|
||||
|
||||
public Set<String> smembers(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.smembers(key);
|
||||
}
|
||||
|
||||
// / Sorted Set Actions ///
|
||||
|
||||
public Boolean zadd(final String key, final double score, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zadd(key, score, member);
|
||||
}
|
||||
|
||||
public Boolean zadd(final String shardingKey, final String key, final double score, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zadd(key, score, member);
|
||||
}
|
||||
|
||||
public Double zscore(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zscore(key, member);
|
||||
}
|
||||
|
||||
public Double zscore(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zscore(key, member);
|
||||
}
|
||||
|
||||
public Long zrank(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrank(key, member);
|
||||
}
|
||||
|
||||
public Long zrank(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrank(key, member);
|
||||
}
|
||||
|
||||
public Long zrevrank(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrank(key, member);
|
||||
}
|
||||
|
||||
public Long zrevrank(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrank(key, member);
|
||||
}
|
||||
|
||||
public Long zcount(final String key, final double start, final double end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zcount(key, start, end);
|
||||
}
|
||||
|
||||
public Long zcount(final String shardingKey, final String key, final double start, final double end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zcount(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrange(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrange(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeWithScores(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeWithScores(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrevrange(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrevrange(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrange(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeWithScores(final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeWithScores(final String shardingKey, final String key, final int start, final int end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrangeWithScores(key, start, end);
|
||||
}
|
||||
|
||||
public Set<String> zrangeByScore(final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrangeByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Set<String> zrangeByScore(final String shardingKey, final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrangeByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrangeByScoreWithScores(key, min, max);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeByScoreWithScores(final String shardingKey, final String key, final double min,
|
||||
final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrangeByScoreWithScores(key, min, max);
|
||||
}
|
||||
|
||||
public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrangeByScore(key, max, min);
|
||||
}
|
||||
|
||||
public Set<String> zrevrangeByScore(final String shardingKey, final String key, final double max, final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrangeByScore(key, max, min);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrevrangeByScoreWithScores(key, max, min);
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeByScoreWithScores(final String shardingKey, final String key, final double max,
|
||||
final double min) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrevrangeByScoreWithScores(key, max, min);
|
||||
}
|
||||
|
||||
public Boolean zrem(final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zrem(key, member);
|
||||
}
|
||||
|
||||
public Boolean zrem(final String shardingKey, final String key, final String member) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zrem(key, member);
|
||||
}
|
||||
|
||||
public Long zremByScore(final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zremByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Long zremByScore(final String shardingKey, final String key, final double min, final double max) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zremByScore(key, min, max);
|
||||
}
|
||||
|
||||
public Long zremByRank(final String key, final long start, final long end) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zremByRank(key, start, end);
|
||||
}
|
||||
|
||||
public Long zremByRank(final String shardingKey, final String key, final long start, final long end) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zremByRank(key, start, end);
|
||||
}
|
||||
|
||||
public Long zcard(final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(key);
|
||||
return jedisTemplate.zcard(key);
|
||||
}
|
||||
|
||||
public Long zcard(final String shardingKey, final String key) {
|
||||
JedisTemplate jedisTemplate = getShard(shardingKey);
|
||||
return jedisTemplate.zcard(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,893 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
import redis.clients.jedis.Tuple;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
import redis.clients.jedis.exceptions.JedisDataException;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* JedisTemplate 提供了一个template方法,负责对Jedis连接的获取与归还。
|
||||
* JedisAction<T> 和 JedisActionNoResult两种回调接口,适用于有无返回值两种情况。
|
||||
* PipelineAction 与 PipelineActionResult两种接口,适合于pipeline中批量传输命令的情况。
|
||||
*
|
||||
* 同时提供一些JedisOperation中定义的 最常用函数的封装, 如get/set/zadd等。
|
||||
*/
|
||||
public class JedisTemplate {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisTemplate.class);
|
||||
|
||||
private JedisPool jedisPool;
|
||||
|
||||
public JedisTemplate(JedisPool jedisPool) {
|
||||
this.jedisPool = jedisPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template.
|
||||
*/
|
||||
public interface JedisAction<T> {
|
||||
T action(Jedis jedis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template without result.
|
||||
*/
|
||||
public interface JedisActionNoResult {
|
||||
void action(Jedis jedis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template.
|
||||
*/
|
||||
public interface PipelineAction {
|
||||
List<Object> action(Pipeline Pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for template without result.
|
||||
*/
|
||||
public interface PipelineActionNoResult {
|
||||
void action(Pipeline Pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action with result.
|
||||
*/
|
||||
public <T> T execute(JedisAction<T> jedisAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
return jedisAction.action(jedis);
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action without result.
|
||||
*/
|
||||
public void execute(JedisActionNoResult jedisAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
jedisAction.action(jedis);
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action with result in pipeline.
|
||||
*/
|
||||
public List<Object> execute(PipelineAction pipelineAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
pipelineAction.action(pipeline);
|
||||
return pipeline.syncAndReturnAll();
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute with a call back action without result in pipeline.
|
||||
*/
|
||||
public void execute(PipelineActionNoResult pipelineAction) throws JedisException {
|
||||
Jedis jedis = null;
|
||||
boolean broken = false;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
pipelineAction.action(pipeline);
|
||||
pipeline.sync();
|
||||
} catch (JedisException e) {
|
||||
broken = handleJedisException(e);
|
||||
throw e;
|
||||
} finally {
|
||||
closeResource(jedis, broken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the internal JedisPool.
|
||||
*/
|
||||
public JedisPool getJedisPool() {
|
||||
return jedisPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle jedisException, write log and return whether the connection is broken.
|
||||
*/
|
||||
protected boolean handleJedisException(JedisException jedisException) {
|
||||
if (jedisException instanceof JedisConnectionException) {
|
||||
logger.error("Redis connection " + jedisPool.getAddress() + " lost.", jedisException);
|
||||
} else if (jedisException instanceof JedisDataException) {
|
||||
if ((jedisException.getMessage() != null) && (jedisException.getMessage().indexOf("READONLY") != -1)) {
|
||||
logger.error("Redis connection " + jedisPool.getAddress() + " are read-only slave.", jedisException);
|
||||
} else {
|
||||
// dataException, isBroken=false
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
logger.error("Jedis exception happen.", jedisException);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return jedis connection to the pool, call different return methods depends on the conectionBroken status.
|
||||
*/
|
||||
protected void closeResource(Jedis jedis, boolean conectionBroken) {
|
||||
try {
|
||||
if (conectionBroken) {
|
||||
jedisPool.returnBrokenResource(jedis);
|
||||
} else {
|
||||
jedisPool.returnResource(jedis);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("return back jedis failed, will fore close the jedis.", e);
|
||||
JedisUtils.destroyJedis(jedis);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// / Common Actions ///
|
||||
|
||||
/**
|
||||
* Remove the specified keys. If a given key does not exist no operation is
|
||||
* performed for this key.
|
||||
*
|
||||
* return false if one of the key is not exist.
|
||||
*/
|
||||
public Boolean del(final String... keys) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.del(keys) == keys.length ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void flushDB() {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.flushDB();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / String Actions ///
|
||||
|
||||
/**
|
||||
* Get the value of the specified key. If the key does not exist null is
|
||||
* returned. If the value stored at key is not a string an error is returned
|
||||
* because GET can only handle string values.
|
||||
*/
|
||||
public String get(final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.get(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> keys(final String key) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.keys(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified key as Long.If the key does not exist null is returned.
|
||||
*/
|
||||
public Long getAsLong(final String key) {
|
||||
String result = get(key);
|
||||
return result != null ? Long.valueOf(result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified key as Integer.If the key does not exist null is returned.
|
||||
*/
|
||||
public Integer getAsInt(final String key) {
|
||||
String result = get(key);
|
||||
return result != null ? Integer.valueOf(result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the specified key as Double.If the key does not exist null is returned.
|
||||
*/
|
||||
public Double getAsDouble(final String key) {
|
||||
String result = get(key);
|
||||
return result != null ? Double.valueOf(result) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the values of all the specified keys. If one or more keys dont exist
|
||||
* or is not of type String, a 'nil' value is returned instead of the value
|
||||
* of the specified key, but the operation never fails.
|
||||
*/
|
||||
public List<String> mget(final String... keys) {
|
||||
return execute(new JedisAction<List<String>>() {
|
||||
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.mget(keys);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the string value as value of the key.
|
||||
* The string can't be longer than 1073741824 bytes (1 GB).
|
||||
*/
|
||||
public void set(final String key, final String value) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.set(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void expire(final String key, final int seconds) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.expire(key, seconds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The command is exactly equivalent to the following group of commands: {@link #set(String, String) SET} +
|
||||
* {@link #expire(String, int) EXPIRE}.
|
||||
* The operation is atomic.
|
||||
*/
|
||||
public void setex(final String key, final String value, final int seconds) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.setex(key, seconds, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* SETNX works exactly like {@link #setNX(String, String) SET} with the only
|
||||
* difference that if the key already exists no operation is performed.
|
||||
* SETNX actually means "SET if Not eXists".
|
||||
*
|
||||
* return true if the key was set.
|
||||
*/
|
||||
public Boolean setnx(final String key, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.setnx(key, value) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The command is exactly equivalent to the following group of commands: {@link #setex(String, String, int) SETEX} +
|
||||
* {@link #sexnx(String, String) SETNX}.
|
||||
* The operation is atomic.
|
||||
*/
|
||||
public Boolean setnxex(final String key, final String value, final int seconds) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
String result = jedis.set(key, value, "NX", "EX", seconds);
|
||||
return JedisUtils.isStatusOk(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* GETSET is an atomic set this value and return the old value command. Set
|
||||
* key to the string value and return the old value stored at key. The
|
||||
* string can't be longer than 1073741824 bytes (1 GB).
|
||||
*/
|
||||
public String getSet(final String key, final String value) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.getSet(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the number stored at key by one. If the key does not exist or
|
||||
* contains a value of a wrong type, set the key to the value of "0" before
|
||||
* to perform the increment operation.
|
||||
* <p>
|
||||
* INCR commands are limited to 64 bit signed integers.
|
||||
* <p>
|
||||
* Note: this is actually a string operation, that is, in Redis there are not "integer" types. Simply the string
|
||||
* stored at the key is parsed as a base 10 64 bit signed integer, incremented, and then converted back as a string.
|
||||
*
|
||||
* @return Integer reply, this commands will reply with the new value of key
|
||||
* after the increment.
|
||||
*/
|
||||
public Long incr(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.incr(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long incrBy(final String key, final long increment) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.incrBy(key, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Double incrByFloat(final String key, final double increment) {
|
||||
return execute(new JedisAction<Double>() {
|
||||
@Override
|
||||
public Double action(Jedis jedis) {
|
||||
return jedis.incrByFloat(key, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the number stored at key by one. If the key does not exist or
|
||||
* contains a value of a wrong type, set the key to the value of "0" before
|
||||
* to perform the decrement operation.
|
||||
*/
|
||||
public Long decr(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.decr(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long decrBy(final String key, final long decrement) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.decrBy(key, decrement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / Hash Actions ///
|
||||
/**
|
||||
* If key holds a hash, retrieve the value associated to the specified
|
||||
* field.
|
||||
* <p>
|
||||
* If the field is not found or the key does not exist, a special 'nil' value is returned.
|
||||
*/
|
||||
public String hget(final String key, final String fieldName) {
|
||||
return execute(new JedisAction<String>() {
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.hget(key, fieldName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> hmget(final String key, final String... fieldsNames) {
|
||||
return execute(new JedisAction<List<String>>() {
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.hmget(key, fieldsNames);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<String, String> hgetAll(final String key) {
|
||||
return execute(new JedisAction<Map<String, String>>() {
|
||||
@Override
|
||||
public Map<String, String> action(Jedis jedis) {
|
||||
return jedis.hgetAll(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void hset(final String key, final String fieldName, final String value) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.hset(key, fieldName, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void hmset(final String key, final Map<String, String> map) {
|
||||
execute(new JedisActionNoResult() {
|
||||
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.hmset(key, map);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public Boolean hsetnx(final String key, final String fieldName, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.hsetnx(key, fieldName, value) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long hincrBy(final String key, final String fieldName, final long increment) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.hincrBy(key, fieldName, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Double hincrByFloat(final String key, final String fieldName, final double increment) {
|
||||
return execute(new JedisAction<Double>() {
|
||||
@Override
|
||||
public Double action(Jedis jedis) {
|
||||
return jedis.hincrByFloat(key, fieldName, increment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long hdel(final String key, final String... fieldsNames) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.hdel(key, fieldsNames);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean hexists(final String key, final String fieldName) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.hexists(key, fieldName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> hkeys(final String key) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.hkeys(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long hlen(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.hlen(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / List Actions ///
|
||||
|
||||
public Long lpush(final String key, final String... values) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.lpush(key, values);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long rpush(final String key, final String... values) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.rpush(key, values);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String rpop(final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.rpop(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String brpop(final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
List<String> nameValuePair = jedis.brpop(key);
|
||||
if (nameValuePair != null) {
|
||||
return nameValuePair.get(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String brpop(final int timeout, final String key) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
List<String> nameValuePair = jedis.brpop(timeout, key);
|
||||
if (nameValuePair != null) {
|
||||
return nameValuePair.get(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Not support for sharding.
|
||||
*/
|
||||
public String rpoplpush(final String sourceKey, final String destinationKey) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.rpoplpush(sourceKey, destinationKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Not support for sharding.
|
||||
*/
|
||||
public String brpoplpush(final String source, final String destination, final int timeout) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.brpoplpush(source, destination, timeout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long llen(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.llen(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String lindex(final String key, final long index) {
|
||||
return execute(new JedisAction<String>() {
|
||||
|
||||
@Override
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.lindex(key, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> lrange(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<List<String>>() {
|
||||
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.lrange(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ltrim(final String key, final int start, final int end) {
|
||||
execute(new JedisActionNoResult() {
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.ltrim(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ltrimFromLeft(final String key, final int size) {
|
||||
execute(new JedisActionNoResult() {
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
jedis.ltrim(key, 0, size - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean lremFirst(final String key, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
Long count = jedis.lrem(key, 1, value);
|
||||
return (count == 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean lremAll(final String key, final String value) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
Long count = jedis.lrem(key, 0, value);
|
||||
return (count > 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / Set Actions ///
|
||||
public Boolean sadd(final String key, final String member) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.sadd(key, member) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> smembers(final String key) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.smembers(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// / Ordered Set Actions ///
|
||||
/**
|
||||
* return true for add new element, false for only update the score.
|
||||
*/
|
||||
public Boolean zadd(final String key, final double score, final String member) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.zadd(key, score, member) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Double zscore(final String key, final String member) {
|
||||
return execute(new JedisAction<Double>() {
|
||||
|
||||
@Override
|
||||
public Double action(Jedis jedis) {
|
||||
return jedis.zscore(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zrank(final String key, final String member) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zrank(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zrevrank(final String key, final String member) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zrevrank(key, member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zcount(final String key, final double min, final double max) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zcount(key, min, max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrange(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrange(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeWithScores(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrangeWithScores(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrevrange(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrevrange(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeWithScores(final String key, final int start, final int end) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrevrangeWithScores(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrangeByScore(final String key, final double min, final double max) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrangeByScore(key, min, max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrangeByScoreWithScores(key, min, max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
|
||||
return execute(new JedisAction<Set<String>>() {
|
||||
|
||||
@Override
|
||||
public Set<String> action(Jedis jedis) {
|
||||
return jedis.zrevrangeByScore(key, max, min);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
|
||||
return execute(new JedisAction<Set<Tuple>>() {
|
||||
|
||||
@Override
|
||||
public Set<Tuple> action(Jedis jedis) {
|
||||
return jedis.zrevrangeByScoreWithScores(key, max, min);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Boolean zrem(final String key, final String member) {
|
||||
return execute(new JedisAction<Boolean>() {
|
||||
|
||||
@Override
|
||||
public Boolean action(Jedis jedis) {
|
||||
return jedis.zrem(key, member) == 1 ? true : false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zremByScore(final String key, final double start, final double end) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zremrangeByScore(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zremByRank(final String key, final long start, final long end) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zremrangeByRank(key, start, end);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Long zcard(final String key) {
|
||||
return execute(new JedisAction<Long>() {
|
||||
|
||||
@Override
|
||||
public Long action(Jedis jedis) {
|
||||
return jedis.zcard(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis;
|
||||
|
||||
import javautils.redis.pool.JedisPool;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
public class JedisUtils {
|
||||
|
||||
private static final String OK_CODE = "OK";
|
||||
private static final String OK_MULTI_CODE = "+OK";
|
||||
|
||||
/**
|
||||
* 判断 返回值是否ok.
|
||||
*/
|
||||
public static boolean isStatusOk(String status) {
|
||||
return (status != null) && (OK_CODE.equals(status) || OK_MULTI_CODE.equals(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* 在Pool以外强行销毁Jedis.
|
||||
*/
|
||||
public static void destroyJedis(Jedis jedis) {
|
||||
if ((jedis != null) && jedis.isConnected()) {
|
||||
try {
|
||||
try {
|
||||
jedis.quit();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
jedis.disconnect();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ping the jedis instance, return true is the result is PONG.
|
||||
*/
|
||||
public static boolean ping(JedisPool pool) {
|
||||
JedisTemplate template = new JedisTemplate(pool);
|
||||
try {
|
||||
String result = template.execute(new JedisTemplate.JedisAction<String>() {
|
||||
public String action(Jedis jedis) {
|
||||
return jedis.ping();
|
||||
}
|
||||
});
|
||||
return (result != null) && result.equals("PONG");
|
||||
} catch (JedisException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
/**
|
||||
* All information for redis connection.
|
||||
*/
|
||||
public class ConnectionInfo {
|
||||
|
||||
public static final String DEFAULT_PASSWORD = null;
|
||||
|
||||
private int database = Protocol.DEFAULT_DATABASE;
|
||||
private String password = DEFAULT_PASSWORD;
|
||||
private int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||
|
||||
public ConnectionInfo() {
|
||||
}
|
||||
|
||||
public ConnectionInfo(int database, String password, int timeout) {
|
||||
this.timeout = timeout;
|
||||
if (password != null && password.length() > 0) {
|
||||
this.password = password;
|
||||
}
|
||||
else {
|
||||
this.password = DEFAULT_PASSWORD;
|
||||
}
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public int getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setDatabase(int database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
if (password != null && password.length() > 0) {
|
||||
this.password = password;
|
||||
}
|
||||
else {
|
||||
this.password = DEFAULT_PASSWORD;
|
||||
}
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConnectionInfo [database=" + database + ", password=" + password + ", timeout=" + timeout + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
/**
|
||||
* Pool which connect to redis instance directly.
|
||||
*/
|
||||
public class JedisDirectPool extends JedisPool {
|
||||
|
||||
public JedisDirectPool(HostAndPort address, JedisPoolConfig config) {
|
||||
initInternalPool(address, new ConnectionInfo(), config);
|
||||
}
|
||||
|
||||
public JedisDirectPool(HostAndPort address, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
initInternalPool(address, connectionInfo, config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.PooledObjectFactory;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
import redis.clients.jedis.BinaryJedis;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
/**
|
||||
* Copy from redis.clients.jedis.JedisFactory, because it is not a public class.
|
||||
*/
|
||||
public class JedisFactory implements PooledObjectFactory<Jedis> {
|
||||
private final String host;
|
||||
private final int port;
|
||||
private final int timeout;
|
||||
private final String password;
|
||||
private final int database;
|
||||
private final String clientName;
|
||||
|
||||
public JedisFactory(final String host, final int port, final int timeout, final String password, final int database) {
|
||||
this(host, port, timeout, password, database, null);
|
||||
}
|
||||
|
||||
public JedisFactory(final String host, final int port, final int timeout, final String password,
|
||||
final int database, final String clientName) {
|
||||
super();
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.timeout = timeout;
|
||||
this.password = password;
|
||||
this.database = database;
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateObject(PooledObject<Jedis> pooledJedis) throws Exception {
|
||||
final BinaryJedis jedis = pooledJedis.getObject();
|
||||
if (jedis.getDB() != database) {
|
||||
jedis.select(database);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
|
||||
final BinaryJedis jedis = pooledJedis.getObject();
|
||||
if (jedis.isConnected()) {
|
||||
try {
|
||||
try {
|
||||
jedis.quit();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
jedis.disconnect();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<Jedis> makeObject() throws Exception {
|
||||
final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
|
||||
|
||||
jedis.connect();
|
||||
if (null != this.password) {
|
||||
jedis.auth(this.password);
|
||||
}
|
||||
if (database != 0) {
|
||||
jedis.select(database);
|
||||
}
|
||||
if (clientName != null) {
|
||||
jedis.clientSetname(clientName);
|
||||
}
|
||||
|
||||
return new DefaultPooledObject<Jedis>(jedis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject<Jedis> pooledJedis) throws Exception {
|
||||
// TODO maybe should select db 0? Not sure right now.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateObject(PooledObject<Jedis> pooledJedis) {
|
||||
final BinaryJedis jedis = pooledJedis.getObject();
|
||||
try {
|
||||
return jedis.isConnected() && jedis.ping().equals("PONG");
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.util.Pool;
|
||||
|
||||
/**
|
||||
* Jedis Pool base class.
|
||||
*/
|
||||
public abstract class JedisPool extends Pool<Jedis> {
|
||||
|
||||
protected HostAndPort address;
|
||||
|
||||
protected ConnectionInfo connectionInfo;
|
||||
|
||||
/**
|
||||
* Create a JedisPoolConfig with new maxPoolSize becasuse JedisPoolConfig's default maxPoolSize is only 8.
|
||||
* Also reset the idle checking time to 10 minutes, the default value is half minute.
|
||||
* Also rest the max idle to zero, the default value is 8 too.
|
||||
* The default idle time is 60 seconds.
|
||||
*/
|
||||
public static JedisPoolConfig createPoolConfig(int maxPoolSize) {
|
||||
JedisPoolConfig config = new JedisPoolConfig();
|
||||
config.setMaxTotal(maxPoolSize);
|
||||
config.setMaxIdle(maxPoolSize);
|
||||
|
||||
config.setTimeBetweenEvictionRunsMillis(600 * 1000);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the internal pool with connection info and pool config.
|
||||
*/
|
||||
protected void initInternalPool(HostAndPort address, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
this.address = address;
|
||||
this.connectionInfo = connectionInfo;
|
||||
JedisFactory factory = new JedisFactory(address.getHost(), address.getPort(), connectionInfo.getTimeout(),
|
||||
connectionInfo.getPassword(), connectionInfo.getDatabase());
|
||||
|
||||
internalPool = new GenericObjectPool(factory, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a broken jedis connection back to pool.
|
||||
*/
|
||||
@Override
|
||||
public void returnBrokenResource(final Jedis resource) {
|
||||
if (resource != null) {
|
||||
returnBrokenResourceObject(resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a available jedis connection back to pool.
|
||||
*/
|
||||
@Override
|
||||
public void returnResource(final Jedis resource) {
|
||||
if (resource != null) {
|
||||
resource.resetState();
|
||||
returnResourceObject(resource);
|
||||
}
|
||||
}
|
||||
|
||||
public HostAndPort getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public ConnectionInfo getConnectionInfo() {
|
||||
return connectionInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Build JedisPool smartly。
|
||||
* Depends on masterName whether prefix with "direct:", it will build JedisSentinelPool or JedisDirectPool.
|
||||
*/
|
||||
public class JedisPoolBuilder {
|
||||
|
||||
public static final String DIRECT_POOL_PREFIX = "direct:";
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisPoolBuilder.class);
|
||||
|
||||
private String[] sentinelHosts;
|
||||
private int sentinelPort = Protocol.DEFAULT_SENTINEL_PORT;
|
||||
|
||||
private String masterName;
|
||||
private String[] shardedMasterNames;
|
||||
|
||||
private int poolSize = -1;
|
||||
|
||||
private int database = Protocol.DEFAULT_DATABASE;
|
||||
private String password = ConnectionInfo.DEFAULT_PASSWORD;
|
||||
private int timeout = Protocol.DEFAULT_TIMEOUT;
|
||||
|
||||
public JedisPoolBuilder setHosts(String[] hosts) {
|
||||
this.sentinelHosts = hosts;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setHosts(String hosts) {
|
||||
if (hosts != null) {
|
||||
this.sentinelHosts = hosts.split(",");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setPort(int port) {
|
||||
this.sentinelPort = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setMasterName(String masterName) {
|
||||
this.masterName = masterName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setShardedMasterNames(String[] shardedMasterNames) {
|
||||
this.shardedMasterNames = shardedMasterNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setShardedMasterNames(String shardedMasterNames) {
|
||||
if (shardedMasterNames != null) {
|
||||
this.shardedMasterNames = shardedMasterNames.split(",");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setDirectHostAndPort(String host, String port) {
|
||||
this.masterName = host + ":" + port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setPoolSize(int poolSize) {
|
||||
this.poolSize = poolSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setDatabase(int database) {
|
||||
this.database = database;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setPassword(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPoolBuilder setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JedisPool buildPool() {
|
||||
|
||||
if ((masterName == null) || "".equals(masterName)) {
|
||||
throw new IllegalArgumentException("masterName is null or empty");
|
||||
}
|
||||
|
||||
if (poolSize < 1) {
|
||||
throw new IllegalArgumentException("poolSize is less then one");
|
||||
}
|
||||
|
||||
JedisPoolConfig config = JedisPool.createPoolConfig(poolSize);
|
||||
ConnectionInfo connectionInfo = new ConnectionInfo(database, password, timeout);
|
||||
|
||||
if (isDirect(masterName)) {
|
||||
return buildDirectPool(masterName, connectionInfo, config);
|
||||
} else {
|
||||
if ((sentinelHosts == null) || (sentinelHosts.length == 0)) {
|
||||
throw new IllegalArgumentException("sentinelHosts is null or empty");
|
||||
}
|
||||
return buildSentinelPool(masterName, connectionInfo, config);
|
||||
}
|
||||
}
|
||||
|
||||
public List<JedisPool> buildShardedPools() {
|
||||
|
||||
if ((shardedMasterNames == null) || (shardedMasterNames.length == 0) || "".equals(shardedMasterNames[0])) {
|
||||
throw new IllegalArgumentException("shardedMasterNames is null or empty");
|
||||
}
|
||||
|
||||
if (poolSize < 1) {
|
||||
throw new IllegalArgumentException("poolSize is less then one");
|
||||
}
|
||||
|
||||
JedisPoolConfig config = JedisPool.createPoolConfig(poolSize);
|
||||
ConnectionInfo connectionInfo = new ConnectionInfo(database, password, timeout);
|
||||
|
||||
List<JedisPool> jedisPools = new ArrayList<JedisPool>();
|
||||
|
||||
if (isDirect(shardedMasterNames[0])) {
|
||||
for (String theMasterName : shardedMasterNames) {
|
||||
jedisPools.add(buildDirectPool(theMasterName, connectionInfo, config));
|
||||
}
|
||||
} else {
|
||||
|
||||
if ((sentinelHosts == null) || (sentinelHosts.length == 0)) {
|
||||
throw new IllegalArgumentException("sentinelHosts is null or empty");
|
||||
}
|
||||
|
||||
for (String theMasterName : shardedMasterNames) {
|
||||
jedisPools.add(buildSentinelPool(theMasterName, connectionInfo, config));
|
||||
}
|
||||
}
|
||||
return jedisPools;
|
||||
}
|
||||
|
||||
private JedisPool buildDirectPool(String directMasterName, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
String hostPortStr = directMasterName.substring(directMasterName.indexOf(":") + 1, directMasterName.length());
|
||||
String[] hostPort = hostPortStr.split(":");
|
||||
|
||||
logger.info("Building JedisDirectPool, on redis server " + hostPort[0] + " ,sentinelPort is " + hostPort[1]);
|
||||
|
||||
HostAndPort masterAddress = new HostAndPort(hostPort[0], Integer.parseInt(hostPort[1]));
|
||||
return new JedisDirectPool(masterAddress, config);
|
||||
}
|
||||
|
||||
private JedisPool buildSentinelPool(String sentinelMasterName, ConnectionInfo connectionInfo, JedisPoolConfig config) {
|
||||
logger.info("Building JedisSentinelPool, on sentinel sentinelHosts:" + Arrays.toString(sentinelHosts)
|
||||
+ " ,sentinelPort is " + sentinelPort + " ,masterName is " + sentinelMasterName);
|
||||
|
||||
HostAndPort[] sentinelAddress = new HostAndPort[sentinelHosts.length];
|
||||
for (int i = 0; i < sentinelHosts.length; i++) {
|
||||
sentinelAddress[i] = new HostAndPort(sentinelHosts[i], sentinelPort);
|
||||
}
|
||||
|
||||
return new JedisSentinelPool(sentinelAddress, sentinelMasterName, connectionInfo, config);
|
||||
}
|
||||
|
||||
private static boolean isDirect(String masterName) {
|
||||
return masterName.startsWith(DIRECT_POOL_PREFIX);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2014 springside.github.io
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
*******************************************************************************/
|
||||
package javautils.redis.pool;
|
||||
|
||||
import javautils.redis.JedisTemplate;
|
||||
import javautils.redis.JedisUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Pool which to get redis master address get from sentinel instances.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pool which to get redis master address get from sentinel instances.
|
||||
*/
|
||||
public final class JedisSentinelPool extends JedisPool {
|
||||
|
||||
private static final String NO_ADDRESS_YET = "I dont know because no sentinel up";
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(JedisSentinelPool.class);
|
||||
|
||||
private List<JedisPool> sentinelPools = new ArrayList<JedisPool>();
|
||||
private MasterSwitchListener masterSwitchListener;
|
||||
|
||||
private String masterName;
|
||||
private JedisPoolConfig masterPoolConfig;
|
||||
private ConnectionInfo masterConnectionInfo;
|
||||
private CountDownLatch poolInit = new CountDownLatch(1);
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>JedisSentinelPool</code>.
|
||||
*
|
||||
* All parameters can be null or empty.
|
||||
*
|
||||
* @param sentinelAddresses Array of HostAndPort to sentinel instances.
|
||||
* @param masterName One sentinel can monitor several redis master-slave pair, use master name to identify them.
|
||||
* @param masterConnectionInfo The the other information like password,timeout.
|
||||
* @param masterPoolConfig Configuration of redis pool.
|
||||
*
|
||||
*/
|
||||
public JedisSentinelPool(HostAndPort[] sentinelAddresses, String masterName, ConnectionInfo masterConnectionInfo,
|
||||
JedisPoolConfig masterPoolConfig) {
|
||||
// sentinelAddresses
|
||||
assertArgument(((sentinelAddresses == null) || (sentinelAddresses.length == 0)), "seintinelInfos is not set");
|
||||
|
||||
for (HostAndPort sentinelInfo : sentinelAddresses) {
|
||||
JedisPool sentinelPool = new JedisDirectPool(sentinelInfo, new JedisPoolConfig());
|
||||
sentinelPools.add(sentinelPool);
|
||||
}
|
||||
|
||||
// masterConnectionInfo
|
||||
assertArgument(masterConnectionInfo == null, "masterConnectionInfo is not set");
|
||||
this.masterConnectionInfo = masterConnectionInfo;
|
||||
|
||||
// masterName
|
||||
assertArgument(((masterName == null) || masterName.isEmpty()), "masterName is not set");
|
||||
this.masterName = masterName;
|
||||
|
||||
// poolConfig
|
||||
assertArgument(masterPoolConfig == null, "masterPoolConfig is not set");
|
||||
this.masterPoolConfig = masterPoolConfig;
|
||||
|
||||
// Start MasterSwitchListener thread ,internal poll will be start in the thread
|
||||
masterSwitchListener = new MasterSwitchListener();
|
||||
masterSwitchListener.start();
|
||||
|
||||
try {
|
||||
if (!poolInit.await(5, TimeUnit.SECONDS)) {
|
||||
logger.warn("the sentiel pool can't not init in 5 seconds");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public JedisSentinelPool(HostAndPort[] sentinelAddresses, String masterName, JedisPoolConfig masterPoolConfig) {
|
||||
this(sentinelAddresses, masterName, new ConnectionInfo(), masterPoolConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// shutdown the listener thread
|
||||
masterSwitchListener.shutdown();
|
||||
|
||||
// destroy sentinel pools
|
||||
for (JedisPool sentinel : sentinelPools) {
|
||||
sentinel.destroy();
|
||||
}
|
||||
|
||||
// destroy redis pool
|
||||
destroyInternelPool();
|
||||
|
||||
// wait for the masterSwitchListener thread finish
|
||||
try {
|
||||
logger.info("Waiting for MasterSwitchListener thread finish");
|
||||
masterSwitchListener.join();
|
||||
logger.info("MasterSwitchListener thread finished");
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
protected void destroyInternelPool() {
|
||||
closeInternalPool();
|
||||
|
||||
address = null;
|
||||
connectionInfo = null;
|
||||
internalPool = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the argurment, throw IllegalArgumentException if the expression is true.
|
||||
*/
|
||||
private static void assertArgument(boolean expression, String message) {
|
||||
if (expression) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
// for test
|
||||
public MasterSwitchListener getMasterSwitchListener() {
|
||||
return masterSwitchListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener thread to listen master switch message from sentinel.
|
||||
*/
|
||||
public class MasterSwitchListener extends Thread {
|
||||
public static final String THREAD_NAME_PREFIX = "MasterSwitchListener-";
|
||||
|
||||
private JedisPubSub subscriber;
|
||||
private JedisPool sentinelPool;
|
||||
private Jedis sentinelJedis;
|
||||
private AtomicBoolean running = new AtomicBoolean(true);
|
||||
private HostAndPort previousMasterAddress;
|
||||
|
||||
public MasterSwitchListener() {
|
||||
super(THREAD_NAME_PREFIX + masterName);
|
||||
}
|
||||
|
||||
// stop the blocking subscription and interrupt the thread
|
||||
public void shutdown() {
|
||||
// interrupt the thread
|
||||
running.getAndSet(false);
|
||||
this.interrupt();
|
||||
|
||||
// stop the blocking subscription
|
||||
try {
|
||||
if (subscriber != null) {
|
||||
subscriber.unsubscribe();
|
||||
}
|
||||
} finally {
|
||||
JedisUtils.destroyJedis(sentinelJedis);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (running.get()) {
|
||||
try {
|
||||
sentinelPool = pickupSentinel();
|
||||
|
||||
if (sentinelPool != null) {
|
||||
|
||||
HostAndPort masterAddress = queryMasterAddress();
|
||||
|
||||
if ((internalPool != null) && isAddressChange(masterAddress)) {
|
||||
logger.info("The internalPool {} had changed, destroy it now.", previousMasterAddress);
|
||||
destroyInternelPool();
|
||||
}
|
||||
|
||||
if (internalPool == null) {
|
||||
logger.info("The internalPool {} is not init or the address had changed, init it now.",
|
||||
masterAddress);
|
||||
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
|
||||
poolInit.countDown();
|
||||
}
|
||||
|
||||
previousMasterAddress = masterAddress;
|
||||
|
||||
sentinelJedis = sentinelPool.getResource();
|
||||
subscriber = new MasterSwitchSubscriber();
|
||||
sentinelJedis.subscribe(subscriber, "+switch-master", "+redirect-to-master");
|
||||
} else {
|
||||
logger.info("All sentinels down, sleep 2 seconds and try to connect again.");
|
||||
// When the system startup but the sentinels not yet, init a urgly address to prevent null point
|
||||
// exception. change the logic later.
|
||||
if (internalPool == null) {
|
||||
HostAndPort masterAddress = new HostAndPort(NO_ADDRESS_YET, 6379);
|
||||
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
|
||||
previousMasterAddress = masterAddress;
|
||||
}
|
||||
sleep(2000);
|
||||
}
|
||||
} catch (JedisConnectionException e) {
|
||||
|
||||
if (sentinelJedis != null) {
|
||||
sentinelPool.returnBrokenResource(sentinelJedis);
|
||||
}
|
||||
|
||||
if (running.get()) {
|
||||
logger.error("Lost connection with Sentinel " + sentinelPool.getAddress()
|
||||
+ ", sleep 1 seconds and try to connect other one. ");
|
||||
sleep(1000);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HostAndPort getCurrentMasterAddress() {
|
||||
return previousMasterAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pickup the first available sentinel, if all sentinel down, return null.
|
||||
*/
|
||||
private JedisPool pickupSentinel() {
|
||||
for (JedisPool pool : sentinelPools) {
|
||||
if (JedisUtils.ping(pool)) {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isAddressChange(HostAndPort currentMasterAddress) {
|
||||
if (previousMasterAddress == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !previousMasterAddress.equals(currentMasterAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query master address from sentinel.
|
||||
*/
|
||||
private HostAndPort queryMasterAddress() {
|
||||
JedisTemplate sentinelTemplate = new JedisTemplate(sentinelPool);
|
||||
List<String> address = sentinelTemplate.execute(new JedisTemplate.JedisAction<List<String>>() {
|
||||
@Override
|
||||
public List<String> action(Jedis jedis) {
|
||||
return jedis.sentinelGetMasterAddrByName(masterName);
|
||||
}
|
||||
});
|
||||
|
||||
if ((address == null) || address.isEmpty()) {
|
||||
throw new IllegalArgumentException("Master name " + masterName + " is not in sentinel.conf");
|
||||
}
|
||||
|
||||
return new HostAndPort(address.get(0), Integer.valueOf(address.get(1)));
|
||||
}
|
||||
|
||||
private void sleep(int millseconds) {
|
||||
try {
|
||||
Thread.sleep(millseconds);
|
||||
} catch (InterruptedException e1) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscriber for the master switch message from sentinel and init the new pool.
|
||||
*/
|
||||
private class MasterSwitchSubscriber extends JedisPubSub {
|
||||
@Override
|
||||
public void onMessage(String channel, String message) {
|
||||
// message example: +switch-master: mymaster 127.0.0.1 6379 127.0.0.1 6380
|
||||
// +redirect-to-master default 127.0.0.1 6380 127.0.0.1 6381 (if slave-master fail-over quick enough)
|
||||
logger.info("Sentinel " + sentinelPool.getAddress() + " published: " + message);
|
||||
String[] switchMasterMsg = message.split(" ");
|
||||
// if the master name equals my master name, destroy the old pool and init a new pool
|
||||
if (masterName.equals(switchMasterMsg[0])) {
|
||||
|
||||
HostAndPort masterAddress = new HostAndPort(switchMasterMsg[3],
|
||||
Integer.parseInt(switchMasterMsg[4]));
|
||||
logger.info("Switch master to " + masterAddress);
|
||||
destroyInternelPool();
|
||||
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
|
||||
previousMasterAddress = masterAddress;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPMessage(String pattern, String channel, String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscribe(String channel, int subscribedChannels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnsubscribe(String channel, int subscribedChannels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPUnsubscribe(String pattern, int subscribedChannels) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPSubscribe(String pattern, int subscribedChannels) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
package javautils.regex;
|
||||
|
||||
import javautils.StringUtil;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class RegexUtil {
|
||||
|
||||
private RegexUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配图象
|
||||
* 格式: /相对路径/文件名.后缀 (后缀为gif,dmp,png,jpg)
|
||||
* 匹配 : /forum/head_icon/admini2005111_ff.gif 或 admini2005111.dmp
|
||||
* 不匹配: c:/admins4512.gif
|
||||
*/
|
||||
public static final String image_regex = "^(/{0,1}\\w){1,}\\.(gif|dmp|png|jpg|jpeg)$|^\\w{1,}\\.(gif|dmp|png|jpg|jpeg)$";
|
||||
|
||||
/**
|
||||
* 匹配email地址
|
||||
* 匹配 : foo@bar.com 或 foobar@foobar.com.au
|
||||
* 不匹配: foo@bar 或 $$$@bar.com
|
||||
*/
|
||||
public static final String email_regex = "(?:\\w[-._\\w]*\\w@\\w[-._\\w]*\\w\\.\\w{2,3}$)";
|
||||
|
||||
/**
|
||||
* 匹配匹配并提取url
|
||||
* 匹配 : http://www.suncer.com 或news://www
|
||||
* 提取(MatchResult matchResult=matcher.getMatch()): matchResult.group(0)=
|
||||
* http://www.suncer.com:8080/index.html?login=true matchResult.group(1) =
|
||||
* http matchResult.group(2) = www.suncer.com matchResult.group(3) = :8080
|
||||
* matchResult.group(4) = /index.html?login=true
|
||||
* 不匹配: c:\window
|
||||
*/
|
||||
public static final String url_regex = "(\\w+)://([^/:]+)(:\\d*)?([^\\s]*)";
|
||||
|
||||
/**
|
||||
* 匹配并提取http
|
||||
* 匹配 : http://www.suncer.com:8080/index.html?login=true
|
||||
* 提取(MatchResult matchResult=matcher.getMatch()): matchResult.group(0)=
|
||||
* http://www.suncer.com:8080/index.html?login=true matchResult.group(1) =
|
||||
* http matchResult.group(2) = www.suncer.com matchResult.group(3) = :8080
|
||||
* matchResult.group(4) = /index.html?login=true
|
||||
* 不匹配: news://www
|
||||
*/
|
||||
public static final String http_regex = "(http|https|ftp)://([^/:]+)(:\\d*)?([^\\s]*)";
|
||||
|
||||
/**
|
||||
* 匹配日期
|
||||
* 范围:1900--2099
|
||||
* 匹配 : 2005-04-04
|
||||
* 不匹配: 01-01-01
|
||||
*/
|
||||
public static final String date_regex = "^((((19){1}|(20){1})d{2})|d{2})[-\\s]{1}[01]{1}d{1}[-\\s]{1}[0-3]{1}d{1}$";// 匹配日期
|
||||
|
||||
/**
|
||||
* 匹配电话
|
||||
* 匹配 : 0371-123456 或 (0371)1234567 或 (0371)12345678 或 010-123456 或
|
||||
* 010-12345678 或 12345678912
|
||||
* 不匹配: 1111-134355 或 0123456789
|
||||
*/
|
||||
public static final String phone_regex = "^(?:0[0-9]{2,3}[-\\s]{1}|\\(0[0-9]{2,4}\\))[0-9]{6,8}$|^[1-9]{1}[0-9]{5,7}$|^[1-9]{1}[0-9]{10}$";
|
||||
|
||||
/**
|
||||
* 匹配身份证
|
||||
* 匹配 : 0123456789123
|
||||
* 不匹配: 0123456
|
||||
*/
|
||||
public static final String ID_card_regex = "^\\d{10}|\\d{13}|\\d{15}|\\d{18}$";
|
||||
|
||||
/**
|
||||
* 匹配邮编代码
|
||||
* 匹配 : 012345
|
||||
* 不匹配: 0123456
|
||||
*/
|
||||
public static final String ZIP_regex = "^[0-9]{6}$";// 匹配邮编代码
|
||||
|
||||
/**
|
||||
* 不包括特殊字符的匹配 (字符串中不包括符号 数学次方号^ 单引号' 双引号" 分号; 逗号, 帽号: 数学减号- 右尖括号> 左尖括号< 反斜杠\
|
||||
* 即空格,制表符,回车符等 )
|
||||
* 格式为: x 或 一个一上的字符
|
||||
* 匹配 : 012345
|
||||
* 不匹配: 0123456
|
||||
*/
|
||||
public static final String non_special_char_regex = "^[^'\"\\;,:-<>\\s].+$";// 匹配邮编代码
|
||||
|
||||
/**
|
||||
* 匹配非负整数(正整数 + 0)
|
||||
*/
|
||||
public static final String non_negative_integers_regex = "^\\d+$";
|
||||
|
||||
/**
|
||||
* 匹配不包括零的非负整数(正整数 > 0)
|
||||
*/
|
||||
public static final String non_zero_negative_integers_regex = "^[1-9]+\\d*$";
|
||||
|
||||
/**
|
||||
* 匹配正整数
|
||||
*/
|
||||
public static final String positive_integer_regex = "^[0-9]*[1-9][0-9]*$";
|
||||
|
||||
/**
|
||||
* 匹配非正整数(负整数 + 0)
|
||||
*/
|
||||
public static final String non_positive_integers_regex = "^((-\\d+)|(0+))$";
|
||||
|
||||
/**
|
||||
* 匹配负整数
|
||||
*/
|
||||
public static final String negative_integers_regex = "^-[0-9]*[1-9][0-9]*$";
|
||||
|
||||
/**
|
||||
* 匹配整数
|
||||
*/
|
||||
public static final String integer_regex = "^-?\\d+$";
|
||||
|
||||
/**
|
||||
* 匹配非负浮点数(正浮点数 + 0)
|
||||
*/
|
||||
public static final String non_negative_rational_numbers_regex = "^\\d+(\\.\\d+)?$";
|
||||
|
||||
/**
|
||||
* 匹配正浮点数
|
||||
*/
|
||||
public static final String positive_rational_numbers_regex = "^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$";
|
||||
|
||||
/**
|
||||
* 匹配非正浮点数(负浮点数 + 0)
|
||||
*/
|
||||
public static final String non_positive_rational_numbers_regex = "^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$";
|
||||
|
||||
/**
|
||||
* 匹配负浮点数
|
||||
*/
|
||||
public static final String negative_rational_numbers_regex = "^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$";
|
||||
|
||||
/**
|
||||
* 匹配浮点数
|
||||
*/
|
||||
public static final String rational_numbers_regex = "^(-?\\d+)(\\.\\d+)?$";
|
||||
|
||||
/**
|
||||
* 匹配由26个英文字母组成的字符串
|
||||
*/
|
||||
public static final String letter_regex = "^[A-Za-z]+$";
|
||||
|
||||
/**
|
||||
* 匹配由26个英文字母的大写组成的字符串
|
||||
*/
|
||||
public static final String upward_letter_regex = "^[A-Z]+$";
|
||||
|
||||
/**
|
||||
* 匹配由26个英文字母的小写组成的字符串
|
||||
*/
|
||||
public static final String lower_letter_regex = "^[a-z]+$";
|
||||
|
||||
/**
|
||||
* 匹配由数字和26个英文字母组成的字符串
|
||||
*/
|
||||
public static final String letter_number_regex = "^[A-Za-z0-9]+$";
|
||||
|
||||
/**
|
||||
* 匹配由数字、26个英文字母或者下划线组成的字符串
|
||||
*/
|
||||
public static final String letter_number_underline_regex = "^\\w+$";
|
||||
|
||||
/**
|
||||
* 验证中文
|
||||
*/
|
||||
public static final String name_input_chn="[\u4e00-\u9fa5]";
|
||||
|
||||
public static boolean isMatcher(String s, String regex){
|
||||
boolean flag = false;
|
||||
try {
|
||||
if(StringUtil.isNotNull(s)) {
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(s);
|
||||
flag = matcher.matches();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("匹配失败!");
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package javautils.spring;
|
||||
|
||||
import javautils.StringUtil;
|
||||
import javautils.encrypt.DESUtil;
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2016/10/3.
|
||||
*/
|
||||
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
|
||||
private static final String KEY = "#$ddw134R$#G#DSFW@#?!@#!@#$CCCREW1";
|
||||
private static final DESUtil DES_UTIL = DESUtil.getInstance();
|
||||
|
||||
@Override
|
||||
protected String convertProperty(String propertyName, String propertyValue) {
|
||||
if (StringUtil.isNotNull(propertyValue) && propertyValue.endsWith("|e")) {
|
||||
String tempValue = propertyValue.substring(0, propertyValue.length() - 2);
|
||||
String decryptValue = DES_UTIL.decryptStr(tempValue, KEY);
|
||||
return decryptValue;
|
||||
} else {
|
||||
return propertyValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package lottery.bin;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Catalina {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package lottery.bin;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ExecuteServer {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package lottery.bin;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
public class StartUp {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StartUp.class);
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
public static void main(String[] args) {
|
||||
logger.debug("start up main method.");
|
||||
String[] configLocations = { "config/spring/spring-config.xml" };
|
||||
applicationContext = new ClassPathXmlApplicationContext(configLocations);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryOpenCodeService {
|
||||
/**
|
||||
* 修改为已开奖
|
||||
*/
|
||||
boolean updateOpened(LotteryOpenCode openCode);
|
||||
/**
|
||||
* 修改为无效已撤单
|
||||
*/
|
||||
boolean updateCancelled(LotteryOpenCode openCode);
|
||||
|
||||
/**
|
||||
* 获取往期未开奖的期数
|
||||
*/
|
||||
List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count);
|
||||
|
||||
/**
|
||||
* 根据彩票ID和期号获取开奖号码
|
||||
*/
|
||||
LotteryOpenCode getByExcept(String lottery, String except);
|
||||
|
||||
/**
|
||||
* 根据彩票ID和期号以及用户获取开奖号码
|
||||
*/
|
||||
LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except);
|
||||
|
||||
/**
|
||||
* 添加开奖号码,有则修改,没有就添加
|
||||
*/
|
||||
boolean add(LotteryOpenCode openCode);
|
||||
|
||||
/**
|
||||
* 查看某个彩种彩期是否已经抓取过了
|
||||
*/
|
||||
boolean hasCaptured(String lotteryName, String expect);
|
||||
|
||||
/**
|
||||
* 初始化开奖号码到redis中
|
||||
*/
|
||||
void initLotteryOpenCode();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRulesConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesConfigService {
|
||||
List<LotteryPlayRulesConfig> listAll();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesGroupConfigService {
|
||||
List<LotteryPlayRulesGroupConfig> listAll();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesGroupService {
|
||||
List<LotteryPlayRulesGroup> listAll();
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRules;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesService {
|
||||
List<LotteryPlayRules> listAll();
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/2/27.
|
||||
*/
|
||||
public interface UserBetsHitRankingService {
|
||||
/**
|
||||
* 每天前10名
|
||||
*/
|
||||
void addIfNecessary(UserBets userBets);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017-05-19.
|
||||
*/
|
||||
public interface UserBetsPointService {
|
||||
void add(UserBets userBets);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserBetsService {
|
||||
/**
|
||||
* 取消追号订单
|
||||
*/
|
||||
boolean cancelChase(String chaseBillno, int userId, String winExpect);
|
||||
|
||||
/**
|
||||
* 是否是待取消的追号单
|
||||
*/
|
||||
boolean isCancelChase(String chaseBillno);
|
||||
|
||||
/**
|
||||
* 对腾讯分分彩因在线人数无变动进行撤单
|
||||
*/
|
||||
void cancelByTXFFCInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList);
|
||||
|
||||
/**
|
||||
* 对腾讯龙虎斗因在线人数无变动进行撤单
|
||||
*/
|
||||
void cancelByTXLHDInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户注单结算service
|
||||
* Created by Nick on 2016/8/29.
|
||||
*/
|
||||
public interface UserBetsSettleService {
|
||||
void settleUserBets(List<UserBets> userBetsList, LotteryOpenCode openCode, Lottery lottery);
|
||||
|
||||
Object[] testUsersBets(UserBets userBets, String openCode, Lottery lottery, boolean cacheDantiao);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
|
||||
public interface UserBillService {
|
||||
/**
|
||||
* 添加投注账单
|
||||
*/
|
||||
boolean addSpendBill(UserBets bBean);
|
||||
/**
|
||||
* 取消订单账单
|
||||
*/
|
||||
boolean addCancelOrderBill(UserBets bBean, String remarks);
|
||||
|
||||
/**
|
||||
* 添加用户赢账单
|
||||
*/
|
||||
boolean addUserWinBill(UserBets userBets, double amount, String remarks);
|
||||
|
||||
/**
|
||||
* 添加上级返点账单
|
||||
*/
|
||||
boolean addProxyReturnBill(UserBets userBets, int upId, double amount, String remarks);
|
||||
|
||||
/**
|
||||
* 添加投注返水
|
||||
*/
|
||||
boolean addSpendReturnBill(UserBets userBets, double amount, String remarks);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/2/27.
|
||||
*/
|
||||
public interface UserHighPrizeService {
|
||||
void addIfNecessary(UserBets userBets);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
import lottery.domains.content.entity.UserLotteryDetailsReport;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserLotteryDetailsReportService {
|
||||
/**
|
||||
* 批量新增或修改报表详情
|
||||
*/
|
||||
void addDetailsReports(List<UserLotteryDetailsReport> detailsReports);
|
||||
|
||||
|
||||
boolean update(int userId, int lotteryId, int ruleId, int type, double amount, String time);
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package lottery.domains.content.biz;
|
||||
|
||||
public interface UserLotteryReportService {
|
||||
boolean update(int userId, int type, double amount, String time);
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import javautils.date.Moment;
|
||||
import javautils.redis.JedisTemplate;
|
||||
import lottery.domains.content.biz.LotteryOpenCodeService;
|
||||
import lottery.domains.content.dao.LotteryDao;
|
||||
import lottery.domains.content.dao.LotteryOpenCodeDao;
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
import lottery.domains.open.jobs.MailJob;
|
||||
import lottery.domains.pool.DataFactory;
|
||||
import lottery.domains.pool.play.HConstants;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.SetUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class LotteryOpenCodeServiceImpl implements LotteryOpenCodeService {
|
||||
private static final Logger log = LoggerFactory.getLogger(LotteryOpenCodeServiceImpl.class);
|
||||
private static final String OPEN_CODE_KEY = "OPEN_CODE:%s";
|
||||
private static final int OPEN_CODE_MOST_EXPECT = 50; // 保留最近50期开奖号码
|
||||
|
||||
@Autowired
|
||||
private LotteryOpenCodeDao lotteryOpenCodeDao;
|
||||
|
||||
@Autowired
|
||||
private LotteryDao lotteryDao;
|
||||
|
||||
@Autowired
|
||||
private JedisTemplate jedisTemplate;
|
||||
|
||||
@Autowired
|
||||
private MailJob mailJob;
|
||||
|
||||
@Autowired
|
||||
private DataFactory dataFactory;
|
||||
|
||||
@Override
|
||||
public boolean updateOpened(LotteryOpenCode openCode) {
|
||||
String updateTime = new Moment().toSimpleTime();
|
||||
boolean updated = lotteryOpenCodeDao.updateOpened(openCode.getId(), updateTime);
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateCancelled(LotteryOpenCode openCode) {
|
||||
String updateTime = new Moment().toSimpleTime();
|
||||
boolean updated = lotteryOpenCodeDao.updateCancelled(openCode.getId(), updateTime);
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count) {
|
||||
return lotteryOpenCodeDao.getBeforeNotOpen(lottery, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LotteryOpenCode getByExcept(String lottery, String except) {
|
||||
return lotteryOpenCodeDao.getByExcept(lottery, except);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except) {
|
||||
return lotteryOpenCodeDao.getByExceptAndUserId(lottery, userId, except);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(LotteryOpenCode openCode) {
|
||||
if (!"jsmmc".equals(openCode.getLottery())) {
|
||||
boolean hasCaptured = hasCaptured(openCode.getLottery(), openCode.getExpect());
|
||||
if (hasCaptured) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean added = lotteryOpenCodeDao.add(openCode);
|
||||
if (!added) {
|
||||
return false;
|
||||
}
|
||||
|
||||
addedToRedis(openCode);
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCaptured(String lotteryName, String expect) {
|
||||
String key = String.format(OPEN_CODE_KEY, lotteryName);
|
||||
|
||||
return jedisTemplate.hexists(key, expect);
|
||||
}
|
||||
|
||||
private void addedToRedis(LotteryOpenCode entity) {
|
||||
// 操作redis
|
||||
String key = String.format(OPEN_CODE_KEY, entity.getLottery());
|
||||
|
||||
if ("jsmmc".equals(entity.getLottery())) {
|
||||
// 急速秒秒彩直接存
|
||||
String field = entity.getExpect() + ":" + entity.getUserId();
|
||||
jedisTemplate.hset(key, field, entity.getCode());
|
||||
}
|
||||
else {
|
||||
// 删除redis中多余的期数,始终保持50期
|
||||
Set<String> hkeys = jedisTemplate.hkeys(key);
|
||||
if (CollectionUtils.isEmpty(hkeys)) {
|
||||
// 最新的设置进去
|
||||
jedisTemplate.hset(key, entity.getExpect(), entity.getCode());
|
||||
}
|
||||
else {
|
||||
TreeSet<String> sortHKeys = new TreeSet<>(hkeys);
|
||||
|
||||
// 先设置进去
|
||||
String[] expects = sortHKeys.toArray(new String[]{});
|
||||
String firstExpect = expects[0];
|
||||
if (entity.getExpect().compareTo(firstExpect) > 0) {
|
||||
jedisTemplate.hset(key, entity.getExpect(), entity.getCode());
|
||||
sortHKeys.add(entity.getExpect());
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(sortHKeys) && sortHKeys.size() > OPEN_CODE_MOST_EXPECT) {
|
||||
int exceedSize = sortHKeys.size() - OPEN_CODE_MOST_EXPECT;
|
||||
|
||||
Iterator<String> iterator = sortHKeys.iterator();
|
||||
int count = 0;
|
||||
List<String> delFields = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
if (count >= exceedSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
delFields.add(iterator.next());
|
||||
iterator.remove();
|
||||
count++;
|
||||
}
|
||||
|
||||
// 删除多余的
|
||||
jedisTemplate.hdel(key, delFields.toArray(new String[]{}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initLotteryOpenCode() {
|
||||
// 加载所有彩票
|
||||
List<Lottery> lotteries = lotteryDao.listAll();
|
||||
for (Lottery lottery : lotteries) {
|
||||
if (lottery.getId() == 117) continue; // 急速秒秒彩不设置
|
||||
|
||||
initLotteryOpenCodeByLottery(lottery);
|
||||
// continue; // 只针对自主彩
|
||||
}
|
||||
}
|
||||
|
||||
private void initLotteryOpenCodeByLottery(final Lottery lottery) {
|
||||
final List<LotteryOpenCode> openCodes = lotteryOpenCodeDao.getLatest(lottery.getShortName(), OPEN_CODE_MOST_EXPECT);
|
||||
if (CollectionUtils.isEmpty(openCodes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String key = String.format(OPEN_CODE_KEY, lottery.getShortName());
|
||||
|
||||
// 批量设置值
|
||||
final TreeMap<String, String> values = new TreeMap<>();
|
||||
for (LotteryOpenCode openCode : openCodes) {
|
||||
values.put(openCode.getExpect(), openCode.getCode());
|
||||
}
|
||||
//
|
||||
// // 倒序
|
||||
// final NavigableMap<String, String> descendingMap = values.descendingMap();
|
||||
|
||||
// 执行pipeline是为保证最大程度减少redis中没有值的情况,比如删除后重新设置前,那么redis此时处于真空状态
|
||||
jedisTemplate.execute(new JedisTemplate.JedisActionNoResult() {
|
||||
@Override
|
||||
public void action(Jedis jedis) {
|
||||
Pipeline pipelined = jedis.pipelined();
|
||||
|
||||
// 删除原开奖号码
|
||||
pipelined.del(key);
|
||||
|
||||
// 重新设置到redis
|
||||
for (String expect : values.keySet()) {
|
||||
pipelined.hset(key, expect, values.get(expect));
|
||||
}
|
||||
|
||||
// 执行
|
||||
pipelined.sync();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import lottery.domains.content.biz.LotteryPlayRulesConfigService;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesConfigDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRulesConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class LotteryPlayRulesConfigServiceImpl implements LotteryPlayRulesConfigService {
|
||||
|
||||
@Autowired
|
||||
private LotteryPlayRulesConfigDao lotteryPlayRulesConfigDao;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<LotteryPlayRulesConfig> listAll() {
|
||||
return lotteryPlayRulesConfigDao.listAll();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import lottery.domains.content.biz.LotteryPlayRulesGroupConfigService;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesGroupConfigDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class LotteryPlayRulesGroupConfigServiceImpl implements LotteryPlayRulesGroupConfigService {
|
||||
|
||||
@Autowired
|
||||
private LotteryPlayRulesGroupConfigDao lotteryPlayRulesGroupConfigDao;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<LotteryPlayRulesGroupConfig> listAll() {
|
||||
return lotteryPlayRulesGroupConfigDao.listAll();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import lottery.domains.content.biz.LotteryPlayRulesGroupService;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesGroupDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class LotteryPlayRulesGroupServiceImpl implements LotteryPlayRulesGroupService {
|
||||
|
||||
@Autowired
|
||||
private LotteryPlayRulesGroupDao lotteryPlayRulesGroupDao;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<LotteryPlayRulesGroup> listAll() {
|
||||
return lotteryPlayRulesGroupDao.listAll();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import lottery.domains.content.biz.LotteryPlayRulesService;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRules;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class LotteryPlayRulesServiceImpl implements LotteryPlayRulesService {
|
||||
|
||||
@Autowired
|
||||
private LotteryPlayRulesDao lotteryPlayRulesDao;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<LotteryPlayRules> listAll() {
|
||||
return lotteryPlayRulesDao.listAll();
|
||||
}
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import javautils.date.Moment;
|
||||
import lottery.domains.content.biz.UserBetsHitRankingService;
|
||||
import lottery.domains.content.dao.DbServerSyncDao;
|
||||
import lottery.domains.content.dao.UserBetsHitRankingDao;
|
||||
import lottery.domains.content.dao.UserDao;
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
import lottery.domains.content.entity.User;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
import lottery.domains.content.entity.UserBetsHitRanking;
|
||||
import lottery.domains.content.global.DbServerSyncEnum;
|
||||
import lottery.domains.content.global.Global;
|
||||
import lottery.domains.pool.DataFactory;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/2/27.
|
||||
*/
|
||||
@Service
|
||||
public class UserBetsHitRankingServiceImpl implements UserBetsHitRankingService {
|
||||
private static final Logger log = LoggerFactory.getLogger(UserBetsHitRankingServiceImpl.class);
|
||||
|
||||
private BlockingQueue<UserBets> userBetsQueue = new LinkedBlockingDeque<>();
|
||||
|
||||
@Autowired
|
||||
private UserBetsHitRankingDao rankingDao;
|
||||
|
||||
@Autowired
|
||||
private DataFactory dataFactory;
|
||||
|
||||
@Autowired
|
||||
private UserDao uDao;
|
||||
|
||||
@Autowired
|
||||
private DbServerSyncDao dbServerSyncDao;
|
||||
|
||||
private static boolean isRunning = false;
|
||||
|
||||
@Scheduled(cron = "0 0/5 * * * *")
|
||||
// @Scheduled(cron = "0/10 * * * * *")
|
||||
public void run() {
|
||||
synchronized (UserBetsHitRankingServiceImpl.class) {
|
||||
if (isRunning == true) {
|
||||
// 任务正在运行,本次中断
|
||||
return;
|
||||
}
|
||||
isRunning = true;
|
||||
}
|
||||
try {
|
||||
add();
|
||||
} finally {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void add() {
|
||||
if(userBetsQueue != null && userBetsQueue.size() > 0) {
|
||||
try {
|
||||
List<UserBets> adds = new LinkedList<>();
|
||||
userBetsQueue.drainTo(adds, 50);
|
||||
if (CollectionUtils.isNotEmpty(adds)) {
|
||||
add(adds);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("添加中奖排行榜错误", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void add(List<UserBets> adds) {
|
||||
if (!dataFactory.getLotteryConfig().isAutoHitRanking()) {
|
||||
return;
|
||||
}
|
||||
int hitRankingSize = dataFactory.getLotteryConfig().getHitRankingSize();
|
||||
|
||||
// 把奖金从大到小排序
|
||||
Collections.sort(adds, new Comparator<UserBets>() {
|
||||
@Override
|
||||
public int compare(UserBets o1, UserBets o2) {
|
||||
return o2.getPrizeTime().compareTo(o1.getPrizeTime());
|
||||
}
|
||||
});
|
||||
|
||||
String today = new Moment().toSimpleDate() + " 00:00:00";
|
||||
String tomorrow = new Moment().add(1, "days").toSimpleDate() + " 00:00:00";
|
||||
|
||||
// 先查看当天的数据是否满了10条
|
||||
List<Integer> todayIds = rankingDao.getIds(Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
|
||||
|
||||
// 没有满10条,把本次的数据由大到小加到数据库,但不超过最大条数
|
||||
int currentSize = todayIds.size();
|
||||
if (currentSize < hitRankingSize) {
|
||||
for (int i = 0; i < adds.size(); i++) {
|
||||
if (currentSize >= hitRankingSize) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
UserBets userBets = adds.get(i);
|
||||
UserBetsHitRanking ranking = convert(userBets);
|
||||
rankingDao.add(ranking);
|
||||
currentSize++;
|
||||
}
|
||||
}
|
||||
|
||||
// 重新调整以往的数据
|
||||
List<Integer> idsByTimeDesc = rankingDao.getIdsByTimeDesc(hitRankingSize, Global.BILL_ACCOUNT_LOTTERY);
|
||||
if (CollectionUtils.isNotEmpty(idsByTimeDesc)) {
|
||||
rankingDao.delNotInIds(idsByTimeDesc, Global.BILL_ACCOUNT_LOTTERY);
|
||||
}
|
||||
|
||||
dbServerSyncDao.update(DbServerSyncEnum.HIT_RANKING);
|
||||
|
||||
log.info("中奖排行榜更新完成");
|
||||
}
|
||||
else {
|
||||
// 如果大于今天最小的奖金,那么加入该数据
|
||||
UserBetsHitRanking minRanking = rankingDao.getMinRanking(Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
|
||||
int addedCount = 0;
|
||||
for (UserBets add : adds) {
|
||||
boolean allowAdd = false;
|
||||
if (minRanking == null) {
|
||||
allowAdd = true;
|
||||
}
|
||||
else {
|
||||
BigDecimal prize = BigDecimal.valueOf(add.getPrizeMoney());
|
||||
int prizeMoney = prize.intValue();
|
||||
if (prizeMoney > minRanking.getPrizeMoney()) {
|
||||
allowAdd = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowAdd) {
|
||||
UserBetsHitRanking ranking = convert(add);
|
||||
rankingDao.add(ranking);
|
||||
addedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 重新调整今天的数据
|
||||
if (addedCount > 0) {
|
||||
List<Integer> totalIds = rankingDao.getTotalIds(hitRankingSize, Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
|
||||
if (CollectionUtils.isNotEmpty(totalIds)) {
|
||||
rankingDao.delNotInIds(totalIds, Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
|
||||
}
|
||||
|
||||
// 重新调整以往的数据
|
||||
List<Integer> idsByTimeDesc = rankingDao.getIdsByTimeDesc(hitRankingSize, Global.BILL_ACCOUNT_LOTTERY);
|
||||
if (CollectionUtils.isNotEmpty(idsByTimeDesc)) {
|
||||
rankingDao.delNotInIds(idsByTimeDesc, Global.BILL_ACCOUNT_LOTTERY);
|
||||
}
|
||||
|
||||
dbServerSyncDao.update(DbServerSyncEnum.HIT_RANKING);
|
||||
|
||||
log.info("中奖排行榜更新完成");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private UserBetsHitRanking convert(UserBets userBets) {
|
||||
|
||||
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
|
||||
if (lottery == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
User user = uDao.getById(userBets.getUserId());
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserBetsHitRanking ranking = new UserBetsHitRanking();
|
||||
ranking.setName(lottery.getShowName());
|
||||
ranking.setUsername(user.getUsername());
|
||||
BigDecimal prize = BigDecimal.valueOf(userBets.getPrizeMoney());
|
||||
ranking.setPrizeMoney(prize.intValue());
|
||||
ranking.setTime(userBets.getPrizeTime());
|
||||
ranking.setPlatform(Global.BILL_ACCOUNT_LOTTERY);
|
||||
ranking.setCode(lottery.getShortName());
|
||||
ranking.setType(lottery.getType()+"");
|
||||
|
||||
return ranking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIfNecessary(UserBets userBets) {
|
||||
if (userBets.getPrizeMoney() != null && userBets.getPrizeMoney() >= 50000) {
|
||||
userBetsQueue.offer(userBets);
|
||||
}
|
||||
}
|
||||
}
|
||||
+276
@@ -0,0 +1,276 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import javautils.array.ArrayUtils;
|
||||
import javautils.math.MathUtil;
|
||||
import lottery.domains.content.biz.UserBetsPointService;
|
||||
import lottery.domains.content.biz.UserBillService;
|
||||
import lottery.domains.content.dao.UserDao;
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
import lottery.domains.content.entity.LotteryPlayRules;
|
||||
import lottery.domains.content.entity.User;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
import lottery.domains.content.global.Global;
|
||||
import lottery.domains.open.jobs.MailJob;
|
||||
import lottery.domains.pool.DataFactory;
|
||||
import lottery.domains.utils.user.UserCodePointUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017-05-19.
|
||||
*/
|
||||
@Service
|
||||
public class UserBetsPointServiceImpl implements UserBetsPointService {
|
||||
private static final Logger log = LoggerFactory.getLogger(UserBetsPointServiceImpl.class);
|
||||
private BlockingQueue<UserBets> userBetsQueue = new LinkedBlockingDeque<>();
|
||||
private static boolean isRunning = false;
|
||||
|
||||
@Autowired
|
||||
private MailJob mailJob;
|
||||
|
||||
@Autowired
|
||||
private UserDao uDao;
|
||||
|
||||
@Autowired
|
||||
private UserBillService uBillService;
|
||||
|
||||
@Autowired
|
||||
private UserCodePointUtil uCodePointUtil;
|
||||
|
||||
@Autowired
|
||||
private DataFactory dataFactory;
|
||||
|
||||
@Override
|
||||
public void add(UserBets userBets) {
|
||||
userBets.setCodes(null); // 将号码置空,减少内存占用
|
||||
userBetsQueue.offer(userBets);
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0/3 * * * * *")
|
||||
public void run() {
|
||||
synchronized (UserBetsPointServiceImpl.class) {
|
||||
if (isRunning == true) {
|
||||
// 任务正在运行,本次中断
|
||||
return;
|
||||
}
|
||||
isRunning = true;
|
||||
}
|
||||
|
||||
try {
|
||||
calculateOrder();
|
||||
} finally {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateOrder() {
|
||||
if(userBetsQueue != null && userBetsQueue.size() > 0) {
|
||||
try {
|
||||
List<UserBets> userBetsList = new LinkedList<>();
|
||||
userBetsQueue.drainTo(userBetsList, 3000); // 每次取3000条,不知道会不会太慢
|
||||
if (CollectionUtils.isNotEmpty(userBetsList)) {
|
||||
calculateOrders(userBetsList);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("添加用户大额中奖失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void calculateOrders(List<UserBets> userBetsList) {
|
||||
log.debug("正在进行注单返点,共计{}条注单", userBetsList.size());
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
for (UserBets userBets : userBetsList) {
|
||||
calculatePointMoney(userBets);
|
||||
}
|
||||
|
||||
long spent = System.currentTimeMillis() - start;
|
||||
log.debug("完成注单返点,共计{}条注单,耗时{}", userBetsList.size(), spent);
|
||||
|
||||
if (spent >= 60000) {
|
||||
String warningMsg = String.format("返点耗时告警;对%s条注单进行返点时耗时达到%s", userBetsList.size(), spent);
|
||||
log.warn(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 增加上级返点与用户投注返点
|
||||
*/
|
||||
private void calculatePointMoney(UserBets userBets) {
|
||||
// 上级返点
|
||||
calculateUpPoint(userBets);
|
||||
|
||||
// 投注返点
|
||||
calculateUserPoint(userBets);
|
||||
}
|
||||
|
||||
/**
|
||||
* 逐级为上级投注返点
|
||||
* 用户投注额 * ((上级返点 - 用户返点 - 累计返点) / 100)
|
||||
* 玩家a:12.0 -> 代理d:12.2 -> 代理c:12.4 -> 代理b:12.6 -> 代理a:13.0
|
||||
*
|
||||
* 玩家a投注:20,000
|
||||
*
|
||||
* 代理d返点:
|
||||
* 返点比例: 12.2 - 12.0 - 0.0 = 0.2
|
||||
* 计算比例: 0.2 / 100 = 0.002
|
||||
* 实际返钱: 20,000 * 0.002 = 40
|
||||
* 累计返点: 0.2
|
||||
*
|
||||
* 代理c返点:
|
||||
* 返点比例: 12.4 - 12.0 - 0.2 = 0.2
|
||||
* 计算比例: 0.2 / 100 = 0.002
|
||||
* 返钱: 20,000 * 0.002 = 40
|
||||
* 累计返点: 0.4
|
||||
*
|
||||
* 代理b返点:
|
||||
* 返点比例: 12.6 - 12.0 - 0.4 = 0.2
|
||||
* 计算比例: 0.2 / 100 = 0.002
|
||||
* 返钱: 20,000 * 0.002 = 40
|
||||
* 累计返点: 0.6
|
||||
*
|
||||
* 代理a返点:
|
||||
* 返占比例: 13.0 - 12.0 - 0.6 = 0.4
|
||||
* 计算比例: 0.4 / 100 = 0.004
|
||||
* 返钱: 20,000 * 0.004 = 80
|
||||
* 累计返点: 1.0
|
||||
*/
|
||||
private void calculateUpPoint(UserBets userBets) {
|
||||
if (userBets.getCode() == dataFactory.getCodeConfig().getSysCode()) {
|
||||
return; // 如果投注是最高,那么就不处理了
|
||||
}
|
||||
|
||||
User user = uDao.getById(userBets.getUserId());
|
||||
if (user == null || user.getUpid() == 0 || user.getUpid() == Global.USER_TOP_ID || StringUtils.isEmpty(user.getUpids())) {
|
||||
// 没有上级代理或上级是总账号时,不做任何处理
|
||||
return;
|
||||
}
|
||||
if (user.getCode() == dataFactory.getCodeConfig().getSysCode()) {
|
||||
return; // 如果用户是最高,那么就不处理了
|
||||
}
|
||||
|
||||
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
|
||||
LotteryPlayRules rules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
boolean isLocate = rules.getIsLocate() == 0 ? false: true;
|
||||
|
||||
int [] upIds = ArrayUtils.transGetIds(user.getUpids()); // 上级ID
|
||||
double currentPoint = 0; // 当前累计返点比例
|
||||
double totalPoint; // 本次总计应该返点
|
||||
if (isLocate) {
|
||||
totalPoint = MathUtil.subtract(dataFactory.getCodeConfig().getSysLp(), user.getLocatePoint());
|
||||
}
|
||||
else {
|
||||
totalPoint = MathUtil.subtract(dataFactory.getCodeConfig().getSysNlp(), user.getNotLocatePoint());
|
||||
}
|
||||
for (int upId : upIds) {
|
||||
// 总账号不返点
|
||||
if (upId == Global.USER_TOP_ID) {
|
||||
continue;
|
||||
}
|
||||
if (currentPoint >= totalPoint) {
|
||||
return; // 如果已经返完就不再返了
|
||||
}
|
||||
|
||||
User upUser = uDao.getById(upId);
|
||||
// 关联账号不返点
|
||||
if (upUser == null || upUser.getType() == Global.USER_TYPE_RELATED) continue;
|
||||
|
||||
double upPoint = isLocate ? upUser.getLocatePoint() : upUser.getNotLocatePoint(); // 上级返点
|
||||
double point = MathUtil.subtract(upPoint, isLocate ? user.getLocatePoint() : user.getNotLocatePoint()); // 返点比例:上级返点-用户返点
|
||||
point = MathUtil.subtract(point, currentPoint); // 返点比例:减去累计返点
|
||||
if(point <= 0) continue; // 小于0就不计算了
|
||||
|
||||
// 返给上级的钱:(注单金额 * (返点比例/100) )
|
||||
double upPointMoney = calculateMoneyByPoint(userBets.getMoney(), point); // 返给上级的钱
|
||||
|
||||
if (upPointMoney <= 0 || upPointMoney <= 0.000001) continue; // 小于0.00001就不计算了
|
||||
|
||||
currentPoint = MathUtil.add(currentPoint, point); // 累计返点
|
||||
|
||||
if (upUser.getAStatus() != 0 && upUser.getAStatus() != -1) continue; // 非正常或冻结用户不返点,系统扣除
|
||||
|
||||
// // 如果用户有上级关联用户,则还需要返给上级
|
||||
// if (upUser.getRelatedUpid() != 0 && upUser.getRelatedUpid() != Global.USER_TOP_ID && upUser.getRelatedPoint() > 0 && upUser.getRelatedPoint() <= 1) {
|
||||
// double relatedMoney = MathUtil.multiply(upPointMoney, upUser.getRelatedPoint());
|
||||
// if (relatedMoney > 0.0001) {
|
||||
// upPointMoney = MathUtil.subtract(upPointMoney, relatedMoney);
|
||||
//
|
||||
// // 生成账单
|
||||
// boolean succeed = uBillService.addProxyReturnBill(userBets, upUser.getRelatedUpid(), relatedMoney, "关联返点");
|
||||
//
|
||||
// // 修改金额
|
||||
// if (succeed) {
|
||||
// uDao.updateLotteryMoney(upUser.getRelatedUpid(), relatedMoney);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (upPointMoney <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成账单
|
||||
boolean succeed = uBillService.addProxyReturnBill(userBets, upId, upPointMoney, "上级返点");
|
||||
|
||||
// 修改金额
|
||||
if (succeed) {
|
||||
uDao.updateLotteryMoney(upId, upPointMoney);
|
||||
}
|
||||
|
||||
if (upUser.getCode() == dataFactory.getCodeConfig().getSysCode()) {
|
||||
return; // 如果上级已经是最高,那么就不处理了
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加用户投注返点
|
||||
*/
|
||||
private void calculateUserPoint(UserBets userBets) {
|
||||
// 本次投注返点
|
||||
double point = userBets.getPoint();
|
||||
if (point <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
|
||||
if (lottery != null) {
|
||||
LotteryPlayRules lotteryPlayRules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
// 固定奖金玩法没有投注返点
|
||||
if (lotteryPlayRules != null && lotteryPlayRules.getFixed() == 0) {
|
||||
double pointMoney = calculateMoneyByPoint(userBets.getMoney(), point);
|
||||
|
||||
if (pointMoney > 0 && pointMoney >= 0.00001) {
|
||||
boolean succeed = uBillService.addSpendReturnBill(userBets, pointMoney, "投注返点");
|
||||
if (succeed) {
|
||||
// 修改金额
|
||||
uDao.updateLotteryMoney(userBets.getUserId(), pointMoney);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据返点与金额计算返钱(金额 * (返点比例/100) )
|
||||
*/
|
||||
private double calculateMoneyByPoint(double money, double point) {
|
||||
double percent = MathUtil.divide(point, 100, 6);
|
||||
double _money = MathUtil.multiply(money, percent);
|
||||
return _money;
|
||||
}
|
||||
}
|
||||
+360
@@ -0,0 +1,360 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import javautils.date.Moment;
|
||||
import javautils.redis.JedisTemplate;
|
||||
import lottery.domains.content.biz.LotteryOpenCodeService;
|
||||
import lottery.domains.content.biz.UserBetsService;
|
||||
import lottery.domains.content.biz.UserBillService;
|
||||
import lottery.domains.content.dao.UserBetsDao;
|
||||
import lottery.domains.content.dao.UserDao;
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
import lottery.domains.content.global.Global;
|
||||
import lottery.domains.content.vo.bets.UserBetsAutoCancelAdapter;
|
||||
import lottery.domains.content.vo.bets.UserBetsCancelAdapter;
|
||||
import lottery.domains.open.jobs.MailJob;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
@Service
|
||||
public class UserBetsServiceImpl implements UserBetsService {
|
||||
public static final String USER_BETS_UNOPEN_RECENT_KEY = "USER:BETS:UNOPEN:RECENT:%s"; // 用户最近未结算彩票投注ID 用户ID
|
||||
public static final String USER_BETS_OPENED_RECENT_KEY = "USER:BETS:OPENED:RECENT:%s"; // 用户最近已结算彩票投注ID 用户ID
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(UserBetsServiceImpl.class);
|
||||
private BlockingQueue<UserBetsCancelAdapter> cancelChaseQueue = new LinkedBlockingDeque<>();
|
||||
|
||||
private ConcurrentHashMap<String, Boolean> cancelChaseMap = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<String, Boolean> cancelChaseHisMap = new ConcurrentHashMap<>();
|
||||
|
||||
private BlockingQueue<UserBetsAutoCancelAdapter> cancelTXFFXInvalidQueue = new LinkedBlockingDeque<>();
|
||||
private Set<String> cancelTXFFXInvalidSet = Collections.synchronizedSet(new HashSet<String>());
|
||||
|
||||
private BlockingQueue<UserBetsAutoCancelAdapter> cancelTXLHDInvalidQueue = new LinkedBlockingDeque<>();
|
||||
private Set<String> cancelTXLHDInvalidSet = Collections.synchronizedSet(new HashSet<String>());
|
||||
|
||||
private static boolean isRunning = false;
|
||||
/**
|
||||
* DAO
|
||||
*/
|
||||
@Autowired
|
||||
private UserDao uDao;
|
||||
|
||||
@Autowired
|
||||
private UserBetsDao uBetsDao;
|
||||
|
||||
@Autowired
|
||||
private LotteryOpenCodeService lotteryOpenCodeService;
|
||||
|
||||
@Autowired
|
||||
private MailJob mailJob;
|
||||
|
||||
/**
|
||||
* SERVICE
|
||||
*/
|
||||
@Autowired
|
||||
private UserBillService uBillService;
|
||||
|
||||
@Autowired
|
||||
private JedisTemplate jedisTemplate;
|
||||
|
||||
@Scheduled(cron = "0/3 * * * * *")
|
||||
public void run() {
|
||||
|
||||
synchronized (UserBetsServiceImpl.class) {
|
||||
if (isRunning == true) {
|
||||
// 任务正在运行,本次中断
|
||||
return;
|
||||
}
|
||||
isRunning = true;
|
||||
}
|
||||
try {
|
||||
cancelChase(); // 撤单追号
|
||||
cancelTXFFC(); // 撤单腾讯分分彩
|
||||
cancelTXLHD(); // 撤单腾讯龙虎斗
|
||||
} finally {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelChase() {
|
||||
if(cancelChaseQueue != null && cancelChaseQueue.size() > 0) {
|
||||
try {
|
||||
List<UserBetsCancelAdapter> cancels = new LinkedList<>();
|
||||
cancelChaseQueue.drainTo(cancels, 200); // 每次取200条
|
||||
if (CollectionUtils.isNotEmpty(cancels)) {
|
||||
cancelChase(cancels);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("撤销用户追单失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelChase(List<UserBetsCancelAdapter> cancels) {
|
||||
log.info("正在中奖撤销追号订单,共计{}条追号单需要撤销", cancels.size());
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
int canceledCount = 0;
|
||||
for (UserBetsCancelAdapter cancel : cancels) {
|
||||
List<UserBets> list = uBetsDao.getByChaseBillno(cancel.getChaseBillno(), cancel.getUserId(), cancel.getWinExpect());
|
||||
for (UserBets bBean : list) {
|
||||
if(bBean.getStatus() == 0) {
|
||||
doCancelOrderByChase(bBean);
|
||||
canceledCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long spent = System.currentTimeMillis() - start;
|
||||
log.info("完成中奖撤销追号订单,共计{}条追号单{}条注单,耗时{}", cancels.size(), canceledCount, spent);
|
||||
|
||||
if (spent >= 30000) {
|
||||
String warningMsg = String.format("中奖撤销追号订单耗时告警;撤销%s条追号单%s条注单时耗时达到%s", cancels.size(), canceledCount, spent);
|
||||
log.warn(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancelChase(String chaseBillno, int userId, String winExpect) {
|
||||
if (!cancelChaseMap.containsKey(chaseBillno) && !cancelChaseHisMap.contains(chaseBillno)) {
|
||||
cancelChaseMap.put(chaseBillno, true);
|
||||
cancelChaseQueue.offer(new UserBetsCancelAdapter(chaseBillno, userId, winExpect));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelChase(String chaseBillno) {
|
||||
return cancelChaseMap.containsKey(chaseBillno) || cancelChaseHisMap.contains(chaseBillno);
|
||||
}
|
||||
|
||||
private boolean doCancelOrderByChase(UserBets bBean) {
|
||||
try {
|
||||
if(bBean.getType() == Global.USER_BETS_TYPE_CHASE && bBean.getStatus() == 0 && bBean.getChaseStop() == 1) {
|
||||
boolean canceled = uBetsDao.cancel(bBean.getId());
|
||||
if(canceled) {
|
||||
boolean added = uBillService.addCancelOrderBill(bBean, "中奖后停止追号返款");
|
||||
if(added) {
|
||||
cacheUserBetsId(bBean);
|
||||
return uDao.updateLotteryMoney(bBean.getUserId(), bBean.getMoney(), -bBean.getMoney());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("中奖停止追号出错,注单号:" + bBean.getId() + ",追单号:" + bBean.getChaseBillno(), e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void cancelTXFFC() {
|
||||
if(cancelTXFFXInvalidQueue != null && cancelTXFFXInvalidQueue.size() > 0) {
|
||||
try {
|
||||
List<UserBetsAutoCancelAdapter> cancels = new LinkedList<>();
|
||||
cancelTXFFXInvalidQueue.drainTo(cancels, 200); // 每次取200条
|
||||
if (CollectionUtils.isNotEmpty(cancels)) {
|
||||
cancelTXFFC(cancels);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("撤销腾讯分分彩失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelTXFFC(List<UserBetsAutoCancelAdapter> cancels) {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
int canceledCount = 0;
|
||||
for (UserBetsAutoCancelAdapter cancel : cancels) {
|
||||
List<UserBets> list = cancel.getUserBetsList();
|
||||
|
||||
log.info("正在撤销腾讯分分彩无效开奖号码,期号{}", cancel.getLotteryOpenCode().getExpect());
|
||||
|
||||
// 撤销注单
|
||||
for (UserBets bBean : list) {
|
||||
if(bBean.getStatus() == 0) {
|
||||
doCancelOrderByTXFFC(bBean, cancel.getLotteryOpenCode().getCode());
|
||||
canceledCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 修改开奖号码状态为无效已撤单(2)
|
||||
lotteryOpenCodeService.updateCancelled(cancel.getLotteryOpenCode());
|
||||
|
||||
cancelTXFFXInvalidSet.remove(cancel.getLotteryOpenCode().getExpect());
|
||||
}
|
||||
|
||||
long spent = System.currentTimeMillis() - start;
|
||||
log.info("完成撤销腾讯分分彩无效开奖号码,共计{}期{}条注单,耗时{}", cancels.size(), canceledCount, spent);
|
||||
|
||||
if (spent >= 30000) {
|
||||
String warningMsg = String.format("撤销腾讯分分彩无效开奖号码耗时告警;撤销%s期%s条注单时耗时达到%s", cancels.size(), canceledCount, spent);
|
||||
log.warn(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelByTXFFCInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList) {
|
||||
if (cancelTXFFXInvalidSet.contains(lotteryOpenCode.getExpect())) {
|
||||
return;
|
||||
}
|
||||
if (!"txffc".equalsIgnoreCase(lotteryOpenCode.getLottery())) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelTXFFXInvalidSet.add(lotteryOpenCode.getExpect());
|
||||
cancelTXFFXInvalidQueue.offer(new UserBetsAutoCancelAdapter(lotteryOpenCode, userBetsList));
|
||||
}
|
||||
|
||||
private boolean doCancelOrderByTXFFC(UserBets bBean, String openCode) {
|
||||
try {
|
||||
Moment thisTime = new Moment();
|
||||
Moment stopTime = new Moment().fromTime(bBean.getStopTime());
|
||||
if (bBean.getStatus() == 0 && thisTime.ge(stopTime)) {
|
||||
boolean canceled = uBetsDao.cancelAndSetOpenCode(bBean.getId(), openCode);
|
||||
if(canceled) {
|
||||
boolean added = uBillService.addCancelOrderBill(bBean, "腾讯分分彩重复开奖号码撤单");
|
||||
if(added) {
|
||||
cacheUserBetsId(bBean);
|
||||
return uDao.updateLotteryMoney(bBean.getUserId(), bBean.getMoney(), -bBean.getMoney());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("腾讯分分彩无效开奖号码撤单出错,注单号:" + bBean.getId(), e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void cancelTXLHD() {
|
||||
if(cancelTXLHDInvalidQueue != null && cancelTXLHDInvalidQueue.size() > 0) {
|
||||
try {
|
||||
List<UserBetsAutoCancelAdapter> cancels = new LinkedList<>();
|
||||
cancelTXLHDInvalidQueue.drainTo(cancels, 200); // 每次取200条
|
||||
if (CollectionUtils.isNotEmpty(cancels)) {
|
||||
cancelTXLHD(cancels);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("撤销腾讯龙虎斗失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelTXLHD(List<UserBetsAutoCancelAdapter> cancels) {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
int canceledCount = 0;
|
||||
for (UserBetsAutoCancelAdapter cancel : cancels) {
|
||||
List<UserBets> list = cancel.getUserBetsList();
|
||||
|
||||
log.info("正在撤销腾讯龙虎斗无效开奖号码,期号{}", cancel.getLotteryOpenCode().getExpect());
|
||||
|
||||
// 撤销注单
|
||||
for (UserBets bBean : list) {
|
||||
if(bBean.getStatus() == 0) {
|
||||
doCancelOrderByTXLHD(bBean, cancel.getLotteryOpenCode().getCode());
|
||||
canceledCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 修改开奖号码状态为无效已撤单(2)
|
||||
lotteryOpenCodeService.updateCancelled(cancel.getLotteryOpenCode());
|
||||
|
||||
cancelTXLHDInvalidSet.remove(cancel.getLotteryOpenCode().getExpect());
|
||||
}
|
||||
|
||||
long spent = System.currentTimeMillis() - start;
|
||||
log.info("完成撤销腾讯龙虎斗无效开奖号码,共计{}期{}条注单,耗时{}", cancels.size(), canceledCount, spent);
|
||||
|
||||
if (spent >= 30000) {
|
||||
String warningMsg = String.format("撤销腾讯龙虎斗无效开奖号码耗时告警;撤销%s期%s条注单时耗时达到%s", cancels.size(), canceledCount, spent);
|
||||
log.warn(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelByTXLHDInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList) {
|
||||
if (cancelTXLHDInvalidSet.contains(lotteryOpenCode.getExpect())) {
|
||||
return;
|
||||
}
|
||||
if (!"txlhd".equalsIgnoreCase(lotteryOpenCode.getLottery())) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelTXLHDInvalidSet.add(lotteryOpenCode.getExpect());
|
||||
cancelTXLHDInvalidQueue.offer(new UserBetsAutoCancelAdapter(lotteryOpenCode, userBetsList));
|
||||
}
|
||||
|
||||
private boolean doCancelOrderByTXLHD(UserBets bBean, String openCode) {
|
||||
try {
|
||||
Moment thisTime = new Moment();
|
||||
Moment stopTime = new Moment().fromTime(bBean.getStopTime());
|
||||
if (bBean.getStatus() == 0 && thisTime.ge(stopTime)) {
|
||||
boolean canceled = uBetsDao.cancelAndSetOpenCode(bBean.getId(), openCode);
|
||||
if(canceled) {
|
||||
boolean added = uBillService.addCancelOrderBill(bBean, "腾讯龙虎斗重复开奖号码撤单");
|
||||
if(added) {
|
||||
cacheUserBetsId(bBean);
|
||||
return uDao.updateLotteryMoney(bBean.getUserId(), bBean.getMoney(), -bBean.getMoney());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
log.error("腾讯龙虎斗无效开奖号码撤单出错,注单号:" + bBean.getId(), e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 30 5 * * *")
|
||||
public void clear() {
|
||||
cancelChaseHisMap.clear();
|
||||
cancelChaseHisMap.putAll(cancelChaseMap);
|
||||
cancelChaseMap.clear();
|
||||
}
|
||||
|
||||
private void cacheUserBetsId(UserBets userBets) {
|
||||
|
||||
final String unOpenCacheKey = String.format(USER_BETS_UNOPEN_RECENT_KEY, userBets.getUserId());
|
||||
final String openedCacheKey = String.format(USER_BETS_OPENED_RECENT_KEY, userBets.getUserId());
|
||||
final String userBetsId = userBets.getId() + "";
|
||||
|
||||
try {
|
||||
jedisTemplate.execute(new JedisTemplate.PipelineActionNoResult() {
|
||||
@Override
|
||||
public void action(Pipeline pipeline) {
|
||||
pipeline.lrem(unOpenCacheKey, 1, userBetsId); // 移除未结算订单ID
|
||||
pipeline.lpush(openedCacheKey, userBetsId); // 设置已结算订单ID
|
||||
pipeline.ltrim(openedCacheKey, 0, 10); // 最多设置10条
|
||||
pipeline.expire(openedCacheKey, 60 * 60 * 12); // 12小时过期
|
||||
pipeline.sync();
|
||||
}
|
||||
});
|
||||
} catch (JedisException e) {
|
||||
log.error("执行Redis缓存注单ID时出错", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+883
@@ -0,0 +1,883 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import javautils.StringUtil;
|
||||
import javautils.date.DateUtil;
|
||||
import javautils.date.Moment;
|
||||
import javautils.math.MathUtil;
|
||||
import javautils.redis.JedisTemplate;
|
||||
import lottery.domains.content.biz.LotteryOpenCodeService;
|
||||
import lottery.domains.content.biz.UserBetsHitRankingService;
|
||||
import lottery.domains.content.biz.UserBetsPointService;
|
||||
import lottery.domains.content.biz.UserBetsService;
|
||||
import lottery.domains.content.biz.UserBetsSettleService;
|
||||
import lottery.domains.content.biz.UserBillService;
|
||||
import lottery.domains.content.biz.UserHighPrizeService;
|
||||
import lottery.domains.content.biz.UserLotteryDetailsReportService;
|
||||
import lottery.domains.content.biz.UserLotteryReportService;
|
||||
import lottery.domains.content.dao.UserBetsDao;
|
||||
import lottery.domains.content.dao.UserDao;
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
import lottery.domains.content.entity.LotteryPlayRules;
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroup;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
import lottery.domains.content.global.Global;
|
||||
import lottery.domains.content.global.NoticeSendType;
|
||||
import lottery.domains.content.vo.config.LotteryConfig;
|
||||
import lottery.domains.content.vo.user.UserVO;
|
||||
import lottery.domains.open.jobs.MailJob;
|
||||
import lottery.domains.pool.DataFactory;
|
||||
import lottery.domains.pool.play.HConstants;
|
||||
import lottery.domains.pool.play.ITicketPlayHandler;
|
||||
import lottery.domains.pool.play.MultipleResult;
|
||||
import lottery.domains.pool.play.TicketPlayHandlerContext;
|
||||
import lottery.domains.pool.play.WinResult;
|
||||
import lottery.domains.pool.play.impl.SSCRX3HHZXPlayHanlder;
|
||||
import lottery.domains.utils.prize.PrizeUtils;
|
||||
import redis.clients.jedis.Pipeline;
|
||||
import redis.clients.jedis.exceptions.JedisException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Created by Nick on 2016/8/29.
|
||||
*/
|
||||
@Service
|
||||
public class UserBetsSettleServiceImpl implements UserBetsSettleService {
|
||||
private static final Logger log = LoggerFactory.getLogger(UserBetsSettleServiceImpl.class);
|
||||
private static final String USER_CURRENT_PRIZE_KEY = "USER:CURRENT_PRIZE:";
|
||||
private static final String LOTTERY_CURRENT_PRIZE_KEY = "LOTTERY:CURRENT_PRIZE:";
|
||||
private static final String USER_BETS_NOTICE_KEY = "USER:BETS_NOTICE";
|
||||
|
||||
/**
|
||||
* 域:用户ID:注单ID:失效时间
|
||||
* 值:json,彩票ID,彩票名称,彩票期号,注单ID,注单状态,投注金额,奖金,玩法名称,通知类型
|
||||
*/
|
||||
public static final String USER_BETS_UNOPEN_RECENT_KEY = "USER:BETS:UNOPEN:RECENT:%s"; // 用户最近未结算彩票投注ID 用户ID
|
||||
public static final String USER_BETS_OPENED_RECENT_KEY = "USER:BETS:OPENED:RECENT:%s"; // 用户最近已结算彩票投注ID 用户ID
|
||||
|
||||
private static final int USER_BETS_NOTICE_EXPIRE_HOURS = 20; // 20小时后失效
|
||||
|
||||
//region services
|
||||
@Autowired
|
||||
private UserBetsDao userBetsDao;
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
@Autowired
|
||||
private UserBillService userBillService;
|
||||
@Autowired
|
||||
private UserBetsService userBetsService;
|
||||
@Autowired
|
||||
private UserLotteryReportService userLotteryReportService;
|
||||
@Autowired
|
||||
private UserLotteryDetailsReportService userLotteryDetailsReportService;
|
||||
@Autowired
|
||||
private DataFactory dataFactory;
|
||||
@Autowired
|
||||
private LotteryOpenCodeService lotteryOpenCodeService;
|
||||
@Autowired
|
||||
private UserBetsHitRankingService userBetsHitRankingService;
|
||||
@Autowired
|
||||
private UserHighPrizeService highPrizeService;
|
||||
@Autowired
|
||||
private UserBetsPointService userBetsPointService;
|
||||
@Autowired
|
||||
private MailJob mailJob;
|
||||
@Autowired
|
||||
private JedisTemplate jedisTemplate;
|
||||
//endregion
|
||||
|
||||
//region 单挑、单期奖金限制
|
||||
private static ConcurrentHashMap<String, Double> expectDantiaoPrize = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, Double> expectDantiaoUnCachePrize = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, Double> userExpectPrize = new ConcurrentHashMap<>();
|
||||
//endregion
|
||||
|
||||
@Scheduled(cron = "0 0 6 * * *")
|
||||
public void clearCache() {
|
||||
expectDantiaoPrize.clear();
|
||||
userExpectPrize.clear();
|
||||
expectDantiaoUnCachePrize.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void settleUserBets(List<UserBets> userBetsList, LotteryOpenCode openCode, Lottery lottery) {
|
||||
try {
|
||||
// 结算注单
|
||||
for (UserBets userBets : userBetsList) {
|
||||
if (userBets.getTime().compareTo(openCode.getTime()) >= 0) {
|
||||
// 如果投注时间大于抓取时间,不开奖
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
|
||||
if(userBets.getType() == Global.USER_BETS_TYPE_CHASE
|
||||
&& userBets.getChaseStop() == 1){
|
||||
boolean cancelChase = userBetsService.isCancelChase(userBets.getChaseBillno());
|
||||
if (!cancelChase) {
|
||||
calculateUsersBets(userBets, openCode.getCode(), lottery);
|
||||
}
|
||||
}
|
||||
else {
|
||||
calculateUsersBets(userBets, openCode.getCode(), lottery);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("开奖发生错误", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新开奖状态
|
||||
lotteryOpenCodeService.updateOpened(openCode);
|
||||
} catch (Exception e){
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算用户注单
|
||||
*/
|
||||
private void calculateUsersBets(UserBets userBets, String openCode, Lottery lottery){
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
// 计算注单
|
||||
Object[] results = testUsersBets(userBets, openCode, lottery, true);
|
||||
|
||||
long spend = System.currentTimeMillis() - start;
|
||||
if (spend >= 500) {
|
||||
String warningMsg = String.format("开奖耗时告警;计算注单耗时较多;计算注单%s时耗时达到%s", userBets.getId(), spend);
|
||||
log.warn(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
}
|
||||
|
||||
if (results == null || results.length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int winNum = (Integer) results[0];
|
||||
double prize = (Double) results[1];
|
||||
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
|
||||
// 计算结果
|
||||
calculateResult(lottery, userBets, openCode, prize, winNum);
|
||||
|
||||
spend = System.currentTimeMillis() - start;
|
||||
if (spend >= 1000) {
|
||||
String warningMsg = String.format("开奖耗时告警;处理注单耗时较多;处理注单%s时耗时达到%s", userBets.getId(), spend);
|
||||
log.warn(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public double getWinMoneyByCode(WinResult result,UserBets userBets, int bUnitMoney,
|
||||
String [] prizeCodes){
|
||||
LotteryPlayRules rules = dataFactory.getLotteryPlayRules(userBets.getLotteryId(), userBets.getRuleId());
|
||||
String tempPrize = disposeDsPlayPrize(rules,prizeCodes,result.getWinCode());
|
||||
double prize = 0;
|
||||
if(!tempPrize.equals("")){
|
||||
//单注奖金 * 中奖注数 * 倍数
|
||||
prize = MathUtil.multiply(
|
||||
MathUtil.multiply(PrizeUtils.getWinMoneyByCode(rules.getFixed(),
|
||||
userBets.getModel(), bUnitMoney,
|
||||
userBets.getCode(),Double.parseDouble(tempPrize)),
|
||||
result.getWinNum()),
|
||||
userBets.getMultiple());
|
||||
}
|
||||
return prize;
|
||||
}
|
||||
|
||||
|
||||
public LotteryPlayRules[] getZhWinLev(int winNum, Lottery lottery){
|
||||
LotteryPlayRules zuheRules1 = dataFactory.getLotteryPlayRules(lottery.getId(), "dw");//一星奖金配置
|
||||
if(zuheRules1 == null){
|
||||
return null;
|
||||
}
|
||||
if(winNum == 1){
|
||||
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1};
|
||||
return res;
|
||||
}
|
||||
else if(winNum == 2){
|
||||
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"exzhixdsq");
|
||||
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2};
|
||||
return res;
|
||||
}
|
||||
else if(winNum == 3){
|
||||
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"exzhixdsq");
|
||||
LotteryPlayRules zuheRules3 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"sxzhixdsq");
|
||||
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2,zuheRules3};
|
||||
return res;
|
||||
}
|
||||
else if(winNum == 4){
|
||||
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"exzhixdsq");
|
||||
LotteryPlayRules zuheRules3 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"sxzhixdsq");
|
||||
LotteryPlayRules zuheRules4 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"sixzhixzhq");
|
||||
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2,zuheRules3,zuheRules4};
|
||||
return res;
|
||||
}
|
||||
else if(winNum == 5){
|
||||
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"exzhixdsq");
|
||||
LotteryPlayRules zuheRules3 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"sxzhixdsq");
|
||||
LotteryPlayRules zuheRules4 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"sixzhixzhq");
|
||||
LotteryPlayRules zuheRules5 = dataFactory.getLotteryPlayRules(lottery.getId(),
|
||||
"wxzhixzh");
|
||||
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2,zuheRules3,
|
||||
zuheRules4,zuheRules5};
|
||||
return res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String disposeDsPlayPrize(LotteryPlayRules rule,String [] codeArr,String winCode){
|
||||
String [] pr = rule.getPrize().split(",");
|
||||
String res = "";
|
||||
for (int i = 0; i < pr.length; i++) {
|
||||
String [] valuearr = codeArr[i].split(",");
|
||||
for (int j = 0; j < valuearr.length; j++) {
|
||||
if(valuearr[j].trim().equals(winCode.trim())){
|
||||
res = pr[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public void calculateResult(Lottery lottery, UserBets userBets, String openCode, double prize, int winNum) {
|
||||
userBets.setOpenCode(openCode);
|
||||
String prizeTime = new Moment().toSimpleTime();
|
||||
userBets.setPrizeTime(prizeTime);
|
||||
|
||||
boolean succeed = false;
|
||||
if(winNum >0 && prize > 0){
|
||||
userBets.setPrizeMoney(prize);
|
||||
userBets.setStatus(Global.USER_BETS_STATUS_WIN);
|
||||
|
||||
// 生成赢账单并更新中奖报表
|
||||
succeed = userBillService.addUserWinBill(userBets, prize, "派奖");
|
||||
|
||||
if (succeed) {
|
||||
// 更新注单状态
|
||||
userBetsDao.updateStatus(userBets.getId(), Global.USER_BETS_STATUS_WIN, openCode, prize, prizeTime);
|
||||
|
||||
// 修改用户金额并解冻金额
|
||||
userDao.updateLotteryMoney(userBets.getUserId(), prize, -userBets.getMoney());
|
||||
}
|
||||
}else{
|
||||
userBets.setPrizeMoney(0d);
|
||||
// 更新注单状态
|
||||
if (winNum > 0) {
|
||||
userBets.setStatus(Global.USER_BETS_STATUS_WIN);
|
||||
userBetsDao.updateStatus(userBets.getId(), Global.USER_BETS_STATUS_WIN, openCode, 0, prizeTime);
|
||||
}
|
||||
else {
|
||||
userBets.setStatus(Global.USER_BETS_STATUS_OPENED);
|
||||
userBetsDao.updateStatus(userBets.getId(), Global.USER_BETS_STATUS_OPENED, openCode, 0, prizeTime);
|
||||
}
|
||||
|
||||
// 解冻金额
|
||||
userDao.updateFreezeMoney(userBets.getUserId(), -userBets.getMoney());
|
||||
succeed = true;
|
||||
}
|
||||
|
||||
if (succeed == false) {
|
||||
String warningMsg = "结算订单出错;ID:" + userBets.getId() + ",新增赢账单时错误";
|
||||
log.error(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新消费报表
|
||||
String time = DateUtil.formatTime(userBets.getTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
|
||||
userLotteryReportService.update(userBets.getUserId(), Global.BILL_TYPE_BILLING_ORDER, userBets.getMoney(), time);
|
||||
userLotteryDetailsReportService.update(userBets.getUserId(), userBets.getLotteryId(), userBets.getRuleId(), Global.BILL_TYPE_BILLING_ORDER, userBets.getMoney(), time);
|
||||
|
||||
// 返点
|
||||
userBetsPointService.add(userBets); // 异步进行
|
||||
|
||||
// 中奖停止撤单
|
||||
if(winNum > 0){
|
||||
if(userBets.getType() == Global.USER_BETS_TYPE_CHASE
|
||||
&& userBets.getChaseStop() == 1){
|
||||
userBetsService.cancelChase(userBets.getChaseBillno(), userBets.getUserId(), userBets.getExpect()); // 异步进行
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 发送邮件通知
|
||||
if (prize >= dataFactory.getMailConfig().getOpen()) {
|
||||
userBets.setPrizeMoney(prize);
|
||||
mailJob.sendOpen(userBets);
|
||||
}
|
||||
|
||||
// 发送自主彩邮件通知
|
||||
if (lottery.getSelf() == 1) {
|
||||
if (prize >= 200) {
|
||||
UserVO user = dataFactory.getUser(userBets.getUserId());
|
||||
String username = user == null ? "未知" : user.getUsername();
|
||||
mailJob.addWarning("用户"+username+"在自主彩"+lottery.getShowName()+"第"+userBets.getExpect()+"中奖" + prize + "元");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("发送邮件告警错误", e);
|
||||
}
|
||||
|
||||
// // 删除用户奖金设置
|
||||
// delCurrentPrize(userBets);
|
||||
|
||||
try {
|
||||
// 新增中奖排行榜
|
||||
if (dataFactory.getLotteryConfig().isAutoHitRanking()) {
|
||||
userBetsHitRankingService.addIfNecessary(userBets);
|
||||
}
|
||||
|
||||
// 通知用户
|
||||
notifyUser(userBets);
|
||||
|
||||
// 移除未结算订单ID,设置已结算订单ID
|
||||
cacheUserBetsId(userBets);
|
||||
|
||||
// 尝试添加大额中奖记录
|
||||
highPrizeService.addIfNecessary(userBets);
|
||||
} catch (Exception e) {
|
||||
log.error("添加中奖通知信息时异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void cacheUserBetsId(UserBets userBets) {
|
||||
|
||||
final String unOpenCacheKey = String.format(USER_BETS_UNOPEN_RECENT_KEY, userBets.getUserId());
|
||||
final String openedCacheKey = String.format(USER_BETS_OPENED_RECENT_KEY, userBets.getUserId());
|
||||
final String userBetsId = userBets.getId() + "";
|
||||
|
||||
try {
|
||||
jedisTemplate.execute(new JedisTemplate.PipelineActionNoResult() {
|
||||
@Override
|
||||
public void action(Pipeline pipeline) {
|
||||
pipeline.lrem(unOpenCacheKey, 1, userBetsId); // 移除未结算订单ID
|
||||
pipeline.lpush(openedCacheKey, userBetsId); // 设置已结算订单ID
|
||||
pipeline.ltrim(openedCacheKey, 0, 10); // 最多设置10条
|
||||
pipeline.expire(openedCacheKey, 60 * 60 * 12); // 12小时过期
|
||||
pipeline.sync();
|
||||
}
|
||||
});
|
||||
} catch (JedisException e) {
|
||||
log.error("执行Redis缓存注单ID时出错", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyUser(UserBets userBets) {
|
||||
// 域:用户ID:注单ID:失效时间
|
||||
// 值:json,彩票ID,彩票名称,彩票期号,注单ID,注单状态,投注金额,奖金,玩法名称,通知类型
|
||||
|
||||
long expireAt = new Moment().add(USER_BETS_NOTICE_EXPIRE_HOURS, "hours").toDate().getTime(); // 20小时后失效
|
||||
|
||||
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
|
||||
String field = userBets.getUserId() + ":" + userBets.getId() + ":" + expireAt; // 用户ID:注单ID:过期时间
|
||||
Map<String, Object> value = new HashMap<>();
|
||||
|
||||
value.put("lotteryId", lottery.getId()); // 彩票ID
|
||||
value.put("lottery", lottery.getShowName()); // 彩票名称
|
||||
value.put("expect", userBets.getExpect()); // 彩票期号
|
||||
value.put("id", userBets.getId()); // 注单ID
|
||||
value.put("status", userBets.getStatus()); // 注单状态
|
||||
value.put("money", userBets.getMoney()); // 投注金额
|
||||
value.put("prizeMoney", userBets.getPrizeMoney()); // 奖金
|
||||
|
||||
String mname = "";
|
||||
LotteryPlayRules playRules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
LotteryPlayRulesGroup group = dataFactory.getLotteryPlayRulesGroup(lottery.getId(), playRules.getGroupId());
|
||||
if(playRules != null) {
|
||||
mname = "[" + group.getName() + "_" + playRules.getName() + "]";
|
||||
}
|
||||
|
||||
value.put("mname", mname); // 玩法名称
|
||||
value.put("type", NoticeSendType.USER_BETS_NOTICE); // 彩票注单通知类型
|
||||
|
||||
jedisTemplate.hset(USER_BETS_NOTICE_KEY, field, JSON.toJSONString(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算该比投注会中多少钱
|
||||
*/
|
||||
public Object[] testUsersBets(UserBets userBets, String openCode, Lottery lottery, boolean cache){
|
||||
LotteryConfig config = dataFactory.getLotteryConfig();
|
||||
|
||||
String codes = userBets.getCodes();
|
||||
|
||||
// 时时彩任三混合组选
|
||||
LotteryPlayRules userBetsPlayRules = dataFactory.getLotteryPlayRules(userBets.getLotteryId(), userBets.getRuleId());
|
||||
if (lottery.getType() == 1 && userBetsPlayRules.getCode().equals("rx3hhzx")) {
|
||||
return rx3hhzxTestUsersBets(userBets, openCode, lottery, cache);
|
||||
}
|
||||
|
||||
// 获取玩法对应的处理类
|
||||
ITicketPlayHandler handler = TicketPlayHandlerContext.getHandler(lottery.getType(), userBetsPlayRules.getCode());
|
||||
if (handler == null) {
|
||||
log.error("注单{}未找到对应的处理类", userBets.getId());
|
||||
return null;
|
||||
}
|
||||
|
||||
// 计算中奖结果
|
||||
WinResult result = handler.calculateWinNum(userBets.getId(), codes, openCode);
|
||||
|
||||
/**
|
||||
* 计算奖金需要注意的地方:
|
||||
*时时彩:
|
||||
*1、二星前、后 、大小单双玩法, 根据中奖注数计算中奖金额 ( prize * 注数) ----------
|
||||
*3、不定位 前、中、三 一码不定 最多可中三注 ( prize * 注数) ----------
|
||||
*4、所有任选玩法 根据中奖注数计算中奖金额 ( prize * 注数) ----------
|
||||
*5、三星 混合组选在计算奖金的时候需要根据返回的对象玩法ID(playId)判断金额 -----------
|
||||
*6、四、五星组合玩法 需要根据中奖注数 来判断中奖金额 (中奖注数等几星中奖) 1/2/3/4/5 中奖数字 = 对应的金额 --------
|
||||
*7、定位胆 = ( prize * 注数) ----------
|
||||
*11X5:
|
||||
* 1、前三/前二“组选单式” 因为投注时没有去重判断,所有在中奖时需要计算注数 ----------
|
||||
* 2、不 定位玩法中奖需要计算注数 ---------
|
||||
* 3、定 位胆玩法中奖需要计算注数 ----------
|
||||
* 4、 趣味猜中位中奖需要根据中奖号码计算奖金:winCode:为0不需要处理,----------
|
||||
* 3和9 =?奖金,4和8 =?奖金,5和7=?奖金,6 =?奖金 返回03 or 09 ……
|
||||
* 5、 趣味定单双中奖需要根据中奖号码计算奖金:winCode:为0不需要处理,-----------
|
||||
* 5单0双 = ?奖金,4单1双 =?奖金 …… 返回 5单0双,4单1双……
|
||||
* 6、任选单式、复式 X中X 都需要根据中奖注数计算奖金 -----------
|
||||
*
|
||||
*福彩3D、排列3:
|
||||
*1、 前三混合组选 需要根据玩法ID(playId)判断奖金 ------------
|
||||
*2、定位胆需要根据中奖注数计算奖金 ----------
|
||||
*3、不定位需要根据中奖注数计算奖金 -----------
|
||||
*
|
||||
*PK10:
|
||||
*1、定位胆需要根据中奖注数来计算奖金 ------------
|
||||
*
|
||||
*K3:
|
||||
*1、二不同号标准选号计算 “单注奖金 乘以中奖注数” --------
|
||||
*2、二不同号手动选号计算 “单注奖金 乘以中奖注数”(投注时没有去不同位置重复号) ---------
|
||||
*3、二不同号 胆拖计算 “单注奖金 乘以中奖注数” -----------
|
||||
*4、二同号手动选号 “单注奖金 乘以中奖注数” -----------
|
||||
*5、快3和值 和值为3或18一等奖;4或17二等奖;5或16三等奖;6或15四等奖;7或14五等奖;8或13六等奖;9或12七等奖;10或11八等奖 ----
|
||||
*
|
||||
*kl8:
|
||||
* 1、趣味和值大小玩法 根据中奖号码来判断奖金
|
||||
* 2、趣味 奇偶盘玩法 根据中奖号码来判断奖金
|
||||
* 3、趣味 上下盘 根据中奖号码来判断奖金
|
||||
* 4、五行玩法 根据中奖号码来判断奖金
|
||||
*/
|
||||
int winNum = 0;
|
||||
double prize = 0;
|
||||
if(result != null && (result.getWinNum() >0 || CollectionUtils.isNotEmpty(result.getMultipleResults()))){
|
||||
switch (result.getPlayId()) {
|
||||
case "1_wxzhixzh": case "1_sixzhixzhh": case "1_sixzhixzhq": // 时时彩 四/五星 组合
|
||||
LotteryPlayRules[] levNum = getZhWinLev(result.getWinNum(),lottery);
|
||||
double zhprize = 0;
|
||||
for (int i = 0; i < levNum.length; i++) {
|
||||
zhprize += PrizeUtils.getBetWinMoney(levNum[i],userBets.getModel(),
|
||||
config.getbUnitMoney(),userBets.getCode());
|
||||
}
|
||||
//单注奖金 * 倍数
|
||||
prize = MathUtil.multiply(zhprize, userBets.getMultiple());
|
||||
//赋值状态
|
||||
winNum = result.getWinNum();
|
||||
break;
|
||||
case "1_sxzuxzsh":case "1_sxzuxzlh":case "1_sxzuxzsz":
|
||||
case "1_sxzuxzlz":case "1_sxzuxzsq":case "1_sxzuxzlq": // 时时彩混合组选
|
||||
case "4_sanxzs":case "4_sanxzl": // 3D 混合组选
|
||||
case "1_sxzuxhzh":case "1_sxzuxhzz":case "1_sxzuxhzq":
|
||||
String playId = result.getPlayId().substring(result.getPlayId().indexOf("_")+1,
|
||||
result.getPlayId().length());
|
||||
LotteryPlayRules rulezx = dataFactory.getLotteryPlayRules(lottery.getId(),playId);
|
||||
double prizehh = PrizeUtils.getMoney(rulezx, userBets.getModel(), config.getbUnitMoney(), userBets.getCode());
|
||||
//单注奖金 * 中奖注数 * 倍数
|
||||
prize = MathUtil.multiply(MathUtil.multiply(prizehh,result.getWinNum()),
|
||||
userBets.getMultiple());
|
||||
//赋值状态
|
||||
winNum = result.getWinNum();
|
||||
break;
|
||||
case "1_longhuhewq": case "1_longhuhewb": case "1_longhuhews": case "1_longhuhewg": // 时时彩龙虎和
|
||||
case "1_longhuheqb": case "1_longhuheqs": case "1_longhuheqg":
|
||||
case "1_longhuhebs": case "1_longhuhebg":
|
||||
case "1_longhuhesg":
|
||||
|
||||
case "7_lhd_longhuhewq": case "7_lhd_longhuhewb": case "7_lhd_longhuhews": case "7_lhd_longhuhewg": // 龙虎斗
|
||||
case "7_lhd_longhuheqb": case "7_lhd_longhuheqs": case "7_lhd_longhuheqg":
|
||||
case "7_lhd_longhuhebs": case "7_lhd_longhuhebg":
|
||||
case "7_lhd_longhuhesg":
|
||||
winNum = result.getWinNum();
|
||||
LotteryPlayRules rule = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
String calPrize = rule.getPrize().split(",")[result.getPrizeIndex()];
|
||||
|
||||
LotteryPlayRules calRule = new LotteryPlayRules();
|
||||
calRule.setFixed(rule.getFixed());
|
||||
calRule.setPrize(calPrize);
|
||||
|
||||
double prizelh = PrizeUtils.getBetWinMoney(calRule, userBets.getModel(),
|
||||
config.getbUnitMoney(), userBets.getCode());
|
||||
//单注奖金 * 中奖注数 * 倍数
|
||||
prize = MathUtil.multiply(MathUtil.multiply(prizelh,result.getWinNum()),
|
||||
userBets.getMultiple());
|
||||
break;
|
||||
case "2_dds": //11x5 定单双
|
||||
winNum = result.getWinNum();
|
||||
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
|
||||
HConstants.playPrize.dds11x5);
|
||||
break;
|
||||
case "2_czw": //11X5猜中位
|
||||
winNum = result.getWinNum();
|
||||
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
|
||||
HConstants.playPrize.czw11x5);
|
||||
break;
|
||||
case "3_hezhi":// 快3和值
|
||||
winNum = result.getWinNum();
|
||||
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
|
||||
HConstants.playPrize.k3hezhi);
|
||||
break;
|
||||
case "5_hezhidx": //快乐8 和值大小
|
||||
winNum = result.getWinNum();
|
||||
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
|
||||
HConstants.playPrize.kl8hezhidx);
|
||||
break;
|
||||
case "5_jopan": //快乐8 和值 奇偶
|
||||
winNum = result.getWinNum();
|
||||
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
|
||||
HConstants.playPrize.kl8jopan);
|
||||
break;
|
||||
case "5_sxpan": //快乐8 和值 上下
|
||||
winNum = result.getWinNum();
|
||||
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
|
||||
HConstants.playPrize.kl8sxpan);
|
||||
break;
|
||||
case "5_hezhiwx": //快乐8 和值 五行
|
||||
winNum = result.getWinNum();
|
||||
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
|
||||
HConstants.playPrize.kl8wx);
|
||||
break;
|
||||
case "6_pk10_dxdsgyhz":// PK10 大小单双冠亚和值
|
||||
case "6_pk10_hzgyhz":// PK10 和值冠亚和值
|
||||
case "6_pk10_hzqshz":// PK10 和值前三和值
|
||||
if (CollectionUtils.isNotEmpty(result.getMultipleResults())) {
|
||||
winNum = result.getWinNum();
|
||||
|
||||
LotteryPlayRules ruleDefault = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
String[] prizeArr = ruleDefault.getPrize().split(",");
|
||||
double[] prizeArrDouble = new double[prizeArr.length];
|
||||
for (int i = 0; i < prizeArr.length; i++) {
|
||||
prizeArrDouble[i] = Double.valueOf(prizeArr[i]);
|
||||
}
|
||||
|
||||
List<MultipleResult> multipleResults = result.getMultipleResults();
|
||||
|
||||
for (MultipleResult multipleResult : multipleResults) {
|
||||
if (multipleResult.getNums() > 0) {
|
||||
// 赔率
|
||||
double odds = prizeArrDouble[multipleResult.getOddsIndex()];
|
||||
|
||||
// 赔率金额
|
||||
double multiplePrize = PrizeUtils.getPrize(ruleDefault.getFixed(), userBets.getModel(), config.getbUnitMoney(), userBets.getCode(), odds);
|
||||
|
||||
//单注奖金 * 中奖注数 * 倍数
|
||||
multiplePrize = MathUtil.multiply(MathUtil.multiply(multiplePrize, multipleResult.getNums()),userBets.getMultiple());
|
||||
|
||||
prize += multiplePrize;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (CollectionUtils.isNotEmpty(result.getMultipleResults())) {
|
||||
winNum = result.getWinNum();
|
||||
|
||||
LotteryPlayRules ruleDefault = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
String[] prizeArr = ruleDefault.getPrize().split(",");
|
||||
double[] prizeArrDouble = new double[prizeArr.length];
|
||||
for (int i = 0; i < prizeArr.length; i++) {
|
||||
prizeArrDouble[i] = Double.valueOf(prizeArr[i]);
|
||||
}
|
||||
|
||||
List<MultipleResult> multipleResults = result.getMultipleResults();
|
||||
|
||||
for (MultipleResult multipleResult : multipleResults) {
|
||||
if (multipleResult.getNums() > 0) {
|
||||
// 赔率
|
||||
double odds = prizeArrDouble[multipleResult.getOddsIndex()];
|
||||
|
||||
// 赔率金额
|
||||
double multiplePrize = PrizeUtils.getPrize(ruleDefault.getFixed(), userBets.getModel(), config.getbUnitMoney(), userBets.getCode(), odds);
|
||||
|
||||
//单注奖金 * 中奖注数 * 倍数
|
||||
multiplePrize = MathUtil.multiply(MathUtil.multiply(multiplePrize, multipleResult.getNums()),userBets.getMultiple());
|
||||
|
||||
prize += multiplePrize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LotteryPlayRules ruleDefault = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
double prizedefailt = PrizeUtils.getBetWinMoney(ruleDefault, userBets.getModel(), config.getbUnitMoney(), userBets.getCode());
|
||||
//单注奖金 * 中奖注数 * 倍数
|
||||
prize = MathUtil.multiply(MathUtil.multiply(prizedefailt,result.getWinNum()), userBets.getMultiple());
|
||||
//赋值状态
|
||||
winNum = result.getWinNum();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (winNum > 0 && prize > 0) {
|
||||
// 判定是否单挑模式
|
||||
prize = assertDantiao(lottery, userBets, prize, cache);
|
||||
|
||||
// 判断是否已经超出本期奖金
|
||||
prize = assertExpectPrize(lottery, userBets, prize, cache);
|
||||
}
|
||||
|
||||
return new Object[]{winNum, prize};
|
||||
}
|
||||
|
||||
/**
|
||||
* 时时彩任三混合组选
|
||||
*/
|
||||
public Object[] rx3hhzxTestUsersBets(UserBets userBets, String openCode, Lottery lottery, boolean cache) {
|
||||
LotteryConfig config = dataFactory.getLotteryConfig();
|
||||
|
||||
String codes = userBets.getCodes();
|
||||
|
||||
SSCRX3HHZXPlayHanlder hanlder = new SSCRX3HHZXPlayHanlder();
|
||||
List<WinResult> results = hanlder.calculateWinNum(userBets.getId(), codes, openCode);
|
||||
if (results == null || results.size() <= 0) {
|
||||
return new Object[]{0, 0.0};
|
||||
}
|
||||
else {
|
||||
double totalPrize = 0;
|
||||
for (WinResult winResult : results) {
|
||||
LotteryPlayRules rule = dataFactory.getLotteryPlayRules(lottery.getId(), winResult.getPlayId());
|
||||
double rulePrize = PrizeUtils.getBetWinMoney(rule, userBets.getModel(), config.getbUnitMoney(),userBets.getCode());
|
||||
|
||||
// 乘注数
|
||||
totalPrize += MathUtil.multiply(rulePrize, winResult.getWinNum());
|
||||
}
|
||||
//单注奖金 * 倍数
|
||||
totalPrize = MathUtil.multiply(totalPrize, userBets.getMultiple());
|
||||
|
||||
// 判定是否单挑模式
|
||||
totalPrize = assertDantiao(lottery, userBets, totalPrize, cache);
|
||||
|
||||
// 判断是否已经超出本期奖金
|
||||
totalPrize = assertExpectPrize(lottery, userBets, totalPrize, cache);
|
||||
|
||||
return new Object[]{1, totalPrize};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断单挑
|
||||
* 单期同用户多注单共享额度
|
||||
*/
|
||||
private double assertDantiao(Lottery lottery, UserBets userBets, double prize, boolean cacheDantiao) {
|
||||
// 判断单挑
|
||||
double finalPrize = prize;
|
||||
if (lottery.getDantiaoMaxPrize() > 0) {
|
||||
LotteryPlayRules playRules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
|
||||
if (StringUtils.isNotEmpty(playRules.getDantiao())) {
|
||||
int dantiaoNum = getDantiaoNum(userBets, playRules);
|
||||
|
||||
if (dantiaoNum > 0 && userBets.getNums() <= dantiaoNum) {
|
||||
|
||||
// String expectKey = userBets.getLotteryId() + "_" + userBets.getExpect();
|
||||
String expectKey = userBets.getLotteryId() + "_" + userBets.getExpect() + "_" + userBets.getUserId();
|
||||
|
||||
Double beforeTotalPrize = cacheDantiao ? expectDantiaoPrize.get(expectKey) : expectDantiaoUnCachePrize.get(expectKey); // 当期的累计单挑总奖金
|
||||
|
||||
if (beforeTotalPrize == null) beforeTotalPrize = 0d;
|
||||
|
||||
if (beforeTotalPrize >= lottery.getDantiaoMaxPrize()) {
|
||||
finalPrize = 0;
|
||||
}
|
||||
else {
|
||||
double expectPrize = beforeTotalPrize + prize;
|
||||
|
||||
if (expectPrize > lottery.getDantiaoMaxPrize()) {
|
||||
finalPrize = MathUtil.subtract(lottery.getDantiaoMaxPrize(), beforeTotalPrize);
|
||||
|
||||
if (finalPrize < 0) {
|
||||
finalPrize = 0;
|
||||
}
|
||||
}
|
||||
if (cacheDantiao) {
|
||||
expectDantiaoPrize.put(expectKey, (beforeTotalPrize + finalPrize));
|
||||
}
|
||||
else {
|
||||
expectDantiaoUnCachePrize.put(expectKey, (beforeTotalPrize + finalPrize));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheDantiao && prize != finalPrize) {
|
||||
String warningMsg = lottery.getShowName() + "第" + userBets.getExpect() + ",用户注单" + userBets.getBillno() + "派奖时属于单挑模式,原奖金:" + prize + ",清除后奖金:" + finalPrize;
|
||||
log.warn(warningMsg);
|
||||
mailJob.addWarning(warningMsg);
|
||||
}
|
||||
|
||||
return finalPrize;
|
||||
}
|
||||
|
||||
private int getDantiaoNum(UserBets userBets, LotteryPlayRules playRules) {
|
||||
if (playRules.getTypeId() != 1) {
|
||||
return Integer.valueOf(playRules.getDantiao());
|
||||
}
|
||||
|
||||
int totalPosition = getSSCBetTotalPosition(userBets);
|
||||
|
||||
int minPosition;
|
||||
switch (playRules.getCode()) {
|
||||
case "rx2fs":
|
||||
case "rx2ds":
|
||||
case "rx2zx":
|
||||
minPosition = 2;
|
||||
break;
|
||||
case "rx3fs":
|
||||
case "rx3ds":
|
||||
case "rx3z3":
|
||||
case "rx3z6":
|
||||
case "rx3hhzx":
|
||||
minPosition = 3;
|
||||
break;
|
||||
case "rx4fs":
|
||||
case "rx4ds":
|
||||
minPosition = 4;
|
||||
break;
|
||||
// 时时彩中龙虎和玩法投注和号码就算单挑,不论注数
|
||||
case "longhuhewq":
|
||||
case "longhuhewb":
|
||||
case "longhuhews":
|
||||
case "longhuhewg":
|
||||
case "longhuheqb":
|
||||
case "longhuheqs":
|
||||
case "longhuheqg":
|
||||
case "longhuhebs":
|
||||
case "longhuhebg":
|
||||
case "longhuhesg":
|
||||
if (userBets.getCodes().contains("和")) {
|
||||
return Integer.valueOf(playRules.getDantiao());
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
// 时时彩中牛牛玩法投注“五条”、“炸弹”、“葫芦”号码就算单挑,不论注数
|
||||
case "sscniuniu":
|
||||
if (userBets.getCodes().contains("五条")) {
|
||||
return Integer.valueOf(playRules.getDantiao().split(",")[0]);
|
||||
}
|
||||
else if (userBets.getCodes().contains("炸弹")) {
|
||||
return Integer.valueOf(playRules.getDantiao().split(",")[1]);
|
||||
}
|
||||
else if (userBets.getCodes().contains("葫芦")) {
|
||||
return Integer.valueOf(playRules.getDantiao().split(",")[2]);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return Integer.valueOf(playRules.getDantiao());
|
||||
}
|
||||
|
||||
if (minPosition > totalPosition) {
|
||||
log.error("玩法{}配置错误,单挑规则配置错误[{}]", playRules.getName(), playRules.getDantiao());
|
||||
return 0;
|
||||
}
|
||||
|
||||
String[] dantiaoNums = playRules.getDantiao().split(",");
|
||||
return Integer.valueOf(dantiaoNums[totalPosition - minPosition]);
|
||||
}
|
||||
|
||||
private int getSSCBetTotalPosition(UserBets userBets) {
|
||||
LotteryPlayRules playRules = dataFactory.getLotteryPlayRules(userBets.getLotteryId(), userBets.getRuleId());
|
||||
int totalPosition = 0;
|
||||
String[] codes;
|
||||
String format;
|
||||
switch (playRules.getCode()) {
|
||||
case "rx2fs":
|
||||
case "rx3fs":
|
||||
case "rx4fs":
|
||||
codes = userBets.getCodes().split(",");
|
||||
for (String code : codes) {
|
||||
if (NumberUtils.isDigits(code)) {
|
||||
totalPosition++;
|
||||
}
|
||||
}
|
||||
return totalPosition;
|
||||
case "rx2ds":
|
||||
case "rx3ds":
|
||||
case "rx4ds":
|
||||
case "rx3z3":
|
||||
case "rx3z6":
|
||||
case "rx3hhzx":
|
||||
case "rx2zx":
|
||||
format = StringUtil.substring(userBets.getCodes(), "[", "]", false);
|
||||
return StringUtils.countMatches(format, "√");
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户当期奖金是否超额,超出则清零,cacheExpect如果为false,则此处逻辑无效,直接返回参数prize
|
||||
* 单期同用户多注单共享额度
|
||||
*/
|
||||
private double assertExpectPrize(Lottery lottery, UserBets userBets, double prize, boolean cachePrize) {
|
||||
if (cachePrize == false || lottery.getExpectMaxPrize() <= 0) {
|
||||
return prize;
|
||||
}
|
||||
|
||||
String prizeKey = userBets.getLotteryId() + "_" + userBets.getExpect() + "_" + userBets.getUserId();
|
||||
Double beforeTotalPrize = userExpectPrize.get(prizeKey);
|
||||
if (beforeTotalPrize == null) beforeTotalPrize = 0d;
|
||||
|
||||
double expectTotalPrize = beforeTotalPrize + prize;
|
||||
|
||||
double finalPrize = prize;
|
||||
|
||||
if (expectTotalPrize > lottery.getExpectMaxPrize()) {
|
||||
finalPrize = MathUtil.subtract(lottery.getExpectMaxPrize(), beforeTotalPrize);
|
||||
|
||||
if (finalPrize < 0) {
|
||||
finalPrize = 0;
|
||||
}
|
||||
}
|
||||
if (prize != finalPrize) {
|
||||
mailJob.sendExpectExceedPrize(userBets, prize, finalPrize);
|
||||
}
|
||||
|
||||
userExpectPrize.put(prizeKey, (beforeTotalPrize + finalPrize));
|
||||
|
||||
return finalPrize;
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import javautils.date.Moment;
|
||||
import lottery.domains.content.biz.UserBillService;
|
||||
import lottery.domains.content.biz.UserLotteryDetailsReportService;
|
||||
import lottery.domains.content.biz.UserLotteryReportService;
|
||||
import lottery.domains.content.dao.UserBillDao;
|
||||
import lottery.domains.content.dao.UserDao;
|
||||
import lottery.domains.content.entity.User;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
import lottery.domains.content.entity.UserBill;
|
||||
import lottery.domains.content.global.Global;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserBillServiceImpl implements UserBillService {
|
||||
private static final Logger log = LoggerFactory.getLogger(UserBillServiceImpl.class);
|
||||
|
||||
//region services
|
||||
@Autowired
|
||||
private UserBillDao uBillDao;
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
@Autowired
|
||||
private UserLotteryReportService uLotteryReportService;
|
||||
@Autowired
|
||||
private UserLotteryDetailsReportService uLotteryDetailsReportService;
|
||||
//endregion
|
||||
|
||||
/**
|
||||
* 生成订单号
|
||||
*/
|
||||
private String billno() {
|
||||
return ObjectId.get().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addCancelOrderBill(UserBets userBets, String remarks) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
User newestUser = userDao.getById(userBets.getUserId());
|
||||
|
||||
String billno = billno();
|
||||
int userId = newestUser.getId();
|
||||
int account = Global.BILL_ACCOUNT_LOTTERY;
|
||||
int type = Global.BILL_TYPE_CANCEL_ORDER;
|
||||
double money = userBets.getMoney();
|
||||
double beforeMoney = newestUser.getLotteryMoney();
|
||||
if (beforeMoney < 0) {
|
||||
beforeMoney = 0;
|
||||
}
|
||||
double afterMoney = newestUser.getLotteryMoney() + money;
|
||||
if (afterMoney < 0) {
|
||||
afterMoney = 0;
|
||||
}
|
||||
Integer refType = type;
|
||||
String refId = String.valueOf(userBets.getId());
|
||||
Moment thisTime = new Moment();
|
||||
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
|
||||
flag = uBillDao.add(tmpBill);
|
||||
// if(flag) {
|
||||
// uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
|
||||
// uLotteryDetailsReportService.update(userId, bBean.getLotteryId(), bBean.getMethod(), type, money, thisTime.toSimpleDate());
|
||||
// }
|
||||
} catch (Exception e) {
|
||||
log.error("写入彩票撤单失败!", e);
|
||||
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addUserWinBill(UserBets userBets, double amount, String remarks) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
User newestUser = userDao.getById(userBets.getUserId());
|
||||
|
||||
String billno = billno();
|
||||
int userId = newestUser.getId();
|
||||
int type = Global.BILL_TYPE_PRIZE;
|
||||
int refType = type;
|
||||
int account = Global.BILL_ACCOUNT_LOTTERY;
|
||||
String refId = String.valueOf(userBets.getId());
|
||||
double money = amount;
|
||||
double beforeMoney = newestUser.getLotteryMoney();
|
||||
if (beforeMoney < 0) {
|
||||
beforeMoney = 0;
|
||||
}
|
||||
double afterMoney = newestUser.getLotteryMoney() + money;
|
||||
if (afterMoney < 0) {
|
||||
afterMoney = 0;
|
||||
}
|
||||
Moment thisTime = new Moment();
|
||||
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
|
||||
flag = uBillDao.add(tmpBill);
|
||||
if(flag) {
|
||||
// Moment betTime = new Moment().fromTime(userBets.getTime()); // 报表计算到投注时间那边
|
||||
uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
|
||||
uLotteryDetailsReportService.update(userId, userBets.getLotteryId(), userBets.getRuleId(), type, amount, thisTime.toSimpleDate());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("写入账单失败!", e);
|
||||
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addProxyReturnBill(UserBets userBets, int upId, double amount, String remarks) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
User newestUser = userDao.getById(upId);
|
||||
|
||||
String billno = billno();
|
||||
int userId = newestUser.getId();
|
||||
int type = Global.BILL_TYPE_PROXY_RETURN;
|
||||
int refType = type;
|
||||
int account = Global.BILL_ACCOUNT_LOTTERY;
|
||||
String refId = String.valueOf(userBets.getId());
|
||||
double money = amount;
|
||||
double beforeMoney = newestUser.getLotteryMoney();
|
||||
if (beforeMoney < 0) {
|
||||
beforeMoney = 0;
|
||||
}
|
||||
double afterMoney = newestUser.getLotteryMoney() + money;
|
||||
if (afterMoney < 0) {
|
||||
afterMoney = 0;
|
||||
}
|
||||
Moment thisTime = new Moment();
|
||||
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
|
||||
flag = uBillDao.add(tmpBill);
|
||||
if(flag) {
|
||||
// Moment betTime = new Moment().fromTime(userBets.getTime()); // 报表计算到投注时间那边
|
||||
uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
|
||||
uLotteryDetailsReportService.update(userId, userBets.getLotteryId(), userBets.getRuleId(), type, amount, thisTime.toSimpleDate());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("写入账单失败!", e);
|
||||
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addSpendReturnBill(UserBets userBets, double amount, String remarks) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
User newestUser = userDao.getById(userBets.getUserId());
|
||||
String billno = billno();
|
||||
int userId = newestUser.getId();
|
||||
int type = Global.BILL_TYPE_SPEND_RETURN;
|
||||
int refType = type;
|
||||
int account = Global.BILL_ACCOUNT_LOTTERY;
|
||||
String refId = String.valueOf(userBets.getId());
|
||||
double money = amount;
|
||||
double beforeMoney = newestUser.getLotteryMoney();
|
||||
if (beforeMoney < 0) {
|
||||
beforeMoney = 0;
|
||||
}
|
||||
double afterMoney = newestUser.getLotteryMoney() + money;
|
||||
if (afterMoney < 0) {
|
||||
afterMoney = 0;
|
||||
}
|
||||
Moment thisTime = new Moment();
|
||||
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
|
||||
flag = uBillDao.add(tmpBill);
|
||||
if(flag) {
|
||||
uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
|
||||
uLotteryDetailsReportService.update(userId, userBets.getLotteryId(), userBets.getRuleId(), type, amount, thisTime.toSimpleDate());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("写入账单失败!", e);
|
||||
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addSpendBill(UserBets bBean) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
User newestUser = userDao.getById(bBean.getUserId());
|
||||
|
||||
String billno = billno();
|
||||
int userId = newestUser.getId();
|
||||
int account = Global.BILL_ACCOUNT_LOTTERY;
|
||||
int type = Global.BILL_TYPE_SPEND;
|
||||
double money = bBean.getMoney();
|
||||
|
||||
double beforeMoney = newestUser.getLotteryMoney() + money;
|
||||
double afterMoney = newestUser.getLotteryMoney();
|
||||
|
||||
if (beforeMoney <= 0) {
|
||||
beforeMoney = 0;
|
||||
}
|
||||
if (afterMoney <= 0) {
|
||||
afterMoney = 0;
|
||||
}
|
||||
|
||||
Integer refType = type;
|
||||
String refId = String.valueOf(bBean.getId());
|
||||
Moment thisTime = new Moment();
|
||||
String remarks = "用户投注:" + bBean.getExpect();
|
||||
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
|
||||
flag = uBillDao.add(tmpBill);
|
||||
if(flag) {
|
||||
uLotteryDetailsReportService.update(userId, bBean.getLotteryId(), bBean.getRuleId(), type, money, thisTime.toSimpleDate());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("写入彩票消费失败!", e);
|
||||
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import javautils.math.MathUtil;
|
||||
import javautils.redis.JedisTemplate;
|
||||
import lottery.domains.content.biz.UserHighPrizeService;
|
||||
import lottery.domains.content.dao.UserDao;
|
||||
import lottery.domains.content.dao.UserHighPrizeDao;
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
import lottery.domains.content.entity.User;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
import lottery.domains.content.entity.UserHighPrize;
|
||||
import lottery.domains.pool.DataFactory;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/3/13.
|
||||
*/
|
||||
@Service
|
||||
public class UserHighPrizeServiceImpl implements UserHighPrizeService {
|
||||
private static final Logger log = LoggerFactory.getLogger(UserHighPrizeServiceImpl.class);
|
||||
|
||||
private static final String USER_HIGH_PRIZE_NOTICE_KEY = "USER:HIGH_PRIZE:NOTICE";
|
||||
|
||||
private BlockingQueue<UserBets> userBetsQueue = new LinkedBlockingDeque<>();
|
||||
|
||||
@Autowired
|
||||
private UserHighPrizeDao highTimesDao;
|
||||
|
||||
@Autowired
|
||||
private JedisTemplate jedisTemplate;
|
||||
|
||||
@Autowired
|
||||
private DataFactory dataFactory;
|
||||
|
||||
@Autowired
|
||||
private UserDao uDao;
|
||||
|
||||
private static boolean isRunning = false;
|
||||
|
||||
@Scheduled(cron = "0/3 * * * * *")
|
||||
public void run() {
|
||||
synchronized (UserHighPrizeServiceImpl.class) {
|
||||
if (isRunning == true) {
|
||||
// 任务正在运行,本次中断
|
||||
return;
|
||||
}
|
||||
isRunning = true;
|
||||
}
|
||||
try {
|
||||
add();
|
||||
} finally {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void add() {
|
||||
if(userBetsQueue != null && userBetsQueue.size() > 0) {
|
||||
try {
|
||||
List<UserBets> adds = new LinkedList<>();
|
||||
userBetsQueue.drainTo(adds, 50);
|
||||
if (CollectionUtils.isNotEmpty(adds)) {
|
||||
add(adds);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("添加用户大额中奖失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void add(List<UserBets> adds) {
|
||||
Map<Integer, User> userMap = new HashMap<>();
|
||||
for (UserBets add : adds) {
|
||||
Lottery lottery = dataFactory.getLottery(add.getLotteryId());
|
||||
if (lottery == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
User user = null;
|
||||
if (userMap.containsKey(add.getUserId())) {
|
||||
user = userMap.get(add.getUserId());
|
||||
}
|
||||
if (user == null) {
|
||||
user = uDao.getById(add.getUserId());
|
||||
}
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UserHighPrize highTimes = convert(add, lottery, user);
|
||||
|
||||
// 加到数据库
|
||||
highTimesDao.add(highTimes);
|
||||
|
||||
// // 加到redis提醒 暂时取消使用,把这句注释取消,再在global.js里把registerWebSocket()取消注释就可以启用了
|
||||
// addToRedis(highTimes, user);
|
||||
}
|
||||
}
|
||||
|
||||
private UserHighPrize convert(UserBets userBets, Lottery lottery, User user) {
|
||||
UserHighPrize highPrize = new UserHighPrize();
|
||||
highPrize.setUserId(user.getId());
|
||||
highPrize.setPlatform(2); // 类型;2:彩票;11:PT;4:AG
|
||||
highPrize.setName(lottery.getShowName());
|
||||
highPrize.setNameId(lottery.getId()+"");
|
||||
highPrize.setSubName(userBets.getExpect());
|
||||
highPrize.setRefId(userBets.getId()+"");
|
||||
highPrize.setMoney(userBets.getMoney());
|
||||
highPrize.setPrizeMoney(userBets.getPrizeMoney());
|
||||
|
||||
double times = userBets.getPrizeMoney() / userBets.getMoney();
|
||||
times = MathUtil.doubleFormat(times, 3);
|
||||
highPrize.setTimes(times);
|
||||
highPrize.setTime(userBets.getPrizeTime());
|
||||
highPrize.setStatus(0); // 状态;0:待确认;1:已锁定;2:已确认
|
||||
|
||||
return highPrize;
|
||||
}
|
||||
|
||||
private void addToRedis(UserHighPrize highPrize, User user) {
|
||||
// 域:数据ID
|
||||
// 值:描述语言
|
||||
|
||||
String field = highPrize.getId()+""; // 数据ID
|
||||
Map<String, Object> value = new HashMap<>();
|
||||
|
||||
value.put("platform", highPrize.getPlatform()); // 类型;2:彩票;11:PT;4:AG
|
||||
value.put("username", user.getUsername()); // 用户名
|
||||
value.put("name", highPrize.getName()); // 游戏名称
|
||||
value.put("subName", highPrize.getSubName()); // 期号或桌号等
|
||||
value.put("refId", highPrize.getRefId()); // 游戏记录ID,可以是user_bets的id也可能是game_bets的id
|
||||
value.put("money", highPrize.getMoney()); // 投注金额
|
||||
value.put("prizeMoney", highPrize.getPrizeMoney()); // 奖金
|
||||
value.put("times", highPrize.getTimes()); // 倍数
|
||||
value.put("type", 1); // 1:大额中奖提醒
|
||||
|
||||
// String money = BigDecimal.valueOf(highPrize.getMoney()).setScale(4, BigDecimal.ROUND_HALF_DOWN).toString();
|
||||
// String prizeMoney = BigDecimal.valueOf(highPrize.getPrizeMoney()).setScale(5, BigDecimal.ROUND_HALF_DOWN).toString();
|
||||
|
||||
// if (highPrize.getTimes() >= 3) {
|
||||
// value = "用户%s在%s投注¥%s元中奖¥%s元,奖金倍数:%s,请在<大额中奖查询>中确认";
|
||||
// value = String.format(value, user.getUsername(), highPrize.getName(), money, prizeMoney, highPrize.getTimes());
|
||||
// }
|
||||
// else {
|
||||
// value = "用户%s在%s投注¥%s元中奖¥%s元,请在<大额中奖查询>中确认";
|
||||
// value = String.format(value, user.getUsername(), highPrize.getName(), money, prizeMoney);
|
||||
// }
|
||||
|
||||
jedisTemplate.hset(USER_HIGH_PRIZE_NOTICE_KEY, field, JSON.toJSONString(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addIfNecessary(UserBets userBets) {
|
||||
if (userBets.getPrizeMoney() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (userBets.getPrizeMoney() <= 100 && userBets.getMoney() <= 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 奖金大于1万,倍数高于5倍
|
||||
double times = userBets.getPrizeMoney() / userBets.getMoney();
|
||||
if (userBets.getPrizeMoney() >= 10000 || times >= 5.0) {
|
||||
userBetsQueue.offer(userBets);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String value = "用户%s在%s%s投注¥%s元中奖¥%s元,请在<大额中奖查询>中确认";
|
||||
value = String.format(value, "aaa", "aaa", "aaa", "100", "200");
|
||||
System.out.println(value);
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import lottery.domains.content.biz.UserLotteryDetailsReportService;
|
||||
import lottery.domains.content.dao.UserLotteryDetailsReportDao;
|
||||
import lottery.domains.content.entity.UserLotteryDetailsReport;
|
||||
import lottery.domains.content.global.Global;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserLotteryDetailsReportServiceImpl implements UserLotteryDetailsReportService {
|
||||
|
||||
@Autowired
|
||||
private UserLotteryDetailsReportDao uLotteryDetailsReportDao;
|
||||
|
||||
@Override
|
||||
public void addDetailsReports(List<UserLotteryDetailsReport> detailsReports) {
|
||||
uLotteryDetailsReportDao.addDetailsReports(detailsReports);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean update(int userId, int lotteryId, int ruleId, int type, double amount,
|
||||
String time) {
|
||||
UserLotteryDetailsReport entity = new UserLotteryDetailsReport();
|
||||
switch (type) {
|
||||
case Global.BILL_TYPE_SPEND:
|
||||
entity.setSpend(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_PRIZE:
|
||||
entity.setPrize(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_SPEND_RETURN:
|
||||
entity.setSpendReturn(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_PROXY_RETURN:
|
||||
entity.setProxyReturn(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_CANCEL_ORDER:
|
||||
entity.setCancelOrder(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_BILLING_ORDER:
|
||||
entity.setBillingOrder(amount);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
UserLotteryDetailsReport bean = uLotteryDetailsReportDao.get(userId, lotteryId, ruleId, time);
|
||||
if(bean != null) {
|
||||
entity.setId(bean.getId());
|
||||
return uLotteryDetailsReportDao.update(entity);
|
||||
} else {
|
||||
entity.setUserId(userId);
|
||||
entity.setLotteryId(lotteryId);
|
||||
entity.setRuleId(ruleId);
|
||||
entity.setTime(time);
|
||||
return uLotteryDetailsReportDao.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package lottery.domains.content.biz.impl;
|
||||
|
||||
import lottery.domains.content.biz.UserLotteryReportService;
|
||||
import lottery.domains.content.dao.UserLotteryReportDao;
|
||||
import lottery.domains.content.entity.UserLotteryReport;
|
||||
import lottery.domains.content.global.Global;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserLotteryReportServiceImpl implements UserLotteryReportService {
|
||||
|
||||
@Autowired
|
||||
private UserLotteryReportDao uLotteryReportDao;
|
||||
|
||||
@Override
|
||||
public boolean update(int userId, int type, double amount, String time) {
|
||||
UserLotteryReport entity = new UserLotteryReport();
|
||||
switch (type) {
|
||||
case Global.BILL_TYPE_TRANS_IN:
|
||||
entity.setTransIn(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_TRANS_OUT:
|
||||
entity.setTransOut(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_SPEND:
|
||||
entity.setSpend(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_PRIZE:
|
||||
entity.setPrize(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_SPEND_RETURN:
|
||||
entity.setSpendReturn(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_PROXY_RETURN:
|
||||
entity.setProxyReturn(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_CANCEL_ORDER:
|
||||
entity.setCancelOrder(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_DIVIDEND:
|
||||
entity.setDividend(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_ACTIVITY:
|
||||
case Global.BILL_TYPE_INTEGRAL:
|
||||
entity.setActivity(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_RED_PACKET:
|
||||
entity.setPacket(amount);
|
||||
break;
|
||||
case Global.BILL_TYPE_BILLING_ORDER:
|
||||
entity.setBillingOrder(amount);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
UserLotteryReport bean = uLotteryReportDao.get(userId, time);
|
||||
if(bean != null) {
|
||||
entity.setId(bean.getId());
|
||||
return uLotteryReportDao.update(entity);
|
||||
} else {
|
||||
entity.setUserId(userId);
|
||||
entity.setTime(time);
|
||||
return uLotteryReportDao.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.DbServerSync;
|
||||
import lottery.domains.content.global.DbServerSyncEnum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DbServerSyncDao {
|
||||
|
||||
List<DbServerSync> listAll();
|
||||
|
||||
boolean update(DbServerSyncEnum type);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryDao {
|
||||
|
||||
List<Lottery> listAll();
|
||||
|
||||
boolean updateStatus(int id, int status);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryOpenCodeDao {
|
||||
/**
|
||||
* 修改为已开奖
|
||||
*/
|
||||
boolean updateOpened(int id, String updateTime);
|
||||
/**
|
||||
* 修改为无效已撤单
|
||||
*/
|
||||
boolean updateCancelled(int id, String updateTime);
|
||||
|
||||
List<LotteryOpenCode> getLatest(String lottery, int count);
|
||||
|
||||
List<LotteryOpenCode> listAfter(String lottery, String expect);
|
||||
|
||||
/**
|
||||
* 获取往期未开奖的期数
|
||||
*/
|
||||
List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count);
|
||||
|
||||
LotteryOpenCode getByExcept(String lottery, String except);
|
||||
|
||||
/**
|
||||
* 根据彩票ID和期号以及用户获取开奖号码
|
||||
*/
|
||||
LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except);
|
||||
|
||||
boolean add(LotteryOpenCode openCode);
|
||||
|
||||
boolean update(LotteryOpenCode openCode);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import javautils.jdbc.PageList;
|
||||
import lottery.domains.content.entity.LotteryOpenTime;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryOpenTimeDao {
|
||||
|
||||
List<LotteryOpenTime> listAll();
|
||||
|
||||
PageList find(List<Criterion> criterions, List<Order> orders, int start, int limit);
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRulesConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesConfigDao {
|
||||
|
||||
List<LotteryPlayRulesConfig> listAll();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRules;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesDao {
|
||||
|
||||
List<LotteryPlayRules> listAll();
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesGroupConfigDao {
|
||||
|
||||
List<LotteryPlayRulesGroupConfig> listAll();
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryPlayRulesGroupDao {
|
||||
|
||||
List<LotteryPlayRulesGroup> listAll();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.LotteryType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LotteryTypeDao {
|
||||
|
||||
List<LotteryType> listAll();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.SysConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SysConfigDao {
|
||||
|
||||
List<SysConfig> listAll();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import javautils.jdbc.PageList;
|
||||
import lottery.domains.content.entity.UserBets;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserBetsDao {
|
||||
boolean add(UserBets userBets);
|
||||
|
||||
UserBets getById(int id);
|
||||
|
||||
UserBets getById(int id, int userId);
|
||||
|
||||
List<UserBets> getByChaseBillno(String chaseBillno, int userId, String winExpect);
|
||||
|
||||
List<UserBets> getByFollowBillno(String followBillno);
|
||||
|
||||
boolean updateToPlan(int id, int type, String planBillno);
|
||||
|
||||
List<UserBets> list(List<Criterion> criterions, List<Order> orders);
|
||||
|
||||
PageList search(List<Criterion> criterions, List<Order> orders, int start, int limit);
|
||||
|
||||
boolean updateStatus(int id, int status, String openCode, double prizeMoney, String prizeTime);
|
||||
|
||||
boolean cancel(int id);
|
||||
|
||||
boolean cancelAndSetOpenCode(int id, String openCode);
|
||||
|
||||
List<?> sumUserProfitGroupByUserId(int lotteryId, String startTime, String endTime, List<Integer> userIds);
|
||||
|
||||
double[] sumProfit(int lotteryId, String startTime, String endTime);
|
||||
|
||||
List<UserBets> getLatest(int userId, int lotteryId, int count);
|
||||
|
||||
List<UserBets> getByExpect(int lotteryId, String expect);
|
||||
|
||||
List<UserBets> getByUserIdAndExpect(int userId, int lotteryId, String expect);
|
||||
|
||||
List<UserBets> getNoDemoUserBetsByExpect(String hsql ,Object[] values);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.UserBetsHitRanking;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserBetsHitRankingDao {
|
||||
long getTotalSize(int platform);
|
||||
|
||||
UserBetsHitRanking getMinRanking(int platform, String startTime, String endTime);
|
||||
|
||||
boolean add(UserBetsHitRanking ranking);
|
||||
|
||||
List<Integer> getIds(int platform, String startTime, String endTime);
|
||||
|
||||
List<Integer> getTotalIds(int count, int platform, String startTime, String endTime);
|
||||
|
||||
List<Integer> getIdsByTimeDesc(int count, int platform);
|
||||
|
||||
int delNotInIds(List<Integer> ids, int platform);
|
||||
|
||||
boolean delNotInIds(List<Integer> ids, int platform, String startTime, String endTime);
|
||||
|
||||
boolean delByTime(int platform, String endTime);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.UserBetsOriginal;
|
||||
|
||||
/**
|
||||
* Created by Nick on 2017/1/15.
|
||||
*/
|
||||
public interface UserBetsOriginalDao {
|
||||
boolean add(UserBetsOriginal original);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.UserBetsRisk;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserBetsRiskDao {
|
||||
List<UserBetsRisk> list(List<Criterion> criterions, List<Order> orders);
|
||||
|
||||
boolean updateStatus(int id, int fromStatus, int toStatus, String openCode, double prizeMoney, String prizeTime, int winNum);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javautils.jdbc.PageList;
|
||||
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
|
||||
import lottery.domains.content.entity.UserBill;
|
||||
|
||||
public interface UserBillDao {
|
||||
|
||||
boolean add(UserBill entity);
|
||||
|
||||
/**
|
||||
* 批量新增注单
|
||||
*/
|
||||
boolean addBills(List<UserBill> userBills);
|
||||
|
||||
UserBill getById(int id);
|
||||
|
||||
PageList search(List<Criterion> criterions, List<Order> orders, int start, int limit);
|
||||
|
||||
/**
|
||||
* 清理负数之前之前金额
|
||||
*/
|
||||
int clearUserBillNegateBeforeMoney();
|
||||
|
||||
/**
|
||||
* 清理负数之前之后金额
|
||||
*/
|
||||
int clearUserBillNegateAfterMoney();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.User;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserDao {
|
||||
/**
|
||||
* 列出用户
|
||||
*/
|
||||
List<User> list(List<Criterion> criterions, List<Order> orders);
|
||||
|
||||
/**
|
||||
* 列出所有用户
|
||||
*/
|
||||
List<User> listAll();
|
||||
|
||||
|
||||
/**
|
||||
* 更新彩票账户资金
|
||||
*/
|
||||
boolean updateLotteryMoney(int id, double lotteryAmount, double freezeAmount);
|
||||
|
||||
/**
|
||||
* 更新彩票账户资金
|
||||
*/
|
||||
boolean updateLotteryMoney(int id, double lotteryAmount);
|
||||
|
||||
/**
|
||||
* 更新彩票账户资金
|
||||
*/
|
||||
boolean updateFreezeMoney(int id, double freezeAmount);
|
||||
|
||||
/**
|
||||
* 通过id获取用户
|
||||
*/
|
||||
User getById(int id);
|
||||
|
||||
/**
|
||||
* 清理用户负数金额
|
||||
*/
|
||||
int clearUserNegateFreezeMoney();
|
||||
|
||||
/**
|
||||
* 获取用户下级代理
|
||||
*/
|
||||
List<User> getUserLower(int id);
|
||||
|
||||
/**
|
||||
* 获取直属下级
|
||||
*/
|
||||
List<User> getUserDirectLower(int id);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.UserHighPrize;
|
||||
|
||||
public interface UserHighPrizeDao {
|
||||
boolean add(UserHighPrize entity);
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.UserLotteryDetailsReport;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserLotteryDetailsReportDao {
|
||||
|
||||
boolean add(UserLotteryDetailsReport entity);
|
||||
|
||||
UserLotteryDetailsReport get(int userId, int lotteryId, int ruleId, String time);
|
||||
|
||||
boolean update(UserLotteryDetailsReport entity);
|
||||
|
||||
void addDetailsReports(List<UserLotteryDetailsReport> detailsReports);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package lottery.domains.content.dao;
|
||||
|
||||
import lottery.domains.content.entity.UserLotteryReport;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UserLotteryReportDao {
|
||||
|
||||
UserLotteryReport get(int userId, String time);
|
||||
|
||||
boolean update(UserLotteryReport entity);
|
||||
|
||||
boolean add(UserLotteryReport entity);
|
||||
|
||||
List<UserLotteryReport> find(List<Criterion> criterions, List<Order> orders);
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.date.Moment;
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.DbServerSyncDao;
|
||||
import lottery.domains.content.entity.DbServerSync;
|
||||
import lottery.domains.content.global.DbServerSyncEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class DbServerSyncDaoImpl implements DbServerSyncDao {
|
||||
|
||||
private final String tab = DbServerSync.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<DbServerSync> superDao;
|
||||
|
||||
@Override
|
||||
public List<DbServerSync> listAll() {
|
||||
String hql = "from " + tab;
|
||||
return superDao.list(hql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(DbServerSyncEnum type) {
|
||||
String key = type.name();
|
||||
String time = new Moment().toSimpleTime();
|
||||
String hql = "update " + tab + " set lastModTime = ?1 where key = ?0";
|
||||
Object[] values = {key, time};
|
||||
return superDao.update(hql, values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.LotteryDao;
|
||||
import lottery.domains.content.entity.Lottery;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class LotteryDaoImpl implements LotteryDao {
|
||||
|
||||
private final String tab = Lottery.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<Lottery> superDao;
|
||||
|
||||
@Override
|
||||
public List<Lottery> listAll() {
|
||||
String hql = "from " + tab + " order by sort, type";
|
||||
return superDao.list(hql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateStatus(int id, int status) {
|
||||
String hql = "update " + tab + " set status = ?1 where id = ?0";
|
||||
Object[] values = {id, status};
|
||||
return superDao.update(hql, values);
|
||||
}
|
||||
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.LotteryOpenCodeDao;
|
||||
import lottery.domains.content.entity.LotteryOpenCode;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class LotteryOpenCodeDaoImpl implements LotteryOpenCodeDao {
|
||||
private final String tab = LotteryOpenCode.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<LotteryOpenCode> superDao;
|
||||
|
||||
@Override
|
||||
public boolean updateOpened(int id, String updateTime) {
|
||||
String hql = "update " + tab + " set openStatus = 1, openTime = ?0 where id=?1";
|
||||
Object[] values = {updateTime, id};
|
||||
return superDao.update(hql, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateCancelled(int id, String updateTime) {
|
||||
String hql = "update " + tab + " set openStatus = 3, openTime = ?0 where id=?1";
|
||||
Object[] values = {updateTime, id};
|
||||
return superDao.update(hql, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LotteryOpenCode> getLatest(String lottery, int count) {
|
||||
String hql = "from " + tab + " where lottery=?0 order by expect desc";
|
||||
Object[] values = {lottery};
|
||||
List<LotteryOpenCode> list = superDao.list(hql, values, 0, count);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LotteryOpenCode> listAfter(String lottery, String expect) {
|
||||
String hql = "from " + tab + " where lottery=?0 and expect>=?1";
|
||||
Object[] values = {lottery, expect};
|
||||
List<LotteryOpenCode> list = superDao.list(hql, values);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count) {
|
||||
String hql = "from " + tab + " where openStatus = 0 and lottery=?0 order by expect desc";
|
||||
Object[] values = {lottery};
|
||||
List<LotteryOpenCode> list = superDao.list(hql, values, 0, count);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LotteryOpenCode getByExcept(String lottery, String except) {
|
||||
String hql = "from " + tab + " where lottery=?0 and expect = ?1 ";
|
||||
Object[] values = {lottery,except};
|
||||
List<LotteryOpenCode> list = superDao.list(hql, values, 0, 1);
|
||||
if(list != null && list.size() > 0) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except) {
|
||||
String hql = "from " + tab + " where lottery=?0 and expect = ?1 and userId = ?2";
|
||||
Object[] values = {lottery,except, userId};
|
||||
List<LotteryOpenCode> list = superDao.list(hql, values, 0, 1);
|
||||
if(list != null && list.size() > 0) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(LotteryOpenCode openCode) {
|
||||
return superDao.save(openCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(LotteryOpenCode openCode) {
|
||||
return superDao.update(openCode);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.jdbc.PageList;
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.LotteryOpenTimeDao;
|
||||
import lottery.domains.content.entity.LotteryOpenTime;
|
||||
import org.hibernate.criterion.Criterion;
|
||||
import org.hibernate.criterion.Order;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class LotteryOpenTimeDaoImpl implements LotteryOpenTimeDao {
|
||||
|
||||
private final String tab = LotteryOpenTime.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<LotteryOpenTime> superDao;
|
||||
|
||||
@Override
|
||||
public List<LotteryOpenTime> listAll() {
|
||||
String hql = "from " + tab + " order by expect asc";
|
||||
return superDao.list(hql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageList find(List<Criterion> criterions, List<Order> orders, int start, int limit) {
|
||||
return superDao.findPageList(LotteryOpenTime.class, criterions, orders, start, limit);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesConfigDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRulesConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class LotteryPlayRulesConfigDaoImpl implements LotteryPlayRulesConfigDao {
|
||||
|
||||
private final String tab = LotteryPlayRulesConfig.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<LotteryPlayRulesConfig> superDao;
|
||||
|
||||
@Override
|
||||
public List<LotteryPlayRulesConfig> listAll() {
|
||||
String hql = "from " + tab;
|
||||
return superDao.list(hql);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRules;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class LotteryPlayRulesDaoImpl implements LotteryPlayRulesDao {
|
||||
|
||||
private final String tab = LotteryPlayRules.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<LotteryPlayRules> superDao;
|
||||
|
||||
@Override
|
||||
public List<LotteryPlayRules> listAll() {
|
||||
String hql = "from " + tab + " order by typeId, groupId";
|
||||
return superDao.list(hql);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesGroupConfigDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class LotteryPlayRulesGroupConfigDaoImpl implements LotteryPlayRulesGroupConfigDao {
|
||||
|
||||
private final String tab = LotteryPlayRulesGroupConfig.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<LotteryPlayRulesGroupConfig> superDao;
|
||||
|
||||
@Override
|
||||
public List<LotteryPlayRulesGroupConfig> listAll() {
|
||||
String hql = "from " + tab + " order by id";
|
||||
return superDao.list(hql);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package lottery.domains.content.dao.impl;
|
||||
|
||||
import javautils.jdbc.hibernate.HibernateSuperDao;
|
||||
import lottery.domains.content.dao.LotteryPlayRulesGroupDao;
|
||||
import lottery.domains.content.entity.LotteryPlayRulesGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class LotteryPlayRulesGroupDaoImpl implements LotteryPlayRulesGroupDao {
|
||||
|
||||
private final String tab = LotteryPlayRulesGroup.class.getSimpleName();
|
||||
|
||||
@Autowired
|
||||
private HibernateSuperDao<LotteryPlayRulesGroup> superDao;
|
||||
|
||||
@Override
|
||||
public List<LotteryPlayRulesGroup> listAll() {
|
||||
String hql = "from " + tab + " order by typeId,sort";
|
||||
return superDao.list(hql);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user