@@ -0,0 +1,10 @@ | |||||
**/target/ | |||||
**/resources/code/ | |||||
/.idea/ | |||||
*.iml | |||||
/logs | |||||
.classpath | |||||
.project | |||||
.factorypath | |||||
**/.settings/ | |||||
.vscode/ |
@@ -0,0 +1,78 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<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"> | |||||
<parent> | |||||
<artifactId>codeGenerate</artifactId> | |||||
<groupId>com.qmrz</groupId> | |||||
<version>1.0</version> | |||||
</parent> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<artifactId>code-generator</artifactId> | |||||
<packaging>jar</packaging> | |||||
<dependencies> | |||||
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-maven-plugin --> | |||||
<dependency> | |||||
<groupId>org.mybatis.generator</groupId> | |||||
<artifactId>mybatis-generator-maven-plugin</artifactId> | |||||
<version>1.3.7</version> | |||||
</dependency> | |||||
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core --> | |||||
<dependency> | |||||
<groupId>org.mybatis.generator</groupId> | |||||
<artifactId>mybatis-generator-core</artifactId> | |||||
<version>1.3.7</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>com.qmrz</groupId> | |||||
<artifactId>common</artifactId> | |||||
<version>1.0</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>mysql</groupId> | |||||
<artifactId>mysql-connector-java</artifactId> | |||||
<version>8.0.11</version> | |||||
</dependency> | |||||
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker --> | |||||
<dependency> | |||||
<groupId>org.freemarker</groupId> | |||||
<artifactId>freemarker</artifactId> | |||||
<version>2.3.28</version> | |||||
</dependency> | |||||
<dependency> | |||||
<groupId>org.testng</groupId> | |||||
<artifactId>testng</artifactId> | |||||
<version>RELEASE</version> | |||||
<scope>test</scope> | |||||
</dependency> | |||||
</dependencies> | |||||
<build> | |||||
<finalName>CodeGenerator</finalName> | |||||
<plugins> | |||||
<plugin> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-maven-plugin</artifactId> | |||||
<configuration> | |||||
<fork>true</fork> | |||||
<mainClass>com.qmrz.CodeGenerator</mainClass> | |||||
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments> | |||||
</configuration> | |||||
<executions> | |||||
<execution> | |||||
<configuration> | |||||
<classifier>exec</classifier> | |||||
</configuration> | |||||
</execution> | |||||
</executions> | |||||
</plugin> | |||||
</plugins> | |||||
</build> | |||||
</project> |
@@ -0,0 +1,20 @@ | |||||
package com.qmrz; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.boot.SpringApplication; | |||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; | |||||
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration; | |||||
import org.springframework.cache.annotation.EnableCaching; | |||||
import org.springframework.transaction.annotation.EnableTransactionManagement; | |||||
@Slf4j | |||||
@SpringBootApplication(exclude={RedisAutoConfiguration.class, | |||||
RedisRepositoriesAutoConfiguration.class}) | |||||
@EnableTransactionManagement | |||||
@EnableCaching | |||||
public class CodeGenerator { | |||||
public static void main(String[] args) { | |||||
SpringApplication.run(CodeGenerator.class, args); | |||||
} | |||||
} |
@@ -0,0 +1,43 @@ | |||||
package com.qmrz.generator; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.CGHelper; | |||||
import com.qmrz.utils.Fn; | |||||
import com.qmrz.utils.MapUtil; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* api同步代码 生成 | |||||
*/ | |||||
public class ApiSyncGenerator { | |||||
private TableService tableService; | |||||
private String dbName; | |||||
public ApiSyncGenerator(String dbName) { | |||||
tableService = SpringContextUtil.getBean(TableService.class); | |||||
this.dbName = dbName; | |||||
} | |||||
public void generator() { | |||||
List<Map> tableList = tableService.getTableList(dbName); | |||||
List<Map> columnList = tableService.getColumnList(dbName); | |||||
GeneratorUtil.setColumnShowName(columnList); | |||||
Map result = columnList.stream().collect(Collectors.groupingBy(map -> map.get("table_name"), Collectors.toList())); | |||||
CGHelper cgHelper = new CGHelper("api_sync.ftl", dbName); | |||||
tableList.forEach(item -> { | |||||
String table_name = item.get("table_name").toString(); | |||||
String table_name2 = Fn.firstUpperCase(table_name); | |||||
item.put("columnList", result.get(table_name)); | |||||
item.put("dbname", dbName); | |||||
item.put("table_name2",table_name2);//首字母大写 | |||||
cgHelper.generator("api_sync", table_name2 + "Sync.java", item); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,45 @@ | |||||
package com.qmrz.generator; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.CGHelper; | |||||
import com.qmrz.utils.Fn; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* Controller生成 | |||||
*/ | |||||
public class ControllerGenerator { | |||||
private TableService tableService; | |||||
private String dbName; | |||||
public ControllerGenerator(String dbName) { | |||||
tableService = SpringContextUtil.getBean(TableService.class); | |||||
this.dbName = dbName; | |||||
} | |||||
public void generator() { | |||||
List<Map> tableList = tableService.getTableList(dbName); | |||||
List<Map> columnList = tableService.getColumnList(dbName); | |||||
GeneratorUtil.setColumnShowName(columnList); | |||||
Map result = columnList.stream().collect(Collectors.groupingBy(map -> map.get("table_name"), Collectors.toList())); | |||||
CGHelper cgHelper = new CGHelper("controller.ftl", dbName); | |||||
tableList.forEach(item -> { | |||||
String table_name = item.get("table_name").toString(); | |||||
String table_name2 = Fn.firstUpperCase(table_name); | |||||
item.put("columnList", result.get(table_name)); | |||||
item.put("dbname", dbName); | |||||
item.put("table_name2", table_name2);//首字母大写 | |||||
cgHelper.generator("controller", table_name2 + "Controller.java", item); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,47 @@ | |||||
package com.qmrz.generator; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.CGHelper; | |||||
import com.qmrz.utils.MapUtil; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* 数据库字典生成 | |||||
*/ | |||||
public class DBReadmeGenerator { | |||||
private TableService tableService; | |||||
private String dbName; | |||||
public DBReadmeGenerator(String dbName) { | |||||
tableService = SpringContextUtil.getBean(TableService.class); | |||||
this.dbName = dbName; | |||||
} | |||||
public void generator() { | |||||
List<Map> tableList = tableService.getTableList(dbName); | |||||
List<Map> columnList = tableService.getColumnList(dbName); | |||||
Map result = columnList.stream().collect(Collectors.groupingBy(map -> map.get("table_name"), Collectors.toList())); | |||||
CGHelper cgHelperTable = new CGHelper("db_tables_readme.md", dbName); | |||||
cgHelperTable.generator("", "db_tables.md", MapUtil.newMap() | |||||
.put("dbname", dbName) | |||||
.put("tableList", tableList) | |||||
.getMap() | |||||
); | |||||
CGHelper cgHelper = new CGHelper("db_readme.md", dbName); | |||||
tableList.forEach(item -> { | |||||
String table_name = item.get("table_name").toString(); | |||||
item.put("columnList", result.get(table_name)); | |||||
item.put("dbname", dbName); | |||||
cgHelper.generator("readme", "db_" + table_name + ".md", item); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,29 @@ | |||||
package com.qmrz.generator; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* 生成基础工具 | |||||
* @Author: suger | |||||
*/ | |||||
public class GeneratorUtil { | |||||
/** | |||||
* 增加显示名 | |||||
* @param columnList | |||||
*/ | |||||
public static void setColumnShowName(List<Map> columnList){ | |||||
for (Map item : columnList) { | |||||
String column_name_show_name = String.valueOf(item.get("column_comment")); | |||||
int space_indexof = column_name_show_name.indexOf(" "); | |||||
if (space_indexof > 0) { | |||||
column_name_show_name = column_name_show_name.substring(0, space_indexof).trim(); | |||||
} | |||||
if (column_name_show_name.trim().length() == 0) { | |||||
column_name_show_name = String.valueOf(item.get("column_name")).trim(); | |||||
} | |||||
item.put("column_name_show_name", column_name_show_name);//获取注释的第一个单词,到英文空格为止 | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,44 @@ | |||||
package com.qmrz.generator; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.CGHelper; | |||||
import com.qmrz.utils.MapUtil; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
public class InterfaceReadmeGenerator { | |||||
private TableService tableService; | |||||
private String dbName; | |||||
public InterfaceReadmeGenerator(String dbName) { | |||||
tableService = SpringContextUtil.getBean(TableService.class); | |||||
this.dbName = dbName; | |||||
} | |||||
public void generator() { | |||||
List<Map> tableList = tableService.getTableList(dbName); | |||||
List<Map> columnList = tableService.getColumnList(dbName); | |||||
Map result = columnList.stream().collect(Collectors.groupingBy(map -> map.get("table_name"), Collectors.toList())); | |||||
CGHelper cgHelperTable = new CGHelper("inteface_tables_readme.md", dbName); | |||||
cgHelperTable.generator("", "inteface_tables_readme.md", MapUtil.newMap() | |||||
.put("dbname", dbName) | |||||
.put("tableList", tableList) | |||||
.getMap() | |||||
); | |||||
CGHelper cgHelper = new CGHelper("inteface_tables_readme.md", dbName); | |||||
tableList.forEach(item -> { | |||||
String table_name = item.get("table_name").toString(); | |||||
item.put("columnList", result.get(table_name)); | |||||
item.put("dbname", dbName); | |||||
item.put("filename", "inteface_" + table_name + "_readme.md"); | |||||
cgHelper.generator("readme", "inteface_" + table_name + "_readme.md", item); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,44 @@ | |||||
package com.qmrz.generator; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.CGHelper; | |||||
import com.qmrz.utils.Fn; | |||||
import com.qmrz.utils.MapUtil; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import org.apache.commons.lang.StringUtils; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* Mapper生成 | |||||
*/ | |||||
public class MapperGenerator { | |||||
private TableService tableService; | |||||
private String dbName; | |||||
public MapperGenerator(String dbName) { | |||||
tableService = SpringContextUtil.getBean(TableService.class); | |||||
this.dbName = dbName; | |||||
} | |||||
public void generator() { | |||||
List<Map> tableList = tableService.getTableList(dbName); | |||||
List<Map> columnList = tableService.getColumnList(dbName); | |||||
Map result = columnList.stream().collect(Collectors.groupingBy(map -> map.get("table_name"), Collectors.toList())); | |||||
CGHelper cgHelper = new CGHelper("mapper.ftl", dbName); | |||||
tableList.forEach(item -> { | |||||
String table_name = item.get("table_name").toString(); | |||||
String table_name2 = Fn.firstUpperCase(table_name); | |||||
item.put("columnList", result.get(table_name)); | |||||
item.put("dbname", dbName); | |||||
item.put("table_name2",table_name2);//首字母大写 | |||||
cgHelper.generator("mapper", table_name2 + "Mapper.xml", item); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,42 @@ | |||||
package com.qmrz.generator; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.CGHelper; | |||||
import com.qmrz.utils.Fn; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* Service生成 | |||||
*/ | |||||
public class ServiceGenerator { | |||||
private TableService tableService; | |||||
private String dbName; | |||||
public ServiceGenerator(String dbName) { | |||||
tableService = SpringContextUtil.getBean(TableService.class); | |||||
this.dbName = dbName; | |||||
} | |||||
public void generator() { | |||||
List<Map> tableList = tableService.getTableList(dbName); | |||||
List<Map> columnList = tableService.getColumnList(dbName); | |||||
Map result = columnList.stream().collect(Collectors.groupingBy(map -> map.get("table_name"), Collectors.toList())); | |||||
CGHelper cgHelper = new CGHelper("service.ftl", dbName); | |||||
tableList.forEach(item -> { | |||||
String table_name = item.get("table_name").toString(); | |||||
String table_name2 = Fn.firstUpperCase(table_name); | |||||
item.put("columnList", result.get(table_name)); | |||||
item.put("dbname", dbName); | |||||
item.put("table_name2",table_name2);//首字母大写 | |||||
cgHelper.generator("service", table_name2 + "Service.java", item); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,42 @@ | |||||
package com.qmrz.generator; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.CGHelper; | |||||
import com.qmrz.utils.Fn; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* ServiceImpl生成 | |||||
*/ | |||||
public class ServiceImplGenerator { | |||||
private TableService tableService; | |||||
private String dbName; | |||||
public ServiceImplGenerator(String dbName) { | |||||
tableService = SpringContextUtil.getBean(TableService.class); | |||||
this.dbName = dbName; | |||||
} | |||||
public void generator() { | |||||
List<Map> tableList = tableService.getTableList(dbName); | |||||
List<Map> columnList = tableService.getColumnList(dbName); | |||||
Map result = columnList.stream().collect(Collectors.groupingBy(map -> map.get("table_name"), Collectors.toList())); | |||||
CGHelper cgHelper = new CGHelper("serviceImpl.ftl", dbName); | |||||
tableList.forEach(item -> { | |||||
String table_name = item.get("table_name").toString(); | |||||
String table_name2 = Fn.firstUpperCase(table_name); | |||||
item.put("columnList", result.get(table_name)); | |||||
item.put("dbname", dbName); | |||||
item.put("table_name2",table_name2);//首字母大写 | |||||
cgHelper.generator("serviceImpl", table_name2 + "ServiceImpl.java", item); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,47 @@ | |||||
package com.qmrz.service.Impl; | |||||
import com.qmrz.service.TableService; | |||||
import com.qmrz.utils.DBHelper; | |||||
import com.qmrz.utils.MapUtil; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* 表结构查询 | |||||
*/ | |||||
@Service | |||||
public class TableServiceImpl implements TableService { | |||||
@Autowired | |||||
DBHelper dbHelper; | |||||
/** | |||||
* 获取指定数据库的所有表结构 | |||||
* @param dbName | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public List<Map> getColumnList(String dbName) { | |||||
return dbHelper.selectList("TableMapper.getColumnList" | |||||
, MapUtil.newMap() | |||||
.put("dbname", dbName) | |||||
.getMap() | |||||
); | |||||
} | |||||
/** | |||||
* 获取指定数据库的所有表 | |||||
* @param dbName | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public List<Map> getTableList(String dbName) { | |||||
return dbHelper.selectList("TableMapper.getTableList" | |||||
, MapUtil.newMap() | |||||
.put("dbname", dbName) | |||||
.getMap() | |||||
); | |||||
} | |||||
} |
@@ -0,0 +1,9 @@ | |||||
package com.qmrz.service; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
public interface TableService { | |||||
List<Map> getColumnList(String dbName); | |||||
List<Map> getTableList(String dbName); | |||||
} |
@@ -0,0 +1,70 @@ | |||||
package com.qmrz.utils; | |||||
import freemarker.template.Configuration; | |||||
import freemarker.template.Template; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.lang.StringUtils; | |||||
import java.io.*; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
/** | |||||
* 生成帮助类(CodeGenerator) | |||||
*/ | |||||
@Slf4j | |||||
public class CGHelper { | |||||
private final String templatePath = "src/main/resources/template"; | |||||
private String savePath; | |||||
private String ftlName; | |||||
public CGHelper(String ftlName, String saveDir) { | |||||
this.ftlName = ftlName; | |||||
this.savePath = "src/main/resources/code/" + saveDir; | |||||
} | |||||
/** | |||||
* 写入文件 | |||||
* | |||||
* @param saveFileName | |||||
* @param viewModel | |||||
*/ | |||||
public void generator(String saveDir, String saveFileName, Map viewModel) { | |||||
Configuration configuration = new Configuration(); | |||||
configuration.setClassicCompatible(true); | |||||
Writer out = null; | |||||
try { | |||||
configuration.setDirectoryForTemplateLoading(new File(templatePath)); | |||||
Template template = configuration.getTemplate(ftlName); | |||||
String save; | |||||
if (StringUtils.isEmpty(saveDir)) { | |||||
save = savePath; | |||||
} else { | |||||
save = savePath + "\\" + saveDir; | |||||
} | |||||
File fileDir = new File(save); | |||||
if (!fileDir.exists() && !fileDir.isDirectory()) { | |||||
fileDir.mkdirs(); | |||||
} | |||||
File docFile = new File(save + "\\" + saveFileName); | |||||
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile))); | |||||
template.process(viewModel, out); | |||||
log.info("成功生成:" + saveFileName); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} finally { | |||||
try { | |||||
if (null != out) { | |||||
out.flush(); | |||||
} | |||||
} catch (Exception e2) { | |||||
e2.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,25 @@ | |||||
server: | |||||
port: 109086 | |||||
sys: | |||||
name: 代码生成 | |||||
spring: | |||||
application: | |||||
name: code-generator | |||||
db: | |||||
driver: com.mysql.cj.jdbc.Driver | |||||
# url: jdbc:mysql://qmrz.cpowvfndzbei.rds.cn-northwest-1.amazonaws.com.cn:3306/qmrz?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC | |||||
url: jdbc:mysql://qmrz-ga.cpowvfndzbei.rds.cn-northwest-1.amazonaws.com.cn:3306/qmrzga-dev?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC | |||||
username: qmrz | |||||
password: Qmrz2018 | |||||
logging: | |||||
level: | |||||
com.ab.domain.mapper: debug | |||||
@@ -0,0 +1,36 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
<mapper namespace="com.qmrz.domain.mapper.TableMapper"> | |||||
<select id="getColumnList" parameterType="Map" resultType="Map"> | |||||
select | |||||
TABLE_NAME as table_name | |||||
,COLUMN_NAME as column_name | |||||
,COLUMN_COMMENT as column_comment | |||||
,DATA_TYPE as data_type | |||||
,COLUMN_TYPE as column_type | |||||
,IS_NULLABLE as is_nullable | |||||
,COLUMN_DEFAULT as column_default | |||||
,COLUMN_KEY as column_key | |||||
,CHARACTER_SET_NAME as character_set_name | |||||
,COLLATION_NAME as collation_name | |||||
from INFORMATION_SCHEMA.Columns | |||||
where table_schema=#{dbname} | |||||
order by ORDINAL_POSITION asc | |||||
</select> | |||||
<select id="getTableList" parameterType="Map" resultType="Map"> | |||||
select | |||||
TABLE_NAME as table_name | |||||
,TABLE_COMMENT as table_comment | |||||
,TABLE_COLLATION as table_collation | |||||
,ENGINE as engine | |||||
from information_schema.tables | |||||
where table_schema=#{dbname} and table_type='BASE TABLE'; | |||||
</select> | |||||
</mapper> |
@@ -0,0 +1,114 @@ | |||||
package com.qmrz.syncapi; | |||||
import com.alibaba.fastjson.JSONArray; | |||||
import com.qmrz.exception.ABException; | |||||
import com.qmrz.utils.*; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import java.time.LocalDateTime; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* 同步 ${table_name},${table_comment} | |||||
*/ | |||||
@Slf4j | |||||
public class ${table_name2}Sync extends BaseSync { | |||||
private String syncStartDate; | |||||
private String syncEndDate; | |||||
public ${table_name2}Sync(String syncStartDate, String syncEndDate) { | |||||
this.syncStartDate = syncStartDate; | |||||
//结束日期需要加一天,api同步时不包含结束日期 | |||||
this.syncEndDate = DateTimeUtil.datePlus(syncEndDate, 1); | |||||
} | |||||
@Override | |||||
protected Map<String, String> getSyncFieldMapping() { | |||||
//注意:不包含createtime,若是子表,则外键ID也不包含 | |||||
Map<String, String> fieldMapping = new HashMap<>(); | |||||
<#list columnList as item> | |||||
<#if item.column_name != "createtime"> | |||||
fieldMapping.put("${item.column_name}", "${item.column_name_show_name}"); | |||||
</#if> | |||||
</#list> | |||||
return fieldMapping; | |||||
} | |||||
public JSONArray getOtherList() { | |||||
throw new ABException("方法未实现"); | |||||
//return this.getSubList("子记录", (rowParent, rowSub) -> { | |||||
// rowSub.put("外键id", rowParent.get("id")); | |||||
//}); | |||||
} | |||||
@Override | |||||
protected String insertMapID() { | |||||
return "${table_name2}Mapper.sync_batch_insert"; | |||||
} | |||||
@Override | |||||
protected String updateMapID() { | |||||
return "${table_name2}Mapper.sync_batch_update"; | |||||
} | |||||
@Override | |||||
protected String deleteMapID() { | |||||
return "${table_name2}Mapper.sync_batch_delete"; | |||||
} | |||||
@Override | |||||
protected String getTableName() { | |||||
return "${table_name}"; | |||||
} | |||||
@Override | |||||
protected String getPrimaryFieldName() { | |||||
return "id"; | |||||
} | |||||
@Override | |||||
protected String getSyncUrl() { | |||||
throw new ABException("方法未实现"); | |||||
} | |||||
@Override | |||||
protected boolean ispage() { | |||||
return true; | |||||
} | |||||
@Override | |||||
protected void insertAddField(Map insertMap) { | |||||
insertMap.put("createtime", DateTimeUtil.format(LocalDateTime.now())); | |||||
} | |||||
/** | |||||
* 查询DB数据,用与api数据比对是否增、删、改 | |||||
* @return | |||||
*/ | |||||
@Override | |||||
protected List selectDB() { | |||||
return SpringContextUtil.getBean(DBHelper.class).selectList("${table_name2}Mapper.sync_batch_select"); | |||||
} | |||||
/** | |||||
* 若需要api数据时(如主表),返回为false,否则true | |||||
* @return | |||||
*/ | |||||
@Override | |||||
protected boolean isOrigin() { | |||||
return false; | |||||
} | |||||
/** | |||||
* 若不需要api数据时,请先填充 this.originApi | |||||
* @return | |||||
*/ | |||||
@Override | |||||
protected JSONArray originApiData() { | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,66 @@ | |||||
package com.qmrz.controller.a1; | |||||
import com.qmrz.controller.base.BaseController; | |||||
import com.qmrz.service.${table_name2}Service; | |||||
import com.qmrz.utils.ExportPOIUtils; | |||||
import com.qmrz.utils.RD; | |||||
import com.qmrz.utils.Web; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.web.bind.annotation.RequestBody; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import java.io.IOException; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* ${table_name},${table_comment} | |||||
* Automatic generation | |||||
*/ | |||||
@Slf4j | |||||
@RequestMapping("/a1/${table_name}") | |||||
@RestController | |||||
public class ${table_name2}Controller extends BaseController { | |||||
${table_name2}Service ${table_name}Service; | |||||
public ${table_name2}Controller(${table_name2}Service ${table_name}Service){ | |||||
super(${table_name}Service); | |||||
this.${table_name}Service = ${table_name}Service; | |||||
} | |||||
@RequestMapping("insert") | |||||
@Override | |||||
public RD insert(@RequestBody Map insertData) { | |||||
return RD.failure("未开启 insert 操作"); | |||||
} | |||||
@RequestMapping("update") | |||||
@Override | |||||
public RD update(@RequestBody Map<String,Object> data) { | |||||
return RD.failure("未开启 update 操作"); | |||||
} | |||||
@RequestMapping("delete") | |||||
@Override | |||||
public RD delete(@RequestBody Map where) { | |||||
return RD.failure("未开启 delete 操作"); | |||||
} | |||||
/** | |||||
* 导出excel | |||||
* @param map | |||||
*/ | |||||
@RequestMapping("export") | |||||
public void export(@RequestBody Map<String, String> map) { | |||||
//db字段名 | |||||
String dbColumn[] = {<#list columnList as item>"${item.column_name}"<#if item_has_next>,</#if></#list>}; | |||||
//excel列名 | |||||
String excelColumn[] = {<#list columnList as item>"${item.column_name_show_name}"<#if item_has_next>,</#if></#list>}; | |||||
List<Map> resultList = this.${table_name}Service.selectList(map); | |||||
try { | |||||
ExportPOIUtils.start_download(Web.getResponse(), "${table_name}", resultList, excelColumn, dbColumn); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
## ${dbname}.${table_name} | |||||
### `${table_comment}` | |||||
> 表信息 | |||||
| 属性 | 内容 | | |||||
| --- | --- | | |||||
| table_collation | ${table_collation} | | |||||
| engine | ${engine} | | |||||
> 表结构 | |||||
| 说明 | 字段名 | 字段类型 | 主键 | 允许为空 | 默认值 | 字符集 | 排序规则 | | |||||
| --- | --- | --- | --- | --- | --- | --- | --- | | |||||
<#list columnList as item> | |||||
| ${item.column_comment} | ${item.column_name} | ${item.column_type} | ${item.column_key} | ${item.is_nullable} | ${item.column_default} | ${item.character_set_name} | ${item.collation_name} | |||||
</#list> | |||||
@@ -0,0 +1,10 @@ | |||||
## ${dbname} 数据库 | |||||
> 表格清单 | |||||
| 表名 | 排序规则 | 引擎 | 说明 | | |||||
| --- | --- | --- | --- | | |||||
<#list tableList as item> | |||||
| [${item.table_name}](readme/db_${item.table_name}.md) | ${item.table_collation} | ${item.engine} | ${item.table_comment} | | |||||
</#list> | |||||
@@ -0,0 +1,44 @@ | |||||
**简要描述:** | |||||
- ${table_comment} | |||||
- [${table_comment}](readme/ ${filename}) | |||||
**请求URL:** | |||||
- ` /mj/${table_name}/select_page ` | |||||
**请求方式:** | |||||
- POST | |||||
**参数:** | |||||
|参数名|类型|说明| | |||||
|:---- |:---|:----- |----- | |||||
<#list columnList as item> | |||||
| ${item.column_name} | ${item.column_type} | ${item.column_comment} | | |||||
</#list> | |||||
| pageIndex | int | 页数 | | |||||
| pageSize | int | 条数 | | |||||
**返回示例** | |||||
``` | |||||
{ | |||||
"data": { | |||||
"data": [ | |||||
{ | |||||
<#list columnList as item> | |||||
"${item.column_name}":"test"(${item.column_comment}) | |||||
</#list> | |||||
} | |||||
], | |||||
"pageCount": 1, | |||||
"pageIndex": 1, | |||||
"pageSize": 10, | |||||
"rowCount": 2(总数) | |||||
}, | |||||
"msg": "success", | |||||
"status": 10200 | |||||
} | |||||
``` |
@@ -0,0 +1,117 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
<!-- | |||||
${table_name}(${table_comment}) | |||||
注意:分隔线以下 不增加业务,有新增自定义业务时加到分隔线上面 | |||||
--> | |||||
<mapper namespace="com.qmrz.domain.mapper.${table_name2}Mapper"> | |||||
<!-- ========================= 分隔线,以下为生成的通用代码 ========================= --> | |||||
<!-- 通用查询条件 --> | |||||
<sql id="common_where"> | |||||
<where> | |||||
<#list columnList as item> | |||||
<if test="${item.column_name}!=null and ${item.column_name}!=''">and a.${item.column_name} = ${"#"}{${item.column_name}}</if> | |||||
</#list> | |||||
<#list columnList as item> | |||||
<if test="like_${item.column_name}!=null and like_${item.column_name}!=''">and a.${item.column_name} like concat('%',${"#"}{like_${item.column_name}},'%')</if> | |||||
</#list> | |||||
</where> | |||||
</sql> | |||||
<!-- 通用查询记录 --> | |||||
<select id="selectList" resultType="java.util.LinkedHashMap"> | |||||
select <#list columnList as item>a.${item.column_name}<#if item_has_next>,</#if></#list> | |||||
from ${table_name} a | |||||
<include refid="common_where" /> | |||||
<if test="__limit__!=null"> | |||||
<#noparse>limit #{__limit__}</#noparse> | |||||
</if> | |||||
</select> | |||||
<!-- 通用查询记录总数 --> | |||||
<select id="selectCount" resultType="Integer"> | |||||
select count(*) from ${table_name} a | |||||
<include refid="common_where" /> | |||||
</select> | |||||
<!-- 通用插入数据 --> | |||||
<insert id="insert"> | |||||
insert into ${table_name}( | |||||
<trim suffixOverrides=","> | |||||
<#list columnList as item> | |||||
<if test="${item.column_name}!=null">${item.column_name},</if> | |||||
</#list> | |||||
</trim>) | |||||
values( | |||||
<trim suffixOverrides=","> | |||||
<#list columnList as item> | |||||
<if test="${item.column_name}!=null">${"#"}{${item.column_name}},</if> | |||||
</#list> | |||||
</trim> | |||||
) | |||||
</insert> | |||||
<!-- 通用更新数据 --> | |||||
<update id="update"> | |||||
update ${table_name} | |||||
<set> | |||||
<#list columnList as item> | |||||
<#if item.column_key?? && item.column_key!="PRI" || item.column_name?? && item.column_name != "id"> | |||||
<if test="${item.column_name}!=null">${item.column_name} = ${"#"}{${item.column_name}},</if> | |||||
</#if> | |||||
</#list> | |||||
</set> | |||||
<where> | |||||
<#list columnList as item> | |||||
<if test="where_${item.column_name}!=null">and ${item.column_name} = ${"#"}{where_${item.column_name}}</if> | |||||
</#list> | |||||
</where> | |||||
</update> | |||||
<!-- 通用删除记录 --> | |||||
<delete id="delete"> | |||||
delete from ${table_name} a | |||||
<include refid="common_where"/> | |||||
</delete> | |||||
<!-- ============================== 以下为api同步使用 ============================== --> | |||||
<select id="sync_batch_select" resultType="Map" parameterType="Map"> | |||||
select <#list columnList as item>${item.column_name}<#if item_has_next>,</#if></#list> | |||||
from ${table_name} | |||||
</select> | |||||
<insert id="sync_batch_insert" parameterType="Map"> | |||||
insert into ${table_name}(<#list columnList as item>${item.column_name}<#if item_has_next>,</#if></#list>) | |||||
values | |||||
<foreach collection="list" item="item" index="index" separator=","> | |||||
(<#list columnList as item>${"#"}{item.${item.column_name}}<#if item_has_next>,</#if></#list>) | |||||
</foreach> | |||||
</insert> | |||||
<update id="sync_batch_update" parameterType="List"> | |||||
<foreach collection="list" item="item" index="index" separator=";"> | |||||
update ${table_name} | |||||
<set> | |||||
<#list columnList as item> | |||||
<#if item.column_key?? && item.column_key!="PRI" && item.column_name?? && item.column_name != "id" && item.column_name!="createtime"> | |||||
${item.column_name}=${"#"}{item.${item.column_name}}, | |||||
</#if> | |||||
</#list> | |||||
</set> | |||||
where id=${"#"}{item.id} | |||||
</foreach> | |||||
</update> | |||||
<delete id="sync_batch_delete" parameterType="List"> | |||||
delete from ${table_name} where id in ( | |||||
<foreach collection="list" item="item" index="index" separator=","> | |||||
${"#"}{item} | |||||
</foreach> | |||||
) | |||||
</delete> | |||||
</mapper> |
@@ -0,0 +1,140 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
<!-- | |||||
${table_name}(${table_comment}) | |||||
注意:分隔线以下 不增加业务,有新增自定义业务时加到分隔线上面 | |||||
--> | |||||
<mapper namespace="com.qmrz.domain.mapper.${table_name2}Mapper"> | |||||
<!-- ========================= 分隔线,以下为生成的通用代码 ========================= --> | |||||
<!-- 通用显示代码对应名字 --> | |||||
<sql id="common_gldworxzqh"> | |||||
,(select name from zonepubinfo zp where 1=1 and zp.pubcode = a.gldw ) as gldwname | |||||
,(select name from zoneadmin zd where 1=1 and zd.id = a.xzqh ) as xzqhname | |||||
</sql> | |||||
<!-- 通用查询条件 --> | |||||
<sql id="common_where"> | |||||
<where> | |||||
<#list columnList as item> | |||||
<#assign age='${item.column_name}'> | |||||
<#if (age=='gldw')> | |||||
<if test="gldwList!=null and gldwList!=''"> | |||||
and a.gldw in ( | |||||
<foreach item="item" index="index" collection="gldwList" separator="," > | |||||
<#noparse> #{item}</#noparse> | |||||
</foreach> | |||||
) | |||||
</if> | |||||
<#else> | |||||
<if test="${item.column_name}!=null and ${item.column_name}!=''">and a.${item.column_name} = ${"#"}{${item.column_name}}</if> | |||||
</#if> | |||||
</#list> | |||||
<#list columnList as item> | |||||
<if test="like_${item.column_name}!=null and like_${item.column_name}!=''">and a.${item.column_name} like concat('%',${"#"}{like_${item.column_name}},'%')</if> | |||||
</#list> | |||||
</where> | |||||
</sql> | |||||
<!-- 通用查询记录 --> | |||||
<select id="selectList" resultType="java.util.LinkedHashMap"> | |||||
select <#list columnList as item>a.${item.column_name}<#if item_has_next>,</#if></#list> | |||||
<#list columnList as item> | |||||
<#assign age='${item.column_name}'> | |||||
<#if (age=='gldw')> | |||||
<include refid="common_gldworxzqh" /> | |||||
</#if> | |||||
</#list> | |||||
from ${table_name} a | |||||
<include refid="common_where" /> | |||||
<if test="__limit__!=null"> | |||||
<#noparse>limit #{__limit__}</#noparse> | |||||
</if> | |||||
</select> | |||||
<!-- 通用查询记录总数 --> | |||||
<select id="selectCount" resultType="Integer"> | |||||
select count(*) from ${table_name} a | |||||
<include refid="common_where" /> | |||||
</select> | |||||
<!-- 通用插入数据 --> | |||||
<insert id="insert"> | |||||
insert into ${table_name}( | |||||
<trim suffixOverrides=","> | |||||
<#list columnList as item> | |||||
<if test="${item.column_name}!=null">${item.column_name},</if> | |||||
</#list> | |||||
</trim>) | |||||
values( | |||||
<trim suffixOverrides=","> | |||||
<#list columnList as item> | |||||
<if test="${item.column_name}!=null">${"#"}{${item.column_name}},</if> | |||||
</#list> | |||||
</trim> | |||||
) | |||||
</insert> | |||||
<!-- 通用更新数据 --> | |||||
<update id="update"> | |||||
update ${table_name} | |||||
<set> | |||||
<#list columnList as item> | |||||
<#if item.column_key?? && item.column_key!="PRI" || item.column_name?? && item.column_name != "id"> | |||||
<if test="${item.column_name}!=null">${item.column_name} = ${"#"}{${item.column_name}},</if> | |||||
</#if> | |||||
</#list> | |||||
</set> | |||||
<where> | |||||
<#list columnList as item> | |||||
<if test="where_${item.column_name}!=null">and ${item.column_name} = ${"#"}{where_${item.column_name}}</if> | |||||
</#list> | |||||
</where> | |||||
</update> | |||||
<!-- 通用删除记录 --> | |||||
<delete id="delete"> | |||||
delete from ${table_name} a | |||||
<include refid="common_where"/> | |||||
</delete> | |||||
<!-- ============================== 以下为api同步使用 ============================== --> | |||||
<select id="sync_batch_select" resultType="Map" parameterType="Map"> | |||||
select <#list columnList as item>${item.column_name}<#if item_has_next>,</#if></#list> | |||||
from ${table_name} | |||||
</select> | |||||
<insert id="sync_batch_insert" parameterType="Map"> | |||||
insert into ${table_name}(<#list columnList as item>${item.column_name}<#if item_has_next>,</#if></#list>) | |||||
values | |||||
<foreach collection="list" item="item" index="index" separator=","> | |||||
(<#list columnList as item>${"#"}{item.${item.column_name}}<#if item_has_next>,</#if></#list>) | |||||
</foreach> | |||||
</insert> | |||||
<update id="sync_batch_update" parameterType="List"> | |||||
<foreach collection="list" item="item" index="index" separator=";"> | |||||
update ${table_name} | |||||
<set> | |||||
<#list columnList as item> | |||||
<#if item.column_key?? && item.column_key!="PRI" && item.column_name?? && item.column_name != "id" && item.column_name!="createtime"> | |||||
${item.column_name}=${"#"}{item.${item.column_name}}, | |||||
</#if> | |||||
</#list> | |||||
</set> | |||||
where id=${"#"}{item.id} | |||||
</foreach> | |||||
</update> | |||||
<delete id="sync_batch_delete" parameterType="List"> | |||||
delete from ${table_name} where id in ( | |||||
<foreach collection="list" item="item" index="index" separator=","> | |||||
${"#"}{item} | |||||
</foreach> | |||||
) | |||||
</delete> | |||||
</mapper> |
@@ -0,0 +1,12 @@ | |||||
package com.qmrz.service; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* ${table_name},${table_comment} | |||||
* Automatic generation | |||||
*/ | |||||
public interface ${table_name2}Service extends BaseService { | |||||
} |
@@ -0,0 +1,22 @@ | |||||
package com.qmrz.service.impl; | |||||
import com.qmrz.service.${table_name2}Service; | |||||
import com.qmrz.utils.MapUtil; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* ${table_name},${table_comment} | |||||
* Automatic generation | |||||
*/ | |||||
@Slf4j | |||||
@Service | |||||
public class ${table_name2}ServiceImpl extends BaseServiceImpl implements ${table_name2}Service { | |||||
public ${table_name2}ServiceImpl(){ | |||||
super("${table_name}"); | |||||
} | |||||
} | |||||
@@ -0,0 +1,89 @@ | |||||
import com.qmrz.CodeGenerator; | |||||
import com.qmrz.generator.*; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.junit.Test; | |||||
import org.junit.runner.RunWith; | |||||
import org.springframework.boot.test.context.SpringBootTest; | |||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | |||||
@Slf4j | |||||
@RunWith(SpringJUnit4ClassRunner.class) | |||||
@SpringBootTest(classes = CodeGenerator.class) | |||||
public class TestCodeGenerator { | |||||
private String dbname="qmrzga-dev"; | |||||
/** | |||||
* 生成所有 | |||||
*/ | |||||
@Test | |||||
public void generatorAll() { | |||||
readme(); | |||||
mapper(); | |||||
service(); | |||||
serviceImpl(); | |||||
controller(); | |||||
interface2(); | |||||
} | |||||
/** | |||||
* readme 生成 | |||||
*/ | |||||
@Test | |||||
public void readme() { | |||||
DBReadmeGenerator generator = new DBReadmeGenerator(dbname); | |||||
generator.generator(); | |||||
} | |||||
/** | |||||
* readme 生成 | |||||
*/ | |||||
@Test | |||||
public void interface2() { | |||||
InterfaceReadmeGenerator generator = new InterfaceReadmeGenerator(dbname); | |||||
generator.generator(); | |||||
} | |||||
/** | |||||
* mapper 生成 | |||||
*/ | |||||
@Test | |||||
public void mapper() { | |||||
MapperGenerator generator = new MapperGenerator(dbname); | |||||
generator.generator(); | |||||
} | |||||
/** | |||||
* service 生成 | |||||
*/ | |||||
@Test | |||||
public void service() { | |||||
ServiceGenerator generator = new ServiceGenerator(dbname); | |||||
generator.generator(); | |||||
} | |||||
/** | |||||
* serviceImpl 生成 | |||||
*/ | |||||
@Test | |||||
public void serviceImpl() { | |||||
ServiceImplGenerator generator = new ServiceImplGenerator(dbname); | |||||
generator.generator(); | |||||
} | |||||
/** | |||||
* controller 生成 | |||||
*/ | |||||
@Test | |||||
public void controller() { | |||||
ControllerGenerator generator = new ControllerGenerator(dbname); | |||||
generator.generator(); | |||||
} | |||||
/** | |||||
* api_sync 同步 | |||||
*/ | |||||
@Test | |||||
public void api_sync() { | |||||
ApiSyncGenerator generator = new ApiSyncGenerator(dbname); | |||||
generator.generator(); | |||||
} | |||||
} |
@@ -0,0 +1,26 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<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"> | |||||
<parent> | |||||
<artifactId>codeGenerate</artifactId> | |||||
<groupId>com.qmrz</groupId> | |||||
<version>1.0</version> | |||||
</parent> | |||||
<modelVersion>4.0.0</modelVersion> | |||||
<artifactId>common</artifactId> | |||||
<packaging>jar</packaging> | |||||
<dependencies> | |||||
<dependency> | |||||
<groupId>org.apache.poi</groupId> | |||||
<artifactId>poi</artifactId> | |||||
<version>3.9</version> | |||||
</dependency> | |||||
</dependencies> | |||||
</project> |
@@ -0,0 +1,11 @@ | |||||
package com.qmrz; | |||||
import com.qmrz.config.SysInfo; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
@Slf4j | |||||
public class BaseAdminController { | |||||
@Autowired | |||||
protected SysInfo sysInfo; | |||||
} |
@@ -0,0 +1,99 @@ | |||||
package com.qmrz.admin; | |||||
import com.qmrz.constants.ConstantValue; | |||||
import com.qmrz.dto.SecurityAdminDTO; | |||||
import com.qmrz.exception.ABException; | |||||
import com.qmrz.utils.Session; | |||||
import org.apache.shiro.SecurityUtils; | |||||
import org.apache.shiro.subject.Subject; | |||||
/** | |||||
* 管理员登录信息获取 | |||||
*/ | |||||
public class AdminLogin { | |||||
public static final AdminLogin instance = new AdminLogin(); | |||||
/** | |||||
* 获取管理员登录信息 | |||||
* | |||||
* @return | |||||
*/ | |||||
// public AdminLoginInfo getAdminInfo() { | |||||
// AdminLoginInfo info = Session.getSession("admininfo"); | |||||
// return info; | |||||
// } | |||||
public SecurityAdminDTO getAdminInfo() { | |||||
Subject currentUser = SecurityUtils.getSubject(); | |||||
SecurityAdminDTO info = (SecurityAdminDTO) currentUser.getPrincipal(); | |||||
return info; | |||||
} | |||||
public Boolean isSuper() { | |||||
return ConstantValue.ONE.equals(getAdminInfo().getIssuper()); | |||||
} | |||||
/** | |||||
* 获取管理员名称 | |||||
* | |||||
* @return | |||||
*/ | |||||
// public String getAdminName() { | |||||
// AdminLoginInfo info = getAdminInfo(); | |||||
// if (info == null) { | |||||
// return "未登录"; | |||||
// } | |||||
// return info.getAdminname(); | |||||
// } | |||||
public String getAdminName() { | |||||
Subject currentUser = SecurityUtils.getSubject(); | |||||
if (!currentUser.isAuthenticated()) { | |||||
return "未登录"; | |||||
} | |||||
return ((SecurityAdminDTO) currentUser.getPrincipal()).getUsername(); | |||||
} | |||||
/** | |||||
* 验证用户是否登录 | |||||
* | |||||
* @return | |||||
*/ | |||||
// public boolean isLogin() { | |||||
// AdminLoginInfo info = getAdminInfo(); | |||||
// if (info == null) { | |||||
// return false; | |||||
// } | |||||
// return info.getAdminid() > 0; | |||||
// } | |||||
public boolean isLogin() { | |||||
Subject currentUser = SecurityUtils.getSubject(); | |||||
return currentUser.isAuthenticated(); | |||||
} | |||||
public static final String CustomerInfo_SessionName = "admin_customer_info"; | |||||
public static CustomerInfo getCustomerInfo() { | |||||
CustomerInfo info = Session.getSession(CustomerInfo_SessionName); | |||||
if (info == null) { | |||||
throw new ABException("客户标识不存在"); | |||||
} | |||||
if (info.getCustomerID() == null || info.getCustomerDir() == null) { | |||||
throw new ABException("客户id 或 dir为空"); | |||||
} | |||||
return info; | |||||
} | |||||
public static Integer getCustomerID() { | |||||
return getCustomerInfo().getCustomerID(); | |||||
} | |||||
public static void setCustomInfo(CustomerInfo customInfo){ | |||||
if (customInfo.getCustomerID() == null || customInfo.getCustomerDir() == null) { | |||||
throw new ABException("客户id 或 dir为空"); | |||||
} | |||||
Session.setSession(CustomerInfo_SessionName,customInfo); | |||||
} | |||||
} |
@@ -0,0 +1,12 @@ | |||||
package com.qmrz.admin; | |||||
import lombok.Data; | |||||
/** | |||||
* 管理员登录信息 | |||||
*/ | |||||
@Data | |||||
public class AdminLoginInfo { | |||||
private int adminid; | |||||
private String adminname; | |||||
} |
@@ -0,0 +1,14 @@ | |||||
package com.qmrz.admin; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
@Data | |||||
@AllArgsConstructor | |||||
public class CustomerInfo implements Serializable { | |||||
private static final long serialVersionUID = -1959344102914768364L; | |||||
private Integer customerID; | |||||
private String customerDir; | |||||
} |
@@ -0,0 +1,75 @@ | |||||
package com.qmrz.config; | |||||
import com.github.pagehelper.PageInterceptor; | |||||
import com.qmrz.mybatis.MapperScannerConfigurer; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.ibatis.session.SqlSessionFactory; | |||||
import org.mybatis.spring.SqlSessionFactoryBean; | |||||
import org.mybatis.spring.SqlSessionTemplate; | |||||
import org.springframework.context.annotation.Bean; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import javax.sql.DataSource; | |||||
/** | |||||
* 初始配置 | |||||
*/ | |||||
@Slf4j | |||||
@Configuration | |||||
public class Config { | |||||
public Config() { | |||||
log.info("------------ Config"); | |||||
} | |||||
/** | |||||
* 配置数据源 | |||||
* | |||||
* @param dbInfo 数据库配置信息 | |||||
* @return | |||||
*/ | |||||
@Bean | |||||
public DataSource dataSource(ConfigDBInfo dbInfo) { | |||||
log.info("------------ dataSource"); | |||||
log.info(dbInfo.toString()); | |||||
return ConfigDBUtils.getDruid(dbInfo); | |||||
} | |||||
/** | |||||
* 利用SqlSessionFactoryBean,绑定mapper(xml)位置 | |||||
* | |||||
* @param dataSource 数据源 | |||||
* @return | |||||
*/ | |||||
@Bean("SqlSessionFactory") | |||||
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource,PageInterceptor pageHelper) throws Exception { | |||||
log.info("------------ SqlSessionFactoryBean"); | |||||
SqlSessionFactoryBean sqlSessionFactoryBean = | |||||
ConfigDBUtils.getSqlSessionFactoryBean(dataSource, "classpath*:mapper/*.xml",pageHelper); | |||||
return sqlSessionFactoryBean; | |||||
} | |||||
@Bean("sqlSessionTemplate") | |||||
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { | |||||
log.info("------------ sqlSessionTemplate"); | |||||
SqlSessionTemplate s = new SqlSessionTemplate(sqlSessionFactory); | |||||
return s; | |||||
} | |||||
/** | |||||
* mapper配置扫描并绑定 | |||||
* | |||||
* @return | |||||
*/ | |||||
@Bean | |||||
public MapperScannerConfigurer mapperScannerConfigurer() { | |||||
log.info("------------ MapperScannerConfigurer"); | |||||
//SqlSessionFactory名称即是SqlSessionFactoryBean的指定bean名 | |||||
return ConfigDBUtils.getMapperScannerConfigurer("SqlSessionFactory", "com.qmrz.domain.mapper"); | |||||
} | |||||
@Bean | |||||
public PageInterceptor pageHelper() { | |||||
return ConfigDBUtils.pageHelper(); | |||||
} | |||||
} |
@@ -0,0 +1,24 @@ | |||||
package com.qmrz.config; | |||||
import lombok.Data; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
import org.springframework.stereotype.Component; | |||||
/** | |||||
* 数据库配置信息 | |||||
*/ | |||||
@Slf4j | |||||
@Component | |||||
@Data | |||||
@ConfigurationProperties(prefix = "db") | |||||
public class ConfigDBInfo { | |||||
private String driver; | |||||
private String url; | |||||
private String username; | |||||
private String password; | |||||
public ConfigDBInfo() { | |||||
log.info("------ ConfigDBInfo"); | |||||
} | |||||
} |
@@ -0,0 +1,149 @@ | |||||
package com.qmrz.config; | |||||
import com.alibaba.druid.filter.Filter; | |||||
import com.alibaba.druid.pool.DruidDataSource; | |||||
import com.alibaba.druid.wall.WallConfig; | |||||
import com.alibaba.druid.wall.WallFilter; | |||||
import com.github.pagehelper.PageInterceptor; | |||||
import com.qmrz.mybatis.MapperScannerConfigurer; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.ibatis.plugin.Interceptor; | |||||
import org.apache.ibatis.session.Configuration; | |||||
import org.mybatis.spring.SqlSessionFactoryBean; | |||||
import org.springframework.context.ApplicationContext; | |||||
import org.springframework.context.support.FileSystemXmlApplicationContext; | |||||
import javax.sql.DataSource; | |||||
import java.io.IOException; | |||||
import java.sql.SQLException; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import java.util.Properties; | |||||
/** | |||||
* 数据库配置工具 | |||||
*/ | |||||
@Slf4j | |||||
public class ConfigDBUtils { | |||||
/** | |||||
* 生成数据源 | |||||
* | |||||
* @param info | |||||
* @return | |||||
*/ | |||||
public static DataSource getDruid(ConfigDBInfo info) { | |||||
log.info("Create DruidDataSource:" + info.getUrl()); | |||||
DruidDataSource dds = new DruidDataSource(); | |||||
dds.setUrl(info.getUrl()); | |||||
dds.setUsername(info.getUsername()); | |||||
dds.setPassword(info.getPassword()); | |||||
dds.setDriverClassName(info.getDriver()); | |||||
dds.setInitialSize(0);//初始化连接大小 | |||||
dds.setMaxActive(3000);//连接池最大使用连接数量 | |||||
dds.setMinIdle(0);//连接池最小空闲 | |||||
dds.setMaxWait(60000);//获取连接最大等待时间 | |||||
dds.setValidationQuery("select 1");//验证数据库连接有效性,要求查询语句 | |||||
WallConfig wallConfig = new WallConfig(); | |||||
wallConfig.setMultiStatementAllow(true); | |||||
WallFilter wallFilter = new WallFilter(); | |||||
wallFilter.setConfig(wallConfig); | |||||
List<Filter> filters = new ArrayList<>(); | |||||
filters.add(wallFilter); | |||||
dds.setProxyFilters(filters); | |||||
//建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 | |||||
dds.setTestWhileIdle(true); | |||||
//申请连接时执行validationQuery检测连接是否有效,配置true会降低性能。 | |||||
dds.setTestOnBorrow(false); | |||||
//归还连接时执行validationQuery检测连接是否有效,配置true会降低性能 | |||||
dds.setTestOnReturn(false); | |||||
//配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | |||||
dds.setTimeBetweenEvictionRunsMillis(60000); | |||||
//配置一个连接在池中最小生存的时间,单位是毫秒 | |||||
dds.setMinEvictableIdleTimeMillis(25200000); | |||||
//对于长时间不使用的连接强制关闭 | |||||
dds.setRemoveAbandoned(true); | |||||
//关闭超过30分钟的空闲连接,1800秒,也就是30分钟 | |||||
dds.setRemoveAbandonedTimeout(1800); | |||||
//关闭abanded连接时输出错误日志 | |||||
dds.setLogAbandoned(true); | |||||
//设置批量更新 | |||||
//监控数据库 | |||||
//dds.setFilters("mergeStat"); | |||||
try { | |||||
dds.setFilters("stat,wall"); | |||||
} catch (SQLException e) { | |||||
log.info("error:" + e.getMessage()); | |||||
// TODO Auto-generated catch block | |||||
e.printStackTrace(); | |||||
} | |||||
return dds; | |||||
} | |||||
/** | |||||
* 使用SqlSessionFactoryBean,扫描或绑定mapper(xml)位置 | |||||
* | |||||
* @param dataSource 数据源 | |||||
* @param mapperPath mapper(xml)位置 | |||||
*/ | |||||
public static SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource, String mapperPath, PageInterceptor pageHelper) { | |||||
SqlSessionFactoryBean s = new SqlSessionFactoryBean(); | |||||
s.setDataSource(dataSource); | |||||
s.setPlugins(new Interceptor[]{pageHelper}); | |||||
ApplicationContext ctx = new FileSystemXmlApplicationContext(); | |||||
try { | |||||
Configuration c = new Configuration(); | |||||
c.setCallSettersOnNulls(true); | |||||
s.setConfiguration(c); | |||||
s.setMapperLocations(ctx.getResources(mapperPath)); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return s; | |||||
} | |||||
public static PageInterceptor pageHelper() { | |||||
PageInterceptor pageHelper = new PageInterceptor(); | |||||
Properties p = new Properties(); | |||||
p.setProperty("offsetAsPageNum", "true"); | |||||
p.setProperty("rowBoundsWithCount", "true"); | |||||
p.setProperty("reasonable", "true"); | |||||
// p.setProperty("dialect", "mysql"); | |||||
pageHelper.setProperties(p); | |||||
return pageHelper; | |||||
} | |||||
/** | |||||
* 使用MapperScannerConfigurer,扫描或绑定 mapper接口位置,并与xml文件映射生产相应实例 | |||||
* | |||||
* @param sqlSessionFactoryBean | |||||
* @param packageName | |||||
*/ | |||||
public static MapperScannerConfigurer getMapperScannerConfigurer(String sqlSessionFactoryBean, String packageName) { | |||||
MapperScannerConfigurer m = new MapperScannerConfigurer(); | |||||
//包名:指定mapper接口所在包位置 | |||||
m.setBasePackage(packageName); | |||||
//SqlSessionFactoryBea的名称,用与mapper的接口和xml的映射 | |||||
m.setSqlSessionFactoryBeanName(sqlSessionFactoryBean); | |||||
return m; | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package com.qmrz.config; | |||||
import lombok.Data; | |||||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
import org.springframework.stereotype.Component; | |||||
/** | |||||
* 数据库配置信息 | |||||
*/ | |||||
@Component | |||||
@Data | |||||
@ConfigurationProperties(prefix = "uploadfile") | |||||
public class ConfigUploadFileInfo { | |||||
private Long size;//byte | |||||
private String path; | |||||
private int picMaxWidth;//px | |||||
private int picMaxHeight;//px | |||||
} |
@@ -0,0 +1,15 @@ | |||||
package com.qmrz.config; | |||||
//@Configuration | |||||
//@EnableWebSecurity | |||||
public class SecurityConfig { | |||||
// @Override | |||||
// protected void configure(HttpSecurity http) throws Exception { | |||||
// http.csrf().disable(); | |||||
// http.authorizeRequests().antMatchers("/").permitAll() | |||||
// .and() | |||||
// .headers().frameOptions().disable(); | |||||
// | |||||
// | |||||
// } | |||||
} |
@@ -0,0 +1,79 @@ | |||||
package com.qmrz.config; | |||||
import lombok.Data; | |||||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
import org.springframework.stereotype.Component; | |||||
@Component | |||||
@Data | |||||
@ConfigurationProperties(prefix = "sys") | |||||
public class SysInfo { | |||||
/** 站点名称 */ | |||||
private String name; | |||||
/** | |||||
* token密钥 | |||||
*/ | |||||
private String policeSecret; | |||||
/** | |||||
* 过期毫秒数 | |||||
*/ | |||||
private Long policeExpire; | |||||
/** | |||||
* wxapp表id为wxappid的做为系统公众号 | |||||
*/ | |||||
private Integer wxappid; | |||||
/** | |||||
* 微信公众号域名 | |||||
*/ | |||||
private String wxdomain; | |||||
/** | |||||
* 阿里短信应用id | |||||
*/ | |||||
private Integer alismsid; | |||||
/** | |||||
* 微信支付回调地址 | |||||
*/ | |||||
private String paynotifyurl; | |||||
/** | |||||
* 订单生成的机器 IP | |||||
*/ | |||||
private String payip; | |||||
/** | |||||
* shiro session超时时间1天 | |||||
*/ | |||||
private Integer globalSessionTimeout; | |||||
/** | |||||
* shiro 缓存前缀 | |||||
*/ | |||||
private String shiroCachePrefix; | |||||
/** | |||||
* 是否开启api 数据同步 | |||||
*/ | |||||
private Boolean openSyncApi; | |||||
/** | |||||
* 是否开启 自动分派 | |||||
*/ | |||||
private Boolean openBatchAssign; | |||||
/** | |||||
* 数据库名 | |||||
*/ | |||||
private String dbname; | |||||
/** | |||||
* 数据同步地址 | |||||
*/ | |||||
private String syncapiurl; | |||||
} |
@@ -0,0 +1,6 @@ | |||||
package com.qmrz.constants; | |||||
public class ABMessage { | |||||
public static final String test = "注意,是测试数据,接口对接中"; | |||||
public static final String test2 = "注意,是测试数据,暂时都返回固定站点信息"; | |||||
} |
@@ -0,0 +1,7 @@ | |||||
package com.qmrz.constants; | |||||
public class ConstantValue { | |||||
public static final Integer ZERO = 0; | |||||
public static final Integer ONE = 1; | |||||
public static final Integer TWO = 2; | |||||
} |
@@ -0,0 +1,33 @@ | |||||
package com.qmrz.dto; | |||||
import com.qmrz.utils.Fn; | |||||
import java.util.HashMap; | |||||
/** | |||||
* 通用参数接收模型(可扩展) | |||||
*/ | |||||
public class PageMapDTO extends HashMap<String, Object> { | |||||
/** | |||||
* 页码 默认第1页 | |||||
* @return | |||||
*/ | |||||
public int getPageIndex() { | |||||
int pageIdnex = Fn.toInt(this.get("pageIndex")); | |||||
if (pageIdnex <= 0) { | |||||
pageIdnex = 1; | |||||
} | |||||
return pageIdnex; | |||||
} | |||||
/** | |||||
* 每页记录数 默认每页20条 | |||||
* @return | |||||
*/ | |||||
public int getPageSize(){ | |||||
int pageSize = Fn.toInt(this.get("pageSize")); | |||||
if (pageSize <= 0) { | |||||
pageSize = 20; | |||||
} | |||||
return pageSize; | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
package com.qmrz.dto; | |||||
import lombok.Data; | |||||
@Data | |||||
public class ParamCodeDTO { | |||||
private String code; | |||||
public ParamCodeDTO() { | |||||
} | |||||
public ParamCodeDTO(String code) { | |||||
this.code = code; | |||||
} | |||||
public static ParamCodeDTO newdto(String code){ | |||||
return new ParamCodeDTO(code); | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
package com.qmrz.dto; | |||||
import com.qmrz.admin.AdminLogin; | |||||
import com.qmrz.exception.ABException; | |||||
import lombok.Data; | |||||
@Data | |||||
public class ParamCustomer { | |||||
private Integer customerid = AdminLogin.getCustomerInfo().getCustomerID(); | |||||
public ParamCustomer setCustomerid(Integer customerid){ | |||||
throw new ABException("customerid不允许set,请使用_set"); | |||||
} | |||||
public ParamCustomer _setCustomerid(Integer customerid){ | |||||
this.customerid = customerid; | |||||
return this; | |||||
} | |||||
} |
@@ -0,0 +1,45 @@ | |||||
package com.qmrz.dto; | |||||
import com.qmrz.admin.AdminLogin; | |||||
import lombok.Data; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
@Data | |||||
@Slf4j | |||||
public class ParamIDDTO { | |||||
private Integer id; | |||||
private Integer customerid; | |||||
public ParamIDDTO setCustomerid(Integer customerid) { | |||||
log.warn("customerid不允许set,请使用_set"); | |||||
return this; | |||||
} | |||||
public ParamIDDTO _setCustomerid(Integer customerid) { | |||||
this.customerid = customerid; | |||||
return this; | |||||
} | |||||
public ParamIDDTO() { | |||||
this.customerid = AdminLogin.getCustomerInfo().getCustomerID(); | |||||
} | |||||
public ParamIDDTO(Integer id) { | |||||
this.id = id; | |||||
this.customerid = AdminLogin.getCustomerInfo().getCustomerID(); | |||||
} | |||||
public ParamIDDTO(Integer id, Integer customerid) { | |||||
this.id = id; | |||||
this.customerid = customerid; | |||||
} | |||||
public static ParamIDDTO newdto(Integer id) { | |||||
return new ParamIDDTO(id); | |||||
} | |||||
// @Override | |||||
// public String toString() { | |||||
// return id.toString(); | |||||
// } | |||||
} |
@@ -0,0 +1,29 @@ | |||||
package com.qmrz.dto; | |||||
import lombok.Data; | |||||
@Data | |||||
public class ParamIDPageDTO extends ParamPageDTO { | |||||
private Integer id; | |||||
public ParamIDPageDTO() { | |||||
} | |||||
public ParamIDPageDTO(Integer id) { | |||||
this.id = id; | |||||
} | |||||
public ParamIDPageDTO(Integer id, ParamPageDTO pageDTO) { | |||||
this.id = id; | |||||
this.setPageIndex(pageDTO.getPageIndex()); | |||||
this.setPageSize(pageDTO.getPageSize()); | |||||
} | |||||
public static ParamIDPageDTO newdto(Integer id) { | |||||
return new ParamIDPageDTO(id); | |||||
} | |||||
public static ParamIDPageDTO newdto(Integer id, ParamPageDTO pageDTO) { | |||||
return new ParamIDPageDTO(id, pageDTO); | |||||
} | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.qmrz.dto; | |||||
import lombok.Data; | |||||
@Data | |||||
public class ParamLongIDDTO { | |||||
private Long id; | |||||
public ParamLongIDDTO() { | |||||
} | |||||
public ParamLongIDDTO(Long id) { | |||||
this.id = id; | |||||
} | |||||
public static ParamLongIDDTO newdto(Long id){ | |||||
return new ParamLongIDDTO(id); | |||||
} | |||||
} |
@@ -0,0 +1,24 @@ | |||||
package com.qmrz.dto; | |||||
import lombok.Data; | |||||
import java.math.BigDecimal; | |||||
/** | |||||
* 金额 | |||||
*/ | |||||
@Data | |||||
public class ParamMoneyDTO { | |||||
private BigDecimal money; | |||||
public ParamMoneyDTO() { | |||||
} | |||||
public ParamMoneyDTO(BigDecimal money) { | |||||
this.money = money; | |||||
} | |||||
public static ParamMoneyDTO newdto(BigDecimal money){ | |||||
return new ParamMoneyDTO(money); | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
package com.qmrz.dto; | |||||
import com.qmrz.admin.AdminLogin; | |||||
import lombok.Data; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
@Data | |||||
@Slf4j | |||||
public class ParamNameDTO { | |||||
private String name; | |||||
private Integer customerid; | |||||
public ParamNameDTO setCustomerid(Integer customerid){ | |||||
log.warn("customerid不允许set,请使用_set"); | |||||
return this; | |||||
} | |||||
public ParamNameDTO _setCustomerid(Integer customerid){ | |||||
this.customerid = customerid; | |||||
return this; | |||||
} | |||||
public ParamNameDTO() { | |||||
this.customerid = AdminLogin.getCustomerInfo().getCustomerID(); | |||||
} | |||||
public ParamNameDTO(String name) { | |||||
this.name = name; | |||||
this.customerid = AdminLogin.getCustomerInfo().getCustomerID(); | |||||
} | |||||
public ParamNameDTO(String name,Integer customerid) { | |||||
this.name = name; | |||||
this.customerid = customerid; | |||||
} | |||||
public static ParamNameDTO newdto(String name) { | |||||
return new ParamNameDTO(name); | |||||
} | |||||
} |
@@ -0,0 +1,61 @@ | |||||
package com.qmrz.dto; | |||||
import com.github.pagehelper.PageHelper; | |||||
import com.qmrz.admin.AdminLogin; | |||||
import lombok.Data; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
/** | |||||
* 接收参数基础对象:含分页等属性 | |||||
*/ | |||||
@Data | |||||
@Slf4j | |||||
public class ParamPageDTO { | |||||
/** | |||||
* 默认第1页 | |||||
*/ | |||||
private int pageIndex = 1; | |||||
/** | |||||
* 默认20条每页 | |||||
*/ | |||||
private int pageSize = 20; | |||||
// private Integer customerid; | |||||
public ParamPageDTO() { | |||||
// this.customerid = AdminLogin.getCustomerInfo().getCustomerID(); | |||||
} | |||||
public ParamPageDTO(Integer customerid) { | |||||
// this.customerid = customerid; | |||||
} | |||||
public ParamPageDTO(Integer customerid, Integer pageIndex, Integer pageSize) { | |||||
// this.customerid = customerid; | |||||
if (pageIndex <= 0) { | |||||
pageIndex = 1; | |||||
} | |||||
this.pageIndex = pageIndex; | |||||
if (pageSize <= 0) { | |||||
pageSize = 20; | |||||
} | |||||
this.pageSize = pageSize; | |||||
} | |||||
public ParamPageDTO setCustomerid(Integer customerid) { | |||||
log.warn("customerid不允许set,请使用_set"); | |||||
return this; | |||||
} | |||||
public ParamPageDTO _setCustomerid(Integer customerid) { | |||||
// this.customerid = customerid; | |||||
return this; | |||||
} | |||||
/** | |||||
* 使用分页mapper时,请调用此方法 | |||||
*/ | |||||
public void startPage() { | |||||
PageHelper.startPage(pageIndex, pageSize); | |||||
} | |||||
} |
@@ -0,0 +1,19 @@ | |||||
package com.qmrz.dto; | |||||
import lombok.Data; | |||||
@Data | |||||
public class ParamTypeDTO { | |||||
private Integer type; | |||||
public ParamTypeDTO() { | |||||
} | |||||
public ParamTypeDTO(Integer type) { | |||||
this.type = type; | |||||
} | |||||
public static ParamTypeDTO newdto(Integer type){ | |||||
return new ParamTypeDTO(type); | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
package com.qmrz.dto; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
@Data | |||||
public class SecurityAdminDTO implements Serializable { | |||||
private static final long serialVersionUID = 1922126787657987938L; | |||||
private Integer id; | |||||
private String username; | |||||
private String password; | |||||
/** | |||||
* 角色列表 | |||||
*/ | |||||
private HashMap<String,List<String>> roles; | |||||
/** | |||||
* 权限列表 | |||||
*/ | |||||
private List<String> funs; | |||||
/** | |||||
* 是否超级管理员 | |||||
*/ | |||||
private Integer issuper; | |||||
private Integer islock; | |||||
private Long addtime; | |||||
private Long updatetime; | |||||
} |
@@ -0,0 +1,25 @@ | |||||
package com.qmrz.dto; | |||||
import lombok.Data; | |||||
@Data | |||||
public class TParamIDDTO<T> { | |||||
private Integer id; | |||||
private T model; | |||||
public TParamIDDTO() { | |||||
} | |||||
public TParamIDDTO(Integer id) { | |||||
this.id = id; | |||||
} | |||||
public static TParamIDDTO newdto(Integer id){ | |||||
return new TParamIDDTO(id); | |||||
} | |||||
// @Override | |||||
// public String toString() { | |||||
// return id.toString(); | |||||
// } | |||||
} |
@@ -0,0 +1,53 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RDCode; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
@Slf4j | |||||
public class ABException extends RuntimeException { | |||||
private RDCode code; | |||||
public ABException() { | |||||
super(RDCode.exception.getMessage()); | |||||
this.code = RDCode.exception; | |||||
log(); | |||||
} | |||||
public ABException(String msg, Throwable cause) { | |||||
super(msg, cause); | |||||
this.code = RDCode.exception; | |||||
log(); | |||||
} | |||||
public ABException(RDCode code, String msg) { | |||||
super(msg); | |||||
this.code = code; | |||||
log(); | |||||
} | |||||
public ABException(RDCode code, String msg, Throwable cause) { | |||||
super(msg, cause); | |||||
this.code = code; | |||||
log(); | |||||
} | |||||
public ABException(String msg) { | |||||
super(msg); | |||||
this.code = RDCode.exception; | |||||
log(); | |||||
} | |||||
public ABException(RDCode code) { | |||||
super(code.getMessage()); | |||||
this.code = code; | |||||
log(); | |||||
} | |||||
public RDCode getCode() { | |||||
return code; | |||||
} | |||||
private void log() { | |||||
log.error(this.getClass().getName() + ":" + this.code.getState() + ":" + this.getMessage()); | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RDCode; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
/** | |||||
* 失败异常 | |||||
*/ | |||||
@Slf4j | |||||
public class FailureException extends ABException { | |||||
public FailureException(String msg) { | |||||
super(RDCode.failure, msg); | |||||
} | |||||
} |
@@ -0,0 +1,66 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RD; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.http.HttpHeaders; | |||||
import org.springframework.http.HttpStatus; | |||||
import org.springframework.http.ResponseEntity; | |||||
import org.springframework.validation.BindException; | |||||
import org.springframework.validation.FieldError; | |||||
import org.springframework.validation.ObjectError; | |||||
import org.springframework.web.bind.MethodArgumentNotValidException; | |||||
import org.springframework.web.bind.annotation.ControllerAdvice; | |||||
import org.springframework.web.context.request.WebRequest; | |||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
@Slf4j | |||||
@ControllerAdvice | |||||
public class GlobalControllerException extends ResponseEntityExceptionHandler { | |||||
private ObjectError error; | |||||
@Override | |||||
protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { | |||||
log.info("------ GlobalControllerException -----"); | |||||
//ex.printStackTrace(); | |||||
//System.out.println("====== GlobalControllerException ====="); | |||||
List<ObjectError> list = ex.getAllErrors(); | |||||
if (list.size() > 0) { | |||||
return handleExceptionInternal(ex, RD.failure(list.get(0).getDefaultMessage()), headers, status, request); | |||||
} | |||||
return handleExceptionInternal(ex, RD.failure(ex.getMessage()), headers, status, request); | |||||
} | |||||
@Override | |||||
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { | |||||
System.out.println("------ MethodArgumentExceptionHandler -----"); | |||||
//ex.printStackTrace(); | |||||
//System.out.println("====== MethodArgumentExceptionHandler ====="); | |||||
List<ObjectError> list = ex.getBindingResult().getAllErrors(); | |||||
if (list.size() > 0) { | |||||
// return handleExceptionInternal(ex, RD.failure(list.get(0).getDefaultMessage()), headers, status, request); | |||||
Map<String, String> result = new HashMap<>(); | |||||
for (ObjectError error : list) { | |||||
if (error instanceof FieldError) { | |||||
FieldError err = (FieldError) error; | |||||
result.put(err.getField(), err.getDefaultMessage()); | |||||
} | |||||
} | |||||
if (result.size() > 0) { | |||||
return handleExceptionInternal(ex, RD.failureByForm("操作失败", result), headers, HttpStatus.OK, request); | |||||
} | |||||
} | |||||
return handleExceptionInternal(ex, RD.failure(ex.getMessage()), headers, status, request); | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RD; | |||||
import com.qmrz.utils.Web; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.web.servlet.HandlerExceptionResolver; | |||||
import org.springframework.web.servlet.ModelAndView; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
/** | |||||
* 全局 spring 异常捕获 | |||||
*/ | |||||
@Slf4j | |||||
public class GlobalSpringException implements HandlerExceptionResolver { | |||||
@Override | |||||
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { | |||||
log.info("GlobalSpringException:" + ex.getMessage()); | |||||
if (ex instanceof org.apache.shiro.authz.UnauthorizedException) { | |||||
Web.printRD(response, RD.notpermission()); | |||||
return new ModelAndView(); | |||||
} else if (ex instanceof ABException) { | |||||
ABException ab = (ABException) ex; | |||||
Web.printRD(response, RD.create(ab.getCode(), ab.getMessage(), null)); | |||||
return new ModelAndView(); | |||||
} else { | |||||
Web.printRD(response, RD.exception(ex.getMessage()+ ex.getClass().getName())); | |||||
log.error(RD.exception(ex.getMessage() + ex.getClass().getName()).toString()); | |||||
ex.printStackTrace(); | |||||
return new ModelAndView(); | |||||
} | |||||
// return null; | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RDCode; | |||||
/** | |||||
* 无权限异常 | |||||
*/ | |||||
public class NotPermissionException extends ABException { | |||||
public NotPermissionException() { | |||||
super(RDCode.nopermission); | |||||
} | |||||
public NotPermissionException(String msg) { | |||||
super(RDCode.nopermission,msg); | |||||
} | |||||
} |
@@ -0,0 +1,12 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RDCode; | |||||
/** | |||||
* 民警未登录或超时 | |||||
*/ | |||||
public class PoliceNotLoginException extends ABException { | |||||
public PoliceNotLoginException() { | |||||
super(RDCode.notlogin); | |||||
} | |||||
} |
@@ -0,0 +1,12 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RDCode; | |||||
/** | |||||
* 用户未登录 | |||||
*/ | |||||
public class UserNotLoginException extends ABException { | |||||
public UserNotLoginException() { | |||||
super(RDCode.notlogin); | |||||
} | |||||
} |
@@ -0,0 +1,12 @@ | |||||
package com.qmrz.exception; | |||||
import com.qmrz.utils.RDCode; | |||||
/** | |||||
* 微信用户未授权或超时 | |||||
*/ | |||||
public class WXUserNotAuthorizationException extends ABException { | |||||
public WXUserNotAuthorizationException() { | |||||
super(RDCode.notauthorization); | |||||
} | |||||
} |
@@ -0,0 +1,274 @@ | |||||
package com.qmrz.mybatis; | |||||
import com.github.pagehelper.Page; | |||||
import com.github.pagehelper.PageHelper; | |||||
import com.qmrz.dto.ParamPageDTO; | |||||
import com.qmrz.exception.ABException; | |||||
import com.qmrz.mybatis.service.BaseService; | |||||
import com.qmrz.mybatis.sql.BaseWrapper; | |||||
import com.qmrz.mybatis.sql.sqlnode.UpdateParam; | |||||
import com.qmrz.utils.PageData; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.mybatis.spring.SqlSessionTemplate; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.function.Consumer; | |||||
@Slf4j | |||||
public class BasePO<T> implements BaseService<T> { | |||||
SqlSessionTemplate sqlTemp; | |||||
POUtil poUtil; | |||||
private POProxy poProxy; | |||||
public void _setPoProxy(POProxy poProxy) { | |||||
this.poProxy = poProxy; | |||||
} | |||||
public POProxy _getProxy() { | |||||
return poProxy; | |||||
} | |||||
public void _setPoUtil(POUtil poUtil) { | |||||
this.poUtil = poUtil; | |||||
} | |||||
public BasePO() { | |||||
this.sqlTemp = SpringContextUtil.getBean(SqlSessionTemplate.class); | |||||
} | |||||
private String getMSID(String methodName) { | |||||
String claName; | |||||
if (poProxy != null) { | |||||
claName = poProxy.getClassPO().getName(); | |||||
} else { | |||||
claName = this.getClass().getName(); | |||||
} | |||||
return claName + "_" + methodName + "_ActiveRecord"; | |||||
} | |||||
private Map<String, Object> toMap(Object obj) { | |||||
return toMap(obj, true); | |||||
} | |||||
private Map<String, Object> toMap(Object obj, boolean isContainKey) { | |||||
if (obj instanceof Map) { | |||||
return (Map) obj; | |||||
} | |||||
if (obj instanceof BasePO) { | |||||
BasePO basePO = (BasePO) obj; | |||||
if (basePO._getProxy() == null) { | |||||
throw new ABException("请使用proxy()创建实体对象:" + this.getClass().getName()); | |||||
// return new POUtil(obj.getClass()).getMapNotNull(obj); | |||||
} else { | |||||
Map result = basePO._getProxy().getSetList(); | |||||
if (!isContainKey) { | |||||
result.remove(poUtil.getPrimarykey().getFieldNameByDB()); | |||||
} | |||||
return result; | |||||
} | |||||
} else { | |||||
return poUtil.getParam(obj); | |||||
} | |||||
// throw new ABException("非法参数"); | |||||
} | |||||
private BasePO createProxy() { | |||||
poProxy = new POProxy(); | |||||
poUtil = new POUtil(this.getClass()); | |||||
BasePO po = poProxy.getProxy(this.getClass()); | |||||
po._setPoProxy(poProxy); | |||||
po._setPoUtil(poUtil); | |||||
return po; | |||||
} | |||||
/** | |||||
* 创建代理对象 | |||||
* | |||||
* @return | |||||
*/ | |||||
public T proxy() { | |||||
return (T) this.createProxy(); | |||||
} | |||||
/** | |||||
* 创建代理对象,并初始化填充代理对象 | |||||
* | |||||
* @param object 将object属性填充到代理对象(即将非代理对象使用代理对象接管) | |||||
* @return | |||||
*/ | |||||
public T proxy(Object object) { | |||||
return proxy(object, false); | |||||
} | |||||
/** | |||||
* @param object | |||||
* @param isAllowNull 指定object里属性是否允许为空 | |||||
* @return | |||||
*/ | |||||
public T proxy(Object object, boolean isAllowNull) { | |||||
BasePO po = this.createProxy(); | |||||
POUtil.fillNotNull(po, object, isAllowNull); | |||||
return (T) po; | |||||
} | |||||
/** | |||||
* 创建代理对象,并初始化填充代理对象数据 | |||||
* | |||||
* @param object | |||||
* @param only 初始指定字段(初始化数据时,只填充在onlyFieldNameList里包含的字段) | |||||
* @return | |||||
*/ | |||||
public T proxy(Object object, String... only) { | |||||
return proxy(object, false, only); | |||||
} | |||||
public T proxy(Object object, boolean isAllowNull, String... only) { | |||||
BasePO po = this.createProxy(); | |||||
//将object属性填充到代理对象(即将非代理对象使用代理对象接管) | |||||
POUtil.fillNotNull(po, object, only, isAllowNull); | |||||
return (T) po; | |||||
} | |||||
@Override | |||||
public List<T> selectWrapper(Consumer<? super BaseWrapper> wrapper) { | |||||
return this.sqlTemp.selectList(getMSID("selectWrapper"), wrapper); | |||||
} | |||||
@Override | |||||
public T selectOneWrapper(Consumer<? super BaseWrapper> wrapper) { | |||||
List<T> list = this.sqlTemp.selectList(getMSID("selectOneWrapper"), wrapper); | |||||
if (list.size() == 0) { | |||||
return null; | |||||
} | |||||
return list.get(0); | |||||
} | |||||
@Override | |||||
public Integer updateWrapper(Object param, Consumer<? super BaseWrapper> wrapper) { | |||||
return this.sqlTemp.update(getMSID("updateWrapper") | |||||
, new UpdateParam(toMap(param), wrapper)); | |||||
} | |||||
public Integer update(Consumer<? super BaseWrapper> wrapper) { | |||||
return this.sqlTemp.update(getMSID("updateWrapper") | |||||
, new UpdateParam(toMap(this), wrapper)); | |||||
} | |||||
@Override | |||||
public Integer deleteWrapper(Consumer<? super BaseWrapper> wrapper) { | |||||
return this.sqlTemp.delete(getMSID("deleteWrapper"), wrapper); | |||||
} | |||||
public PageData<T> selectPage(ParamPageDTO paramPageDTO, Consumer<? super BaseWrapper> wrapper) { | |||||
PageHelper.startPage(paramPageDTO.getPageIndex(), paramPageDTO.getPageSize()); | |||||
Page<T> result = (Page<T>) this.sqlTemp.selectList(getMSID("selectWrapper"), wrapper); | |||||
return PageData.newobj(result); | |||||
} | |||||
public List<T> select() { | |||||
return this.select(this); | |||||
} | |||||
@Override | |||||
public List<T> select(Object whereObject) { | |||||
return this.sqlTemp.selectList(getMSID("select"), toMap(whereObject)); | |||||
} | |||||
public PageData<T> selectPage(ParamPageDTO paramPageDTO) { | |||||
PageHelper.startPage(paramPageDTO.getPageIndex(), paramPageDTO.getPageSize()); | |||||
return PageData.newobj((Page<T>) (this.select(this))); | |||||
} | |||||
@Override | |||||
public T selectOne(Object whereObject) { | |||||
return this.sqlTemp.selectOne(getMSID("selectOne"), toMap(whereObject)); | |||||
} | |||||
public T selectOne() { | |||||
return this.selectOne(this); | |||||
} | |||||
@Override | |||||
public Integer selectCount(Object whereObject) { | |||||
List<Integer> result = this.sqlTemp.selectList(getMSID("selectCount"), toMap(whereObject)); | |||||
return result.get(0); | |||||
} | |||||
public Integer selectCount() { | |||||
return this.selectCount(this); | |||||
} | |||||
@Override | |||||
public List<T> selectAll() { | |||||
return this.sqlTemp.selectList(getMSID("selectAll"), new LinkedHashMap<>()); | |||||
} | |||||
@Override | |||||
public T selectByPrimaryKey(Object paramPrimaryKey) { | |||||
return this.selectOne(poUtil.getParamPrimaryKey(paramPrimaryKey)); | |||||
} | |||||
public T selectByPrimaryKey() { | |||||
return this.selectByPrimaryKey(this); | |||||
} | |||||
@Override | |||||
public int delete(Object whereObject) { | |||||
return this.sqlTemp.delete(getMSID("delete"), toMap(whereObject)); | |||||
} | |||||
@Override | |||||
public int deleteByPrimaryKey(Object paramPrimaryKey) { | |||||
return this.delete(poUtil.getParamPrimaryKey(paramPrimaryKey)); | |||||
} | |||||
public int deleteByPrimaryKey() { | |||||
return this.deleteByPrimaryKey(this); | |||||
} | |||||
public int delete() { | |||||
return this.delete(this); | |||||
} | |||||
@Override | |||||
public int insert(T entity) { | |||||
return this.sqlTemp.insert(getMSID("insert"), entity); | |||||
} | |||||
public int insert() { | |||||
return this.insert((T) this); | |||||
} | |||||
public int update(Object paramSet, Object paramWhere) { | |||||
UpdateParam param = new UpdateParam(toMap(paramSet), toMap(paramWhere)); | |||||
return this.update(param); | |||||
} | |||||
@Override | |||||
public int updateByPrimaryKey(Object whereValue) { | |||||
return this.update(toMap(this, false), poUtil.getParamPrimaryKeyByValue(whereValue)); | |||||
//poUtil.getParamWriteNotNull(this) | |||||
} | |||||
@Override | |||||
public int update(UpdateParam updateParam) { | |||||
return this.sqlTemp.update(getMSID("update"), updateParam); | |||||
} | |||||
public int updateByPrimaryKey() { | |||||
return this.updateByPrimaryKey(poUtil.getValueByPrimaryKey(this)); | |||||
} | |||||
public int updateByPrimaryKey(Object paramSet, Object whereValue) { | |||||
return this.update(paramSet, poUtil.getParamPrimaryKeyByValue(whereValue)); | |||||
} | |||||
} |
@@ -0,0 +1,205 @@ | |||||
package com.qmrz.mybatis; | |||||
import com.qmrz.mybatis.sql.sqlnode.SqlNodeWrapper; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.ibatis.mapping.MappedStatement; | |||||
import org.apache.ibatis.scripting.xmltags.SqlNode; | |||||
@Slf4j | |||||
public class BaseProviderSqlSource { | |||||
public SqlNode selectWrapper(MappedStatement ms, Class<?> classPO) { | |||||
MapperUtil.setResultType(ms, classPO); | |||||
return new SqlNodeWrapper(classPO, "selectWrapper"); | |||||
} | |||||
public SqlNode selectOneWrapper(MappedStatement ms, Class<?> classPO) { | |||||
MapperUtil.setResultType(ms, classPO); | |||||
return new SqlNodeWrapper(classPO, "selectOneWrapper"); | |||||
} | |||||
public SqlNode updateWrapper(MappedStatement ms, Class<?> classPO) { | |||||
return new SqlNodeWrapper(classPO, "updateWrapper"); | |||||
} | |||||
public SqlNode deleteWrapper(MappedStatement ms, Class<?> classPO) { | |||||
return new SqlNodeWrapper(classPO, "deleteWrapper"); | |||||
} | |||||
/** | |||||
* 该方法仅仅用来初始化ProviderSqlSource | |||||
* | |||||
* @param record | |||||
* @return | |||||
*/ | |||||
public String dynamicSQL(Object record) { | |||||
log.info("BaseProviderSqlSource dynamicSQL"); | |||||
return "dynamicSQL"; | |||||
} | |||||
public SqlNode select(MappedStatement ms, Class<?> classPO) { | |||||
MapperUtil.setResultType(ms, classPO); | |||||
return new SqlNodeWrapper(classPO, "select"); | |||||
//修改返回值类型为实体类型 | |||||
// MapperUtil.setResultType(ms, classPO); | |||||
// | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.selectAllColumns()); | |||||
// sql.append(sqlUtil.fromTable()); | |||||
// sql.append(sqlUtil.whereAllIfFieldXML()); | |||||
// sql.append(sqlUtil.orderByDefault()); | |||||
// | |||||
// return sql.toString(); | |||||
} | |||||
/** | |||||
* 查询全部结果 | |||||
*/ | |||||
public SqlNode selectAll(MappedStatement ms, Class<?> classPO) { | |||||
MapperUtil.setResultType(ms, classPO); | |||||
return new SqlNodeWrapper(classPO, "select"); | |||||
//修改返回值类型为实体类型 | |||||
// MapperUtil.setResultType(ms, classPO); | |||||
// | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.selectAllColumns()); | |||||
// sql.append(sqlUtil.fromTable()); | |||||
// sql.append(sqlUtil.orderByDefault()); | |||||
// | |||||
// return sql.toString(); | |||||
} | |||||
public SqlNode selectOne(MappedStatement ms, Class<?> classPO) { | |||||
MapperUtil.setResultType(ms, classPO); | |||||
return new SqlNodeWrapper(classPO, "selectOne"); | |||||
//修改返回值类型为实体类型 | |||||
// MapperUtil.setResultType(ms, classPO); | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.selectAllColumns()); | |||||
// sql.append(sqlUtil.fromTable()); | |||||
// sql.append(sqlUtil.whereXML()); | |||||
// sql.append(sqlUtil.limit(1)); | |||||
// return sql.toString(); | |||||
} | |||||
/** | |||||
* 根据主键字段进行查询,查询条件使用等号 | |||||
*/ | |||||
public SqlNode selectByPrimaryKey(MappedStatement ms, Class<?> classPO) { | |||||
MapperUtil.setResultType(ms, classPO); | |||||
return new SqlNodeWrapper(classPO, "select"); | |||||
//修改返回值类型为实体类型 | |||||
// MapperUtil.setResultType(ms, classPO); | |||||
// | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.selectAllColumns()); | |||||
// sql.append(sqlUtil.fromTable()); | |||||
// sql.append(sqlUtil.whereByPrimaryKeyXML()); | |||||
// | |||||
// return sql.toString(); | |||||
} | |||||
/** | |||||
* 根据实体中的属性查询总数,查询条件使用等号 | |||||
*/ | |||||
public SqlNode selectCount(MappedStatement ms, Class<?> classPO) { | |||||
MapperUtil.setResultType2(ms, Integer.class,"_count"); | |||||
return new SqlNodeWrapper(classPO, "selectCount"); | |||||
//修改返回值类型为实体类型 | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.selectCount()); | |||||
// sql.append(sqlUtil.fromTable()); | |||||
// sql.append(sqlUtil.whereAllIfFieldXML()); | |||||
// | |||||
// return sql.toString(); | |||||
} | |||||
/** | |||||
* 根据主键字段进行删除,方法参数必须包含完整的主键属性 | |||||
*/ | |||||
public SqlNode deleteByPrimaryKey(MappedStatement ms, Class<?> classPO) { | |||||
return new SqlNodeWrapper(classPO, "delete"); | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.deleteFrom()); | |||||
// sql.append(sqlUtil.whereByPrimaryKeyXML()); | |||||
// return sql.toString(); | |||||
} | |||||
/** | |||||
* 根据实体属性作为条件进行删除,查询条件使用等号 | |||||
*/ | |||||
public SqlNode delete(MappedStatement ms, Class<?> classPO) { | |||||
return new SqlNodeWrapper(classPO, "delete"); | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.deleteFrom()); | |||||
// sql.append(sqlUtil.whereAllIfFieldXML()); | |||||
// return sql.toString(); | |||||
} | |||||
/** | |||||
* 保存一个实体,null的属性不会保存,会使用数据库默认值 | |||||
*/ | |||||
public SqlNode insert(MappedStatement ms, Class<?> classPO) { | |||||
return new SqlNodeWrapper(classPO, "insert"); | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.insertXML()); | |||||
// return sql.toString(); | |||||
} | |||||
// /** | |||||
// * 保存一个实体,所有字段都会插入,null的属性也会保存,不会使用数据库默认值 | |||||
// */ | |||||
// public String insertAllProperty(MappedStatement ms){ | |||||
// System.out.println("BaseProviderSqlSource select"); | |||||
// return "select id,name from test where 1=#{id}"; | |||||
// } | |||||
/** | |||||
* 根据主键更新实体全部字段,null值不会被更新 | |||||
*/ | |||||
public SqlNode updateByPrimaryKey(MappedStatement ms, Class<?> classPO) { | |||||
return new SqlNodeWrapper(classPO, "update"); | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.updateSetXML()); | |||||
// sql.append(sqlUtil.whereByPrimaryKeyXML()); | |||||
// return sql.toString(); | |||||
} | |||||
public SqlNode update(MappedStatement ms, Class<?> classPO) { | |||||
return new SqlNodeWrapper(classPO, "update"); | |||||
// SqlUtil sqlUtil = new SqlUtil(classPO); | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(sqlUtil.updateSetXML()); | |||||
// sql.append(sqlUtil.whereByPrimaryKeyXML()); | |||||
// return sql.toString(); | |||||
} | |||||
/** | |||||
* 根据主键更新实体全部字段,null值也会被更新 | |||||
*/ | |||||
// public String updateByPrimaryKeyAllProperty(MappedStatement ms){ | |||||
// System.out.println("BaseProviderSqlSource select"); | |||||
// return "select id,name from test where 1=#{id}"; | |||||
// } | |||||
} |
@@ -0,0 +1,5 @@ | |||||
package com.qmrz.mybatis; | |||||
public class DBWrapper { | |||||
} |
@@ -0,0 +1,4 @@ | |||||
package com.qmrz.mybatis; | |||||
public interface INull<T> { | |||||
} |
@@ -0,0 +1,131 @@ | |||||
package com.qmrz.mybatis; | |||||
import com.qmrz.mybatis.sql.BaseWrapper; | |||||
import org.apache.ibatis.annotations.*; | |||||
import java.util.List; | |||||
import java.util.function.Consumer; | |||||
public interface Mapper<T> { | |||||
// @Options(useGeneratedKeys = true, keyProperty = "id") | |||||
@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
List<T> selectWrapper(Consumer<? super BaseWrapper> wrapper); | |||||
@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
T selectOneWrapper(Consumer<? super BaseWrapper> wrapper); | |||||
@UpdateProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
Integer updateWrapper(Object param, Consumer<? super BaseWrapper> wrapper); | |||||
@DeleteProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
Integer deleteWrapper(Consumer<? super BaseWrapper> wrapper); | |||||
/** | |||||
* 根据实体中的属性值进行查询,查询条件使用等号 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
List<T> select(Object whereObject); | |||||
//@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
//List<T> selectList(T entity, IWrapper wrapper); | |||||
/** | |||||
* 根据实体中的属性进行查询,只能有一个返回值,有多个结果取第1个 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
T selectOne(Object whereObject); | |||||
/** | |||||
* 根据实体中的属性查询总数,查询条件使用等号 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
Integer selectCount(Object whereObject); | |||||
/** | |||||
* 查询全部结果 | |||||
* | |||||
* @return | |||||
*/ | |||||
@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
List<T> selectAll(); | |||||
/** | |||||
* 根据主键字段进行查询,查询条件使用等号 | |||||
* | |||||
* @param paramPrimaryKey map或实体 | |||||
* @return | |||||
*/ | |||||
@SelectProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
T selectByPrimaryKey(Object paramPrimaryKey); | |||||
/** | |||||
* 根据主键字段进行删除,方法参数必须包含完整的主键属性 | |||||
* | |||||
* @param paramPrimaryKey map或实体 | |||||
* @return | |||||
*/ | |||||
@DeleteProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
int deleteByPrimaryKey(Object paramPrimaryKey); | |||||
/** | |||||
* 根据实体属性作为条件进行删除,查询条件使用等号 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
@DeleteProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
int delete(Object whereObject); | |||||
/** | |||||
* 保存一个实体,null的属性不会保存,会使用数据库默认值 | |||||
* | |||||
* @param entity map或实体 | |||||
* @return | |||||
*/ | |||||
@Options(useGeneratedKeys=true,keyProperty = "id") | |||||
@InsertProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
int insert(T entity); | |||||
/** | |||||
* 保存一个实体,所有字段都会插入,null的属性也会保存,不会使用数据库默认值 | |||||
* | |||||
* @param entity | |||||
* @return | |||||
*/ | |||||
// @InsertProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
// int insertAllProperty(T entity); | |||||
/** | |||||
* 根据主键更新实体全部字段,null值不会被更新 | |||||
* | |||||
* @param paramMap map或实体 | |||||
* @return | |||||
*/ | |||||
@UpdateProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
int updateByPrimaryKey(Object paramMap); | |||||
@UpdateProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
int update(Object paramMap); | |||||
/** | |||||
* 根据主键更新实体全部字段,null值也会被更新 | |||||
* | |||||
* @param entity | |||||
* @return | |||||
*/ | |||||
// @UpdateProvider(type = BaseProviderSqlSource.class, method = "dynamicSQL") | |||||
// int updateByPrimaryKeyAllProperty(T entity); | |||||
} |
@@ -0,0 +1,234 @@ | |||||
package com.qmrz.mybatis; | |||||
import com.qmrz.exception.ABException; | |||||
import com.qmrz.mybatis.service.BaseService; | |||||
import com.qmrz.utils.SpringContextUtil; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.ibatis.builder.annotation.ProviderSqlSource; | |||||
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; | |||||
import org.apache.ibatis.executor.keygen.NoKeyGenerator; | |||||
import org.apache.ibatis.mapping.*; | |||||
import org.apache.ibatis.reflection.MetaObject; | |||||
import org.apache.ibatis.reflection.SystemMetaObject; | |||||
import org.apache.ibatis.scripting.xmltags.DynamicSqlSource; | |||||
import org.apache.ibatis.scripting.xmltags.SqlNode; | |||||
import org.apache.ibatis.scripting.xmltags.TextSqlNode; | |||||
import org.apache.ibatis.session.Configuration; | |||||
import org.apache.ibatis.session.SqlSessionFactory; | |||||
import org.springframework.core.io.Resource; | |||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; | |||||
import java.io.IOException; | |||||
import java.lang.reflect.InvocationTargetException; | |||||
import java.lang.reflect.Method; | |||||
import java.util.*; | |||||
/** | |||||
* mybatis功能扩展,实现无xml mapper | |||||
*/ | |||||
@Slf4j | |||||
public class MapperScan { | |||||
/** | |||||
* 通用方法 | |||||
*/ | |||||
private Map<String, Method> methods; | |||||
private Configuration configuration; | |||||
private BaseProviderSqlSource baseProviderSqlSource; | |||||
public MapperScan() { | |||||
load(SpringContextUtil.getBean(SqlSessionFactory.class)); | |||||
} | |||||
public MapperScan(SqlSessionFactory sqlSessionFactory) { | |||||
load(sqlSessionFactory); | |||||
} | |||||
public void load(SqlSessionFactory sqlSessionFactory) { | |||||
this.methods = new HashMap<>(); | |||||
this.baseProviderSqlSource = new BaseProviderSqlSource(); | |||||
this.configuration = sqlSessionFactory.getConfiguration(); | |||||
for (Method method : BaseProviderSqlSource.class.getDeclaredMethods()) { | |||||
methods.put(method.getName(), method); | |||||
} | |||||
} | |||||
/** | |||||
* 同时扩展mybatis接口和实体功能 | |||||
* @throws IllegalAccessException | |||||
* @throws InvocationTargetException | |||||
* @throws ClassNotFoundException | |||||
*/ | |||||
public void register() throws IllegalAccessException, InvocationTargetException, ClassNotFoundException { | |||||
log.info("扩展 mybatis 接口、实体"); | |||||
registerMapper(); | |||||
registerActiveRecord(); | |||||
} | |||||
/** | |||||
* 实现无xml的mapper接口 | |||||
* @throws InvocationTargetException | |||||
* @throws IllegalAccessException | |||||
*/ | |||||
public void registerMapper() throws InvocationTargetException, IllegalAccessException { | |||||
// log.info("MapperScan registerMapper"); | |||||
for (Object object : new ArrayList<Object>(configuration.getMappedStatements())) { | |||||
if (!(object instanceof MappedStatement)) { | |||||
continue; | |||||
} | |||||
MappedStatement mappedStatement = (MappedStatement) object; | |||||
SqlSource sqlSourceTemp = mappedStatement.getSqlSource(); | |||||
if (!(sqlSourceTemp instanceof ProviderSqlSource)) { | |||||
continue; | |||||
} | |||||
log.info("mappedStatement:" + mappedStatement.getId()); | |||||
String msId = mappedStatement.getId(); | |||||
Method method = methods.get(msId.substring(msId.lastIndexOf(".") + 1)); | |||||
if (method == null) { | |||||
log.warn("通用mapper:" + msId + " 在BaseProviderSqlSource找不到提供方法"); | |||||
continue; | |||||
} | |||||
Class<?> classPO = MapperUtil.getMapperClass(mappedStatement); | |||||
SqlSource sqlSource = createSqlSource(method, mappedStatement, classPO, null); | |||||
MetaObject msObject = SystemMetaObject.forObject(object); | |||||
msObject.setValue("sqlSource", sqlSource); | |||||
} | |||||
} | |||||
/** | |||||
* 创建字符串类型sqlSource | |||||
* @param script | |||||
* @param parameterType | |||||
* @return | |||||
*/ | |||||
private SqlSource createSqlSource(String script, Class<?> parameterType) { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append("<script>\n\t"); | |||||
sql.append(script); | |||||
sql.append("</script>"); | |||||
return configuration.getDefaultScriptingLanguageInstance() | |||||
.createSqlSource(configuration, sql.toString(), parameterType); | |||||
} | |||||
/** | |||||
* 创建sqlSource对象,自动识别sql类型(String、SqlNode) | |||||
* @param method | |||||
* @param mappedStatement | |||||
* @param classPO | |||||
* @param parameterType | |||||
* @return | |||||
* @throws InvocationTargetException | |||||
* @throws IllegalAccessException | |||||
*/ | |||||
private SqlSource createSqlSource(Method method, MappedStatement mappedStatement, Class<?> classPO, Class<?> parameterType) throws InvocationTargetException, IllegalAccessException { | |||||
SqlSource sqlSource; | |||||
if (String.class.equals(method.getReturnType())) { | |||||
String script = (String) method.invoke(baseProviderSqlSource, mappedStatement, classPO); | |||||
sqlSource = createSqlSource(script, parameterType); | |||||
} else if (SqlNode.class.isAssignableFrom(method.getReturnType())) { | |||||
SqlNode sqlNode = (SqlNode) method.invoke(baseProviderSqlSource, mappedStatement, classPO); | |||||
sqlSource = new DynamicSqlSource(configuration, sqlNode); | |||||
} else { | |||||
throw new ABException("未知sql源"); | |||||
} | |||||
return sqlSource; | |||||
} | |||||
/** | |||||
* 扩展实体功能 | |||||
* @throws ClassNotFoundException | |||||
* @throws InvocationTargetException | |||||
* @throws IllegalAccessException | |||||
*/ | |||||
public void registerActiveRecord() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException { | |||||
//获取实体资源 | |||||
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); | |||||
Resource[] r = new Resource[0]; | |||||
try { | |||||
r = resolver.getResources("classpath*:com/qmrz/domain/**/*.class"); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
//实体资源转字符串 | |||||
List<String> classList = new ArrayList<>(); | |||||
try { | |||||
for (Resource resource : r) { | |||||
String path = resource.getURL().getPath(); | |||||
path = path.replace("\\", "/"); | |||||
classList.add(path.substring(path.indexOf("/com/") + 1 | |||||
, path.lastIndexOf(".class")) | |||||
.replace("/", ".")); | |||||
} | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
//将属于BasePO类的实体进行扩展 | |||||
for (String str : classList) { | |||||
Class<?> classPO = Class.forName(str); | |||||
if (!BasePO.class.isAssignableFrom(classPO)) { | |||||
continue; | |||||
} | |||||
Method[] methods = BaseService.class.getMethods(); | |||||
for (Method method : methods) { | |||||
registerActiveRecordMethod(method.getName(), classPO); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* 注册实体扩展方法 | |||||
* @param methodName | |||||
* @param classPO | |||||
* @throws InvocationTargetException | |||||
* @throws IllegalAccessException | |||||
*/ | |||||
private void registerActiveRecordMethod(String methodName, Class<?> classPO) throws InvocationTargetException, IllegalAccessException { | |||||
String id = classPO.getName() + "_" + methodName; | |||||
String newMsId = id + "_ActiveRecord"; | |||||
//创建默认动态sql | |||||
SqlSource sqlSource = new DynamicSqlSource(configuration, new TextSqlNode("SQL_CommonMapper")); | |||||
SqlCommandType sqlCommandType = null; | |||||
if (methodName.startsWith("select")) { | |||||
sqlCommandType = SqlCommandType.SELECT; | |||||
} else if (methodName.startsWith("update")) { | |||||
sqlCommandType = SqlCommandType.UPDATE; | |||||
} else if (methodName.startsWith("insert")) { | |||||
sqlCommandType = SqlCommandType.INSERT; | |||||
} else if (methodName.startsWith("delete")) { | |||||
sqlCommandType = SqlCommandType.DELETE; | |||||
} | |||||
//Statement构建配置 | |||||
MappedStatement.Builder builder = | |||||
new MappedStatement.Builder(configuration | |||||
, newMsId, sqlSource, sqlCommandType); | |||||
if (methodName.startsWith("insert")) { | |||||
builder.keyProperty("id"); | |||||
} | |||||
//Statement构建 | |||||
MappedStatement statement = builder.build(); | |||||
//insert后支持主键注入 | |||||
builder.keyGenerator(SqlCommandType.INSERT.equals(sqlCommandType) ? new Jdbc3KeyGenerator() : new NoKeyGenerator()); | |||||
//获取statement对应方法 | |||||
Method method = methods.get(methodName); | |||||
//扩展方法与statement绑定并返回SqlSource | |||||
sqlSource = createSqlSource(method, statement, classPO, null); | |||||
//配置statement方法的sql源 | |||||
MetaObject msObject = SystemMetaObject.forObject(statement); | |||||
msObject.setValue("sqlSource", sqlSource); | |||||
//注入mybatis | |||||
configuration.addMappedStatement(statement); | |||||
} | |||||
} |
@@ -0,0 +1,33 @@ | |||||
package com.qmrz.mybatis; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry; | |||||
@Slf4j | |||||
public class MapperScannerConfigurer extends org.mybatis.spring.mapper.MapperScannerConfigurer { | |||||
public void setMarkerInterface(Class<?> superClass) { | |||||
log.info("setMarkerInterface"); | |||||
log.info(superClass.getName()); | |||||
super.setMarkerInterface(superClass); | |||||
// this.markerInterface = superClass; | |||||
// if (Marker.class.isAssignableFrom(superClass)) { | |||||
// mapperHelper.registerMapper(superClass); | |||||
// } | |||||
} | |||||
@Override | |||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { | |||||
log.info("postProcessBeanDefinitionRegistry"); | |||||
super.postProcessBeanDefinitionRegistry(registry); | |||||
} | |||||
@Override | |||||
public void afterPropertiesSet() throws Exception { | |||||
log.info("afterPropertiesSet"); | |||||
super.afterPropertiesSet(); | |||||
} | |||||
} |
@@ -0,0 +1,96 @@ | |||||
package com.qmrz.mybatis; | |||||
import com.qmrz.exception.ABException; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.ibatis.mapping.MappedStatement; | |||||
import org.apache.ibatis.mapping.ResultMap; | |||||
import org.apache.ibatis.mapping.ResultMapping; | |||||
import org.apache.ibatis.reflection.MetaObject; | |||||
import org.apache.ibatis.reflection.SystemMetaObject; | |||||
import org.apache.ibatis.session.Configuration; | |||||
import java.lang.reflect.Field; | |||||
import java.lang.reflect.ParameterizedType; | |||||
import java.util.ArrayList; | |||||
import java.util.Collections; | |||||
import java.util.List; | |||||
@Slf4j | |||||
public class MapperUtil { | |||||
/** | |||||
* 获取Mapper的泛型实体 | |||||
* | |||||
* @param ms | |||||
* @return | |||||
*/ | |||||
public static Class<?> getMapperClass(MappedStatement ms) { | |||||
// log.warn(ms.getResource()); | |||||
String poClassName = ms.getResource().replace(".java (best guess)", "") | |||||
.replace("/", "."); | |||||
//获取实体 | |||||
Class<?> classPO; | |||||
try { | |||||
Class<?> clazz = Class.forName(poClassName); | |||||
classPO = (Class<?>) ((ParameterizedType) (clazz.getGenericInterfaces()[0])).getActualTypeArguments()[0]; | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
throw new ABException("通用Mapper:" + e.getMessage()); | |||||
} | |||||
// log.warn(classPO.getName()); | |||||
return classPO; | |||||
} | |||||
public static void setResultType(MappedStatement ms, Class<?> classPO) { | |||||
Configuration configuration = ms.getConfiguration(); | |||||
MetaObject msObject = SystemMetaObject.forObject(ms); | |||||
// List<ResultMapping> resultMappings = new ArrayList<>(); | |||||
// MetaObject msObject = SystemMetaObject.forObject(ms); | |||||
// ResultMap.Builder builder = new ResultMap.Builder(ms.getConfiguration() | |||||
// , classPO.getName() + "_ResultType", | |||||
// classPO, resultMappings, true); | |||||
// | |||||
// | |||||
// | |||||
// List<ResultMap> resultMaps = new ArrayList<>(); | |||||
// resultMaps.add(builder.build()); | |||||
// msObject.setValue("resultMaps", Collections.unmodifiableList(resultMaps)); | |||||
List<ResultMapping> resultMappings = new ArrayList<>(); | |||||
for (Field field : classPO.getDeclaredFields()) { | |||||
ResultMapping.Builder builder = new ResultMapping.Builder(configuration | |||||
, field.getName(), field.getName()//, POUtil.getFieldNameByDB(field) | |||||
, field.getType()); | |||||
resultMappings.add(builder.build()); | |||||
} | |||||
ResultMap.Builder builder = new ResultMap.Builder(configuration, classPO.getName() + "_CommonMapperResultMap", | |||||
classPO, resultMappings, true); | |||||
List<ResultMap> resultMaps = new ArrayList<>(); | |||||
resultMaps.add(builder.build()); | |||||
msObject.setValue("resultMaps", Collections.unmodifiableList(resultMaps)); | |||||
} | |||||
public static void setResultType2(MappedStatement ms, Class<?> cla, String fieldName) { | |||||
Configuration configuration = ms.getConfiguration(); | |||||
MetaObject msObject = SystemMetaObject.forObject(ms); | |||||
List<ResultMapping> resultMappings = new ArrayList<>(); | |||||
ResultMapping.Builder builder2 = new ResultMapping.Builder(configuration | |||||
, fieldName, fieldName//, POUtil.getFieldNameByDB(field) | |||||
, cla); | |||||
resultMappings.add(builder2.build()); | |||||
ResultMap.Builder builder = new ResultMap.Builder(configuration, cla.getName() + "_CommonMapperResultMap", | |||||
cla, resultMappings, true); | |||||
List<ResultMap> resultMaps = new ArrayList<>(); | |||||
resultMaps.add(builder.build()); | |||||
msObject.setValue("resultMaps", Collections.unmodifiableList(resultMaps)); | |||||
} | |||||
} |
@@ -0,0 +1,25 @@ | |||||
package com.qmrz.mybatis; | |||||
import lombok.Data; | |||||
import org.apache.commons.lang.StringUtils; | |||||
import java.util.List; | |||||
/** | |||||
* 实体属性与DB字段 | |||||
*/ | |||||
@Data | |||||
public class PO { | |||||
private String tableNameByDB; | |||||
private List<POPropertie> fieldList; | |||||
private Class<?> entityClass; | |||||
private String schemasName; | |||||
public String getTableNameByDBAll() { | |||||
if (StringUtils.isEmpty(this.schemasName)) { | |||||
return this.tableNameByDB; | |||||
} else { | |||||
return this.schemasName + "." + this.tableNameByDB; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
package com.qmrz.mybatis; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import java.lang.reflect.Field; | |||||
/** | |||||
* 实体属性与DB字段 | |||||
*/ | |||||
@Data | |||||
@AllArgsConstructor | |||||
public class POPropertie { | |||||
private String fieldName; | |||||
private String fieldNameByDB; | |||||
private Field field; | |||||
private Class<?> javaType; | |||||
/** | |||||
* 默认为null,若不为null,则对应db类型字段串 | |||||
*/ | |||||
private String dbType; | |||||
/** | |||||
* 0:无排序 1:asc 2:desc | |||||
*/ | |||||
private int orderByStatus; | |||||
private int orderByIndex; | |||||
private boolean isPrimarykey; | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package com.qmrz.mybatis; | |||||
import lombok.Data; | |||||
/** | |||||
* 实体属性与DB字段 | |||||
*/ | |||||
@Data | |||||
public class POPropertieValue extends POPropertie { | |||||
private Object value; | |||||
public POPropertieValue(POPropertie p, Object value) { | |||||
super(p.getFieldName(), p.getFieldNameByDB(), p.getField(), p.getJavaType(),p.getDbType() | |||||
, p.getOrderByStatus(), p.getOrderByIndex(), p.isPrimarykey()); | |||||
this.value = value; | |||||
} | |||||
} |
@@ -0,0 +1,61 @@ | |||||
package com.qmrz.mybatis; | |||||
import org.springframework.cglib.proxy.Enhancer; | |||||
import org.springframework.cglib.proxy.MethodInterceptor; | |||||
import org.springframework.cglib.proxy.MethodProxy; | |||||
import java.lang.reflect.Method; | |||||
import java.lang.reflect.ParameterizedType; | |||||
import java.util.*; | |||||
/** | |||||
* 实体代理类,用于监控实体属性的变化 | |||||
*/ | |||||
public class POProxy implements MethodInterceptor { | |||||
private Enhancer enhancer = new Enhancer(); | |||||
private Class<?> classPO; | |||||
private Map<String, Object> setList = new LinkedHashMap<>(); | |||||
public Class<?> getClassPO() { | |||||
return classPO; | |||||
} | |||||
public Map<String, Object> getSetList() { | |||||
return setList; | |||||
} | |||||
/** | |||||
* 创建代理 | |||||
* @param classPO | |||||
* @param <T> | |||||
* @return | |||||
*/ | |||||
public <T> T getProxy(Class classPO) { | |||||
this.classPO = classPO; | |||||
//设置创建子类的类 | |||||
enhancer.setSuperclass(classPO); | |||||
enhancer.setCallback(this); | |||||
return (T) enhancer.create(); | |||||
} | |||||
/** | |||||
* 监控set属性 | |||||
* @param o | |||||
* @param method | |||||
* @param objects | |||||
* @param methodProxy | |||||
* @return | |||||
* @throws Throwable | |||||
*/ | |||||
@Override | |||||
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { | |||||
String methodName = method.getName().toLowerCase(); | |||||
if (methodName.startsWith("set")) { | |||||
setList.put(methodName.substring(3, methodName.length()), objects[0]); | |||||
} | |||||
//代理类调用父类的方法 | |||||
return methodProxy.invokeSuper(o, objects); | |||||
} | |||||
} |
@@ -0,0 +1,463 @@ | |||||
package com.qmrz.mybatis; | |||||
import com.qmrz.exception.ABException; | |||||
import com.qmrz.mybatis.annotation.*; | |||||
import org.apache.ibatis.reflection.MetaObject; | |||||
import org.apache.ibatis.reflection.SystemMetaObject; | |||||
import java.lang.annotation.Annotation; | |||||
import java.lang.reflect.Field; | |||||
import java.util.*; | |||||
public class POUtil { | |||||
private static final Class<? extends Annotation> AnnotationID = ID.class; | |||||
private static final Class<? extends Annotation> AnnotationDBType = DBType.class; | |||||
private static final Class<? extends Annotation> AnnotationFieldName = FieldName.class; | |||||
private static final Class<? extends Annotation> AnnotationTableName = TableName.class; | |||||
private static final Class<? extends Annotation> AnnotationOrderByDefault = OrderByDefault.class; | |||||
private Class<?> classPO; | |||||
private String tableNameByDB; | |||||
private String schemasNameByDB; | |||||
private List<POPropertie> propertieList; | |||||
private List<POPropertie> propertieListOrderBy; | |||||
private POPropertie primarykey; | |||||
public POUtil(Class<?> classPO) { | |||||
this.classPO = classPO; | |||||
this.loadTableNameByDB(); | |||||
this.loadSchemasNameByDB(); | |||||
this.loadPropertieList(); | |||||
this.loadOrderBy(); | |||||
} | |||||
public String getTableNameByDB() { | |||||
return tableNameByDB; | |||||
} | |||||
public String getSchemasNameByDB() { | |||||
return schemasNameByDB; | |||||
} | |||||
public List<POPropertie> getPropertieList() { | |||||
return propertieList; | |||||
} | |||||
public List<POPropertie> getPropertieListOrderBy() { | |||||
return propertieListOrderBy; | |||||
} | |||||
public POPropertie getPrimarykey() { | |||||
return primarykey; | |||||
} | |||||
private void loadOrderBy() { | |||||
this.propertieListOrderBy = new ArrayList<>(); | |||||
this.propertieList.forEach(item -> { | |||||
if (item.getOrderByStatus() != 0) { | |||||
this.propertieListOrderBy.add(item); | |||||
} | |||||
}); | |||||
Collections.sort(this.propertieListOrderBy, new Comparator<POPropertie>() { | |||||
@Override | |||||
public int compare(POPropertie o1, POPropertie o2) { | |||||
if (o1.getOrderByIndex() < o2.getOrderByIndex()) { | |||||
return -1; | |||||
} else if (o1.getOrderByIndex() == o2.getOrderByIndex()) { | |||||
return 0; | |||||
} else { | |||||
return 1; | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
/** | |||||
* 写入参数,insert和update时的参数,不包含主键 和 为null | |||||
* | |||||
* @param po | |||||
* @return | |||||
*/ | |||||
// public Map<String, Object> getParamWriteNotNull(Object po) { | |||||
// Map<String, Object> param = new LinkedHashMap<>(); | |||||
// getPropertieNotNull(po).forEach(item -> { | |||||
// param.put(item.getFieldName(), item.getValue()); | |||||
// }); | |||||
// return param; | |||||
// } | |||||
/** | |||||
* 实体转map,若实体对象在当前实体结构中不存在,则不加入map | |||||
* | |||||
* @param po | |||||
* @return | |||||
*/ | |||||
public Map<String, Object> getParam(Object po) { | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
MetaObject mo = SystemMetaObject.forObject(po); | |||||
List<String> names = Arrays.asList(mo.getGetterNames()); | |||||
getPropertieList().forEach(item -> { | |||||
String dbname = item.getFieldNameByDB(); | |||||
if (names.contains(dbname)) { | |||||
param.put(dbname, mo.getValue(dbname)); | |||||
} | |||||
}); | |||||
return param; | |||||
} | |||||
/** | |||||
* @param paramPrimaryKey 实体(里面存储key字段) | |||||
* @return | |||||
*/ | |||||
public Map<String, Object> getParamPrimaryKey(Object paramPrimaryKey) { | |||||
MetaObject msObject = SystemMetaObject.forObject(paramPrimaryKey); | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
param.put(this.primarykey.getFieldNameByDB() | |||||
, msObject.getValue(this.primarykey.getFieldName())); | |||||
return param; | |||||
} | |||||
public Map<String, Object> getParamPrimaryKeyByValue(Object value) { | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
param.put(this.primarykey.getFieldNameByDB() | |||||
, value); | |||||
return param; | |||||
} | |||||
public Object getValueByPrimaryKey(Object objectPO) { | |||||
MetaObject msObject = SystemMetaObject.forObject(objectPO); | |||||
return msObject.getValue(this.primarykey.getFieldName()); | |||||
} | |||||
// /** | |||||
// * 写入参数,insert和update时的参数,不包含主键 和 为null | |||||
// * | |||||
// * @return | |||||
// */ | |||||
// public Map<String, Object> getParamWriteNotNull(Object po) { | |||||
// MetaObject msObject = SystemMetaObject.forObject(po); | |||||
// Map<String, Object> param = new LinkedHashMap<>(); | |||||
// | |||||
// for (POPropertie item : this.getPropertieList()) { | |||||
// if (item.isPrimarykey()) { | |||||
// continue; | |||||
// } | |||||
// | |||||
// Object val = msObject.getValue(item.getFieldName()); | |||||
// if (val == null) { | |||||
// continue; | |||||
// } | |||||
// | |||||
// param.put(item.getFieldName(), val); | |||||
// } | |||||
// return param; | |||||
// } | |||||
/** | |||||
* 获取所有非null属性(不含主键、含属性值) | |||||
* | |||||
* @param po | |||||
* @return | |||||
*/ | |||||
// public List<POPropertieValue> getPropertieNotNull(Object po) { | |||||
// List<POPropertieValue> fieldList = new ArrayList<>(); | |||||
// MetaObject msObject = SystemMetaObject.forObject(po); | |||||
// | |||||
// for (POPropertie propertie : this.propertieList) { | |||||
// if (propertie.isPrimarykey()) { | |||||
// continue; | |||||
// } | |||||
// Object fieldValue = msObject.getValue(propertie.getFieldName()); | |||||
// if (fieldValue == null) { | |||||
// continue; | |||||
// } | |||||
// fieldList.add(new POPropertieValue(propertie, fieldValue)); | |||||
// } | |||||
// return fieldList; | |||||
// } | |||||
/** | |||||
* Object转map | |||||
* | |||||
* @param po | |||||
* @return | |||||
*/ | |||||
public static Map<String, Object> getMap(Object po) { | |||||
List<POPropertieValue> fieldList = new ArrayList<>(); | |||||
MetaObject msObject = SystemMetaObject.forObject(po); | |||||
Field[] fields = po.getClass().getDeclaredFields(); | |||||
Map<String, Object> result = new LinkedHashMap<>(); | |||||
for (Field field : fields) { | |||||
result.put(field.getName(), msObject.getValue(field.getName())); | |||||
} | |||||
return result; | |||||
} | |||||
// public Map<String, Object> getMapNotNull(Object po) { | |||||
// List<POPropertieValue> fieldList = new ArrayList<>(); | |||||
// MetaObject msObject = SystemMetaObject.forObject(po); | |||||
// | |||||
// Map<String, Object> result = new LinkedHashMap<>(); | |||||
// for (POPropertie item : this.propertieList) { | |||||
// Object val = msObject.getValue(item.getFieldName()); | |||||
// if (val == null) { | |||||
// continue; | |||||
// } | |||||
// if (item.isPrimarykey()) { | |||||
// continue; | |||||
// } | |||||
// result.put(item.getFieldName(), val); | |||||
// } | |||||
// | |||||
// return result; | |||||
// } | |||||
/** | |||||
* 填充实体数据,将object 属性填充到 objectProxy | |||||
* | |||||
* @param objectProxy | |||||
* @param object | |||||
*/ | |||||
public static void fillNotNull(BasePO objectProxy, Object object, boolean isAllowNull) { | |||||
List<POPropertieValue> fieldList = new ArrayList<>(); | |||||
MetaObject msObjectProxy = SystemMetaObject.forObject(objectProxy); | |||||
MetaObject msObject = SystemMetaObject.forObject(object); | |||||
for (Field field : objectProxy._getProxy().getClassPO().getDeclaredFields()) { | |||||
if (!msObject.hasGetter(field.getName())) { | |||||
continue; | |||||
} | |||||
Object obj = msObject.getValue(field.getName()); | |||||
if (obj == null) { | |||||
if (isAllowNull) { | |||||
continue; | |||||
} else { | |||||
//若object有属性,则必须不能为null | |||||
throw new ABException(field.getName() + "不允许为空"); | |||||
} | |||||
} | |||||
msObjectProxy.setValue(field.getName(), obj); | |||||
} | |||||
} | |||||
public static void fillNotNull(BasePO objectProxy, Object object, String[] fieldNameList, boolean isAllowNull) { | |||||
List<POPropertieValue> fieldList = new ArrayList<>(); | |||||
MetaObject msObjectProxy = SystemMetaObject.forObject(objectProxy); | |||||
MetaObject msObject = SystemMetaObject.forObject(object); | |||||
for (String fieldName : fieldNameList) { | |||||
if (!msObject.hasGetter(fieldName)) { | |||||
continue; | |||||
} | |||||
Object obj = msObject.getValue(fieldName); | |||||
if (obj == null) { | |||||
if (isAllowNull) { | |||||
continue; | |||||
} else { | |||||
//若object有属性,则必须不能为null | |||||
throw new ABException(fieldName + "不允许为空"); | |||||
} | |||||
} | |||||
msObjectProxy.setValue(fieldName, obj); | |||||
} | |||||
} | |||||
/** | |||||
* 只返回指定参数 | |||||
* | |||||
* @param po | |||||
* @param names | |||||
* @return | |||||
*/ | |||||
public static Map<String, Object> getMapByNames(Object po, String... names) { | |||||
Map<String, Object> result = new LinkedHashMap<>(); | |||||
if (po == null) { | |||||
return result; | |||||
} | |||||
MetaObject msObject = SystemMetaObject.forObject(po); | |||||
for (String name : names) { | |||||
result.put(name, msObject.getValue(name)); | |||||
} | |||||
return result; | |||||
} | |||||
/** | |||||
* 只返回指定参数 | |||||
* | |||||
* @param list | |||||
* @param names | |||||
* @return | |||||
*/ | |||||
public static List<Map<String, Object>> getListMapByNames(List list, String... names) { | |||||
List<Map<String, Object>> result = new ArrayList<>(); | |||||
for (Object o : list) { | |||||
result.add(getMapByNames(o, names)); | |||||
} | |||||
return result; | |||||
} | |||||
/** | |||||
* 获取所有属性(不含值) | |||||
* | |||||
* @return | |||||
*/ | |||||
public void loadPropertieList() { | |||||
this.propertieList = new ArrayList<>(); | |||||
Field[] fields = classPO.getDeclaredFields(); | |||||
// POPropertie propID = null; | |||||
POPropertie propIDTmp = null; | |||||
boolean hasOrderBy = false;//是否有指定排序注解,若没有默认主键降序排序 | |||||
for (Field field : fields) { | |||||
String fieldName = field.getName(); | |||||
String fieldNameByDB = getFieldNameByDB(field); | |||||
//获取order by | |||||
int orderByStatus = 0; | |||||
int orderByIndex = 0; | |||||
if (field.isAnnotationPresent(AnnotationOrderByDefault)) { | |||||
OrderByDefault orderByDefault | |||||
= ((OrderByDefault) field.getAnnotation(AnnotationOrderByDefault)); | |||||
boolean isasc = orderByDefault.isasc(); | |||||
if (isasc) { | |||||
orderByStatus = 1; | |||||
} else { | |||||
orderByStatus = 2; | |||||
} | |||||
orderByIndex = orderByDefault.index(); | |||||
hasOrderBy = true; | |||||
} | |||||
//验证是否主键 | |||||
boolean isPrimarykey = false; | |||||
if (field.isAnnotationPresent(AnnotationID)) { | |||||
if (this.primarykey != null) { | |||||
throw new ABException("发现有多个 @ID 注释"); | |||||
} | |||||
isPrimarykey = true; | |||||
} | |||||
String dbType = null; | |||||
if (field.isAnnotationPresent(AnnotationDBType)) { | |||||
dbType = ((DBType) field.getAnnotation(AnnotationDBType)).type(); | |||||
} | |||||
POPropertie p = new POPropertie(fieldName, fieldNameByDB, field, field.getType(), dbType | |||||
, orderByStatus, orderByIndex, isPrimarykey); | |||||
if (isPrimarykey) { | |||||
this.primarykey = p; | |||||
} | |||||
if ("id".equals(fieldName)) { | |||||
p.setPrimarykey(true); | |||||
propIDTmp = p; | |||||
} | |||||
this.propertieList.add(p); | |||||
} | |||||
if (this.primarykey == null) { | |||||
if (propIDTmp == null) { | |||||
if (tableNameByDB.length() >= 4 && "view".equals(tableNameByDB.substring(tableNameByDB.length() - 4))) { | |||||
this.primarykey = new POPropertie(null, null, null, null, null, 1, 1, false); | |||||
} else { | |||||
throw new ABException("必须指定主键:" + this.classPO.getName()); | |||||
} | |||||
}else{ | |||||
this.primarykey = propIDTmp; | |||||
} | |||||
} | |||||
//若没有指定排序,则按主键降序排序 | |||||
if (!hasOrderBy) { | |||||
this.primarykey.setOrderByStatus(2); | |||||
this.primarykey.setOrderByIndex(0); | |||||
} | |||||
} | |||||
public POPropertie getPropertieByName(String name) { | |||||
for (POPropertie item : this.propertieList) { | |||||
if (name.equals(item.getFieldName())) { | |||||
return item; | |||||
} | |||||
} | |||||
throw new ABException("找不到字段:" + this.classPO.getName() + ":" + name); | |||||
} | |||||
/** | |||||
* 获取数据库字段名 | |||||
* | |||||
* @param field | |||||
* @return | |||||
*/ | |||||
public static String getFieldNameByDB(Field field) { | |||||
String fieldNameByDB; | |||||
if (field.isAnnotationPresent(AnnotationFieldName)) { | |||||
fieldNameByDB = ((FieldName) field.getAnnotation(AnnotationFieldName)).name(); | |||||
} else { | |||||
fieldNameByDB = field.getName(); | |||||
} | |||||
return fieldNameByDB; | |||||
} | |||||
// private static boolean getFieldOrderyByDefault(Field field) { | |||||
// if (!field.isAnnotationPresent(AnnotationOrderByDefault)) { | |||||
// return false; | |||||
// } | |||||
// | |||||
// boolean isasc = ((OrderByDefault) field.getAnnotation(AnnotationOrderByDefault)).isasc(); | |||||
// return getFieldNameByDB(field) + (isasc ? " asc" : " desc"); | |||||
// } | |||||
/** | |||||
* 获取数据库表名 | |||||
* | |||||
* @return | |||||
*/ | |||||
private void loadTableNameByDB() { | |||||
if (classPO.isAnnotationPresent(AnnotationTableName)) { | |||||
this.tableNameByDB = ((TableName) classPO.getAnnotation(AnnotationTableName)).name(); | |||||
return; | |||||
} | |||||
String tableName = classPO.getSimpleName().toLowerCase(); | |||||
if (tableName.lastIndexOf("po") > 0) { | |||||
tableName = tableName.substring(0, tableName.length() - 2); | |||||
} | |||||
this.tableNameByDB = tableName; | |||||
} | |||||
private void loadSchemasNameByDB() { | |||||
if (classPO.isAnnotationPresent(AnnotationTableName)) { | |||||
this.schemasNameByDB = ((TableName) classPO.getAnnotation(AnnotationTableName)).schemasName(); | |||||
return; | |||||
} | |||||
this.schemasNameByDB = ""; | |||||
} | |||||
// /** | |||||
// * 是否有该注解 | |||||
// * | |||||
// * @param annotationClass | |||||
// * @return | |||||
// */ | |||||
// public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { | |||||
// boolean result = false; | |||||
// if (field != null) { | |||||
// result = field.isAnnotationPresent(annotationClass); | |||||
// } | |||||
// if (!result && setter != null) { | |||||
// result = setter.isAnnotationPresent(annotationClass); | |||||
// } | |||||
// if (!result && getter != null) { | |||||
// result = getter.isAnnotationPresent(annotationClass); | |||||
// } | |||||
// return result; | |||||
// } | |||||
} |
@@ -0,0 +1,344 @@ | |||||
package com.qmrz.mybatis; | |||||
import com.qmrz.exception.ABException; | |||||
import org.apache.commons.lang.StringUtils; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.List; | |||||
public class SqlUtil { | |||||
private PO po; | |||||
private POUtil poUtil; | |||||
public SqlUtil(Class<?> entityClass) { | |||||
po = new PO(); | |||||
poUtil = new POUtil(entityClass); | |||||
po.setEntityClass(entityClass); | |||||
po.setFieldList(poUtil.getPropertieList()); | |||||
po.setTableNameByDB(poUtil.getTableNameByDB()); | |||||
po.setSchemasName(poUtil.getSchemasNameByDB()); | |||||
if (po.getFieldList().size() == 0) { | |||||
throw new ABException("没有字段"); | |||||
} | |||||
} | |||||
public StringBuilder selectAllColumns() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
List<String> list = new ArrayList<>(); | |||||
sql.append("select "); | |||||
po.getFieldList().forEach( | |||||
item -> list.add(fieldDBSelect(item)) | |||||
); | |||||
sql.append(StringUtils.join(list.toArray(), ",")); | |||||
return sql; | |||||
} | |||||
public StringBuilder selectCount(String fieldName) { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append("select count(").append(fieldName).append(") as _count"); | |||||
return sql; | |||||
} | |||||
public StringBuilder selectCount() { | |||||
return selectCount(poUtil.getPrimarykey().getFieldNameByDB()); | |||||
} | |||||
// private String getAllFieldStr() { | |||||
// List<POPropertie> properties = po.getFieldList(); | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// properties.forEach( | |||||
// item -> sql.append(item.getFieldNameByDB()).append(",") | |||||
// ); | |||||
// | |||||
// return sql.substring(0, sql.length() - 1); | |||||
// } | |||||
private String getOrderByStr() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
poUtil.getPropertieListOrderBy().forEach(item -> { | |||||
int orderByStatus = item.getOrderByStatus(); | |||||
String str = ""; | |||||
if (orderByStatus == 1) { | |||||
str = " asc"; | |||||
} else if (orderByStatus == 2) { | |||||
str = " desc"; | |||||
} | |||||
if (str.length() > 0) { | |||||
sql.append(item.getFieldNameByDB()).append(str).append(","); | |||||
} | |||||
}); | |||||
if (sql.length() > 0) { | |||||
return sql.substring(0, sql.length() - 1); | |||||
//return " order by " + str; | |||||
} | |||||
return ""; | |||||
} | |||||
public StringBuilder fromTable() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(" from "); | |||||
sql.append(po.getTableNameByDBAll()); | |||||
return sql; | |||||
} | |||||
public String whereByPrimaryKeyXML() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(" <where>"); | |||||
List<POPropertie> properties = po.getFieldList(); | |||||
sql.append(poUtil.getPrimarykey().getFieldNameByDB() | |||||
+ "=#{" + poUtil.getPrimarykey().getFieldName() + "}"); | |||||
sql.append("</where>"); | |||||
return sql.toString(); | |||||
} | |||||
public String whereByPrimaryKey() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
List<POPropertie> properties = po.getFieldList(); | |||||
sql.append(" where "); | |||||
sql.append(poUtil.getPrimarykey().getFieldNameByDB() | |||||
+ "=#{" + poUtil.getPrimarykey().getFieldName() + "}"); | |||||
return sql.toString(); | |||||
} | |||||
public String whereNotNullXML() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(" <where>"); | |||||
List<POPropertie> properties = po.getFieldList(); | |||||
for (POPropertie column : properties) { | |||||
sql.append(ifNotNullXML(column, column.getFieldNameByDB() + "=#{" + column.getFieldName() + "}")); | |||||
} | |||||
sql.append("</where>"); | |||||
return sql.toString(); | |||||
} | |||||
public String whereXML() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(" <where>"); | |||||
List<POPropertie> properties = po.getFieldList(); | |||||
for (POPropertie column : properties) { | |||||
sql.append(" and " + column.getFieldNameByDB() + "=#{" + column.getFieldName() + "}"); | |||||
} | |||||
sql.append("</where>"); | |||||
return sql.toString(); | |||||
} | |||||
// public String where() { | |||||
// StringBuilder sql = new StringBuilder(); | |||||
// sql.append(" where "); | |||||
// List<POPropertie> properties = po.getFieldList(); | |||||
// | |||||
// List<String> list = new ArrayList<>(); | |||||
// for (POPropertie column : properties) { | |||||
// list.add(column.getFieldNameByDB() + "=#{" + column.getFieldName() + "}"); | |||||
// } | |||||
// sql.append(StringUtils.join(list.toArray()," and ")); | |||||
// return sql.toString(); | |||||
// } | |||||
public StringBuilder whereByParam(Collection<String> param) { | |||||
StringBuilder sql = new StringBuilder(); | |||||
if (param.size() > 0) { | |||||
sql.append(" where "); | |||||
} | |||||
List<String> list = new ArrayList<>(); | |||||
for (String column : param) { | |||||
POPropertie info = poUtil.getPropertieByName(column); | |||||
list.add(info.getFieldNameByDB() + "=#{" + column + "}"); | |||||
} | |||||
sql.append(StringUtils.join(list.toArray(), " and ")); | |||||
return sql; | |||||
} | |||||
/** | |||||
* 不支持查询字符串为空的数据,若要查询,请使用wrapper | |||||
* | |||||
* @param column | |||||
* @param contents | |||||
* @return | |||||
*/ | |||||
private String ifNotNullXML(POPropertie column, String contents) { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(" <if test=\""); | |||||
sql.append(column.getFieldName()).append(" != null"); | |||||
if (column.getJavaType().equals(String.class)) {//若是字符串,则验证是否为"" | |||||
sql.append(" and "); | |||||
sql.append(column.getFieldName()).append(" != '' "); | |||||
} | |||||
sql.append("\">"); | |||||
sql.append(contents); | |||||
sql.append("</if>"); | |||||
return sql.toString(); | |||||
} | |||||
public StringBuilder orderByDefault() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
String orderBy = getOrderByStr(); | |||||
if (orderBy.length() == 0) { | |||||
return sql; | |||||
} | |||||
sql.append(" order by "); | |||||
sql.append(orderBy); | |||||
return sql; | |||||
} | |||||
public String updateSetNotNullXML() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append("update ").append(po.getTableNameByDB()).append(" <set>"); | |||||
poUtil.getPropertieList().forEach(item -> { | |||||
if (!item.isPrimarykey()) { | |||||
sql.append(ifNotNullXML(item, item.getFieldNameByDB() + "=" + fieldDBWrite(item) + ",")); | |||||
} | |||||
}); | |||||
sql.append("</set>"); | |||||
return sql.toString(); | |||||
} | |||||
public StringBuilder updateSet(Collection<String> paramUpdateSet) { | |||||
StringBuilder sql = new StringBuilder(); | |||||
List<String> list = new ArrayList<>(); | |||||
sql.append("update ").append(po.getTableNameByDB()).append(" set "); | |||||
paramUpdateSet.forEach( | |||||
item -> { | |||||
POPropertie info = poUtil.getPropertieByName(item); | |||||
list.add(info.getFieldNameByDB() + "=" + fieldDBWrite(info)); | |||||
} | |||||
); | |||||
sql.append(StringUtils.join(list.toArray(), ",")); | |||||
return sql; | |||||
} | |||||
public StringBuilder insert(Collection<String> paramUpdateSet) { | |||||
List<String> fields = new ArrayList<>(); | |||||
List<String> values = new ArrayList<>(); | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append("insert into ").append(po.getTableNameByDB()).append("("); | |||||
paramUpdateSet.forEach( | |||||
item -> { | |||||
POPropertie info = poUtil.getPropertieByName(item); | |||||
fields.add(info.getFieldNameByDB()); | |||||
} | |||||
); | |||||
sql.append(StringUtils.join(fields.toArray(), ",")); | |||||
sql.append(") values( "); | |||||
paramUpdateSet.forEach( | |||||
item -> { | |||||
POPropertie info = poUtil.getPropertieByName(item); | |||||
values.add(fieldDBWrite(info)); | |||||
} | |||||
); | |||||
sql.append(StringUtils.join(values.toArray(), ",")); | |||||
sql.append(")"); | |||||
return sql; | |||||
} | |||||
public StringBuilder deleteFrom() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append("delete from "); | |||||
sql.append(po.getTableNameByDBAll()); | |||||
return sql; | |||||
} | |||||
public String insertNotNullXML() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append("insert into ").append(po.getTableNameByDB()).append(" ("); | |||||
sql.append("<trim suffixOverrides=\",\">"); | |||||
poUtil.getPropertieList().forEach(item -> { | |||||
if (!item.isPrimarykey()) { | |||||
sql.append(ifNotNullXML(item, item.getFieldNameByDB() + ",")); | |||||
} | |||||
}); | |||||
sql.append("</trim>"); | |||||
sql.append(") values ("); | |||||
sql.append("<trim suffixOverrides=\",\">"); | |||||
poUtil.getPropertieList().forEach(item -> { | |||||
if (!item.isPrimarykey()) { | |||||
sql.append(ifNotNullXML(item, fieldDBWrite(item) + ",")); | |||||
} | |||||
}); | |||||
sql.append("</trim>"); | |||||
sql.append(")"); | |||||
return sql.toString(); | |||||
} | |||||
/** | |||||
* 写入字段处理 | |||||
* | |||||
* @param item | |||||
* @return | |||||
*/ | |||||
private String fieldDBWrite(POPropertie item) { | |||||
String name = "#{" + item.getFieldName() + "}"; | |||||
if (!StringUtils.isEmpty(item.getDbType())) { | |||||
if ("datetime".equals(item.getDbType())) { | |||||
name = "from_unixtime(#{" + item.getFieldName() + "})"; | |||||
} | |||||
} | |||||
return name; | |||||
} | |||||
/** | |||||
* 读取时字段处理 | |||||
* | |||||
* @param item | |||||
* @return | |||||
*/ | |||||
private String fieldDBSelect(POPropertie item) { | |||||
String name = item.getFieldNameByDB(); | |||||
if (!StringUtils.isEmpty(item.getDbType())) { | |||||
if ("datetime".equals(item.getDbType())) { | |||||
name = "unix_timestamp(" + item.getFieldNameByDB() + ") as " + item.getFieldName(); | |||||
} | |||||
} else { | |||||
if (!item.getFieldName().equals(item.getFieldNameByDB())) { | |||||
name = item.getFieldNameByDB() + " as " + item.getFieldName(); | |||||
} | |||||
} | |||||
return name; | |||||
} | |||||
public String limit(int limit) { | |||||
return " limit " + limit; | |||||
} | |||||
public String limit(int startIndex, int limit) { | |||||
return " limit " + startIndex + "," + limit; | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
package com.qmrz.mybatis.annotation; | |||||
import java.lang.annotation.ElementType; | |||||
import java.lang.annotation.Retention; | |||||
import java.lang.annotation.RetentionPolicy; | |||||
import java.lang.annotation.Target; | |||||
@Target(ElementType.FIELD) | |||||
@Retention(RetentionPolicy.RUNTIME) | |||||
public @interface DBType { | |||||
String type(); | |||||
} |
@@ -0,0 +1,9 @@ | |||||
package com.qmrz.mybatis.annotation; | |||||
import java.lang.annotation.*; | |||||
@Target(ElementType.FIELD) | |||||
@Retention(RetentionPolicy.RUNTIME) | |||||
public @interface FieldName { | |||||
String name() default ""; | |||||
} |
@@ -0,0 +1,12 @@ | |||||
package com.qmrz.mybatis.annotation; | |||||
import java.lang.annotation.ElementType; | |||||
import java.lang.annotation.Retention; | |||||
import java.lang.annotation.RetentionPolicy; | |||||
import java.lang.annotation.Target; | |||||
@Target(ElementType.FIELD) | |||||
@Retention(RetentionPolicy.RUNTIME) | |||||
public @interface ID { | |||||
} |
@@ -0,0 +1,13 @@ | |||||
package com.qmrz.mybatis.annotation; | |||||
import java.lang.annotation.ElementType; | |||||
import java.lang.annotation.Retention; | |||||
import java.lang.annotation.RetentionPolicy; | |||||
import java.lang.annotation.Target; | |||||
@Target(ElementType.FIELD) | |||||
@Retention(RetentionPolicy.RUNTIME) | |||||
public @interface OrderByDefault { | |||||
boolean isasc() default false; | |||||
int index(); | |||||
} |
@@ -0,0 +1,13 @@ | |||||
package com.qmrz.mybatis.annotation; | |||||
import java.lang.annotation.ElementType; | |||||
import java.lang.annotation.Retention; | |||||
import java.lang.annotation.RetentionPolicy; | |||||
import java.lang.annotation.Target; | |||||
@Target(ElementType.TYPE) | |||||
@Retention(RetentionPolicy.RUNTIME) | |||||
public @interface TableName { | |||||
String name() default ""; | |||||
String schemasName() default ""; | |||||
} |
@@ -0,0 +1,91 @@ | |||||
package com.qmrz.mybatis.service; | |||||
import com.qmrz.mybatis.BasePO; | |||||
import com.qmrz.mybatis.Mapper; | |||||
import com.qmrz.mybatis.sql.BaseWrapper; | |||||
import com.qmrz.mybatis.sql.sqlnode.UpdateParam; | |||||
import java.util.List; | |||||
import java.util.function.Consumer; | |||||
public abstract class AbstractService<T extends BasePO> implements BaseService<T> { | |||||
private Mapper<T> baseMapper; | |||||
public AbstractService(Mapper<T> baseMapper){ | |||||
this.baseMapper = baseMapper; | |||||
} | |||||
public void setBaseMapper(Mapper<T> baseMapper) { | |||||
this.baseMapper = baseMapper; | |||||
} | |||||
@Override | |||||
public List<T> selectWrapper(Consumer<? super BaseWrapper> wrapper) { | |||||
return baseMapper.selectWrapper(wrapper); | |||||
} | |||||
@Override | |||||
public T selectOneWrapper(Consumer<? super BaseWrapper> wrapper) { | |||||
return baseMapper.selectOneWrapper(wrapper); | |||||
} | |||||
@Override | |||||
public Integer updateWrapper(Object param, Consumer<? super BaseWrapper> wrapper) { | |||||
return baseMapper.updateWrapper(param, wrapper); | |||||
} | |||||
@Override | |||||
public Integer deleteWrapper(Consumer<? super BaseWrapper> wrapper) { | |||||
return baseMapper.deleteWrapper(wrapper); | |||||
} | |||||
@Override | |||||
public List<T> select(Object whereObject) { | |||||
return baseMapper.select(whereObject); | |||||
} | |||||
@Override | |||||
public T selectOne(Object whereObject) { | |||||
return baseMapper.selectOne(whereObject); | |||||
} | |||||
@Override | |||||
public Integer selectCount(Object whereObject) { | |||||
return baseMapper.selectCount(whereObject); | |||||
} | |||||
@Override | |||||
public List<T> selectAll() { | |||||
return baseMapper.selectAll(); | |||||
} | |||||
@Override | |||||
public T selectByPrimaryKey(Object paramPrimaryKey) { | |||||
return baseMapper.selectByPrimaryKey(paramPrimaryKey); | |||||
} | |||||
@Override | |||||
public int deleteByPrimaryKey(Object paramPrimaryKey) { | |||||
return baseMapper.deleteByPrimaryKey(paramPrimaryKey); | |||||
} | |||||
@Override | |||||
public int delete(Object whereObject) { | |||||
return baseMapper.delete(whereObject); | |||||
} | |||||
@Override | |||||
public int insert(T entity) { | |||||
return baseMapper.insert(entity); | |||||
} | |||||
@Override | |||||
public int updateByPrimaryKey(Object paramMap) { | |||||
return baseMapper.updateByPrimaryKey(paramMap); | |||||
} | |||||
@Override | |||||
public int update(UpdateParam updateParam) { | |||||
return baseMapper.update(updateParam); | |||||
} | |||||
} |
@@ -0,0 +1,90 @@ | |||||
package com.qmrz.mybatis.service; | |||||
import com.qmrz.mybatis.sql.BaseWrapper; | |||||
import com.qmrz.mybatis.sql.sqlnode.UpdateParam; | |||||
import java.util.List; | |||||
import java.util.function.Consumer; | |||||
public interface BaseService<T> { | |||||
List<T> selectWrapper(Consumer<? super BaseWrapper> wrapper); | |||||
T selectOneWrapper(Consumer<? super BaseWrapper> wrapper); | |||||
Integer updateWrapper(Object param, Consumer<? super BaseWrapper> wrapper); | |||||
Integer deleteWrapper(Consumer<? super BaseWrapper> wrapper); | |||||
/** | |||||
* 根据实体中的属性值进行查询,查询条件使用等号 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
List<T> select(Object whereObject); | |||||
/** | |||||
* 根据实体中的属性进行查询,只能有一个返回值,有多个结果取第1个 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
T selectOne(Object whereObject); | |||||
/** | |||||
* 根据实体中的属性查询总数,查询条件使用等号 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
Integer selectCount(Object whereObject); | |||||
/** | |||||
* 查询全部结果 | |||||
* | |||||
* @return | |||||
*/ | |||||
List<T> selectAll(); | |||||
/** | |||||
* 根据主键字段进行查询,查询条件使用等号 | |||||
* | |||||
* @param paramPrimaryKey map或实体 | |||||
* @return | |||||
*/ | |||||
T selectByPrimaryKey(Object paramPrimaryKey); | |||||
/** | |||||
* 根据主键字段进行删除,方法参数必须包含完整的主键属性 | |||||
* | |||||
* @param paramPrimaryKey map或实体 | |||||
* @return | |||||
*/ | |||||
int deleteByPrimaryKey(Object paramPrimaryKey); | |||||
/** | |||||
* 根据实体属性作为条件进行删除,查询条件使用等号 | |||||
* | |||||
* @param whereObject map或实体 | |||||
* @return | |||||
*/ | |||||
int delete(Object whereObject); | |||||
/** | |||||
* 保存一个实体,null的属性不会保存,会使用数据库默认值 | |||||
* | |||||
* @param entity map或实体 | |||||
* @return | |||||
*/ | |||||
int insert(T entity); | |||||
/** | |||||
* 根据主键更新实体全部字段,null值不会被更新 | |||||
* | |||||
* @param paramMap map或实体 | |||||
* @return | |||||
*/ | |||||
int updateByPrimaryKey(Object paramMap); | |||||
int update(UpdateParam updateParam); | |||||
} |
@@ -0,0 +1,131 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
import com.qmrz.mybatis.SqlUtil; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* 基础条件接口 | |||||
*/ | |||||
public abstract class AbsWrapperData { | |||||
/** | |||||
* 0:where 1:select 2:from 3:order 5:group 6:limit | |||||
* 20: update set | |||||
* 30: insert | |||||
* 40: delete | |||||
*/ | |||||
private int wrapperStatus = 0; | |||||
/** | |||||
* 当前块里的每个sql片段入栈时的条件组合方式 | |||||
* 0:无 1:and块 2:or块 | |||||
*/ | |||||
private int conditionWhereStatus = 1; | |||||
/** | |||||
* 当前块的条件组合方式 0:无 1:and块 2:or块 | |||||
*/ | |||||
private int wrapperWhereStatus = 1; | |||||
public int getWrapperStatus() { | |||||
return wrapperStatus; | |||||
} | |||||
public int getConditionWhereStatus() { | |||||
return conditionWhereStatus; | |||||
} | |||||
public int getWrapperWhereStatus() { | |||||
return wrapperWhereStatus; | |||||
} | |||||
public abstract StringBuilder getSQL(); | |||||
public StringBuilder getSQLLimit(){ | |||||
return new StringBuilder(); | |||||
} | |||||
public abstract Map<String, Object> getParam(); | |||||
private Class<?> classPO; | |||||
protected SqlUtil sqlUtil; | |||||
/** | |||||
* 总序号 | |||||
*/ | |||||
private int index = 0; | |||||
/** | |||||
* 当前嵌套块的序号 | |||||
*/ | |||||
private int currentIndex = 0; | |||||
protected void setIndex(int index) { | |||||
this.index = index; | |||||
renameByParamName(); | |||||
} | |||||
protected int getIndex() { | |||||
return index; | |||||
} | |||||
protected void setCurrentIndex(int currentIndex) { | |||||
this.currentIndex = currentIndex; | |||||
} | |||||
public AbsWrapperData(int wrapperStatus, int wrapperWhereStatus, int conditionWhereStatus, Class<?> classPO) { | |||||
this.wrapperStatus = wrapperStatus; | |||||
this.wrapperWhereStatus = wrapperWhereStatus; | |||||
this.conditionWhereStatus = conditionWhereStatus; | |||||
this.classPO = classPO; | |||||
this.sqlUtil = new SqlUtil(classPO); | |||||
} | |||||
protected Class<?> getClassPO() { | |||||
return classPO; | |||||
} | |||||
protected abstract void renameByParamName(); | |||||
/** | |||||
* 防止参数重复,重命名增加序号 | |||||
* | |||||
* @param fieldValue | |||||
*/ | |||||
protected void renameByParamName(ConditionGeneralValue fieldValue) { | |||||
fieldValue.setName(fieldValue.getName() + "_" + index); | |||||
} | |||||
protected void renameByParamName(List<ConditionGeneralValue> fieldValue) { | |||||
fieldValue.forEach(item -> item.setName(item.getName() + "_" + index)); | |||||
} | |||||
/** | |||||
* 获取连接符 | |||||
*/ | |||||
public String getLinkStr() { | |||||
String linkStr = " ";//每段sql的连接符,默认使用空格连接 | |||||
if (0 == currentIndex) { | |||||
return linkStr; | |||||
} | |||||
if (0 == this.getWrapperStatus()) {//若where操作 | |||||
Integer whereStatus; | |||||
//是否是块包装器 | |||||
if (this instanceof BaseWrapper) { | |||||
whereStatus = this.getWrapperWhereStatus(); | |||||
} else { | |||||
whereStatus = this.getConditionWhereStatus(); | |||||
} | |||||
if (1 == whereStatus) {//若and | |||||
linkStr = " and "; | |||||
} else if (2 == whereStatus) {//若or | |||||
linkStr = " or "; | |||||
} | |||||
} | |||||
return linkStr; | |||||
} | |||||
} |
@@ -0,0 +1,292 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
import com.qmrz.mybatis.sql.statement.*; | |||||
import java.util.*; | |||||
import java.util.function.Consumer; | |||||
public abstract class BaseWrapper extends AbsWrapperData implements IWrapper { | |||||
/** | |||||
* where 连接状态 | |||||
* 1: and块 | |||||
* 2: or块 | |||||
*/ | |||||
//protected int whereStatus = 1; | |||||
private ConditionCount conditionsCount = new ConditionCount(0); | |||||
private int conditionsCurrentCount = 0; | |||||
private List<AbsWrapperData> conditions = new ArrayList<>(); | |||||
protected void setConditionsCount(ConditionCount conditionsCount) { | |||||
this.conditionsCount = conditionsCount; | |||||
} | |||||
public void addStatement(AbsWrapperData absWrapperData) { | |||||
absWrapperData.setIndex(conditionsCount.getCount()); | |||||
absWrapperData.setCurrentIndex(conditionsCurrentCount); | |||||
conditions.add(absWrapperData); | |||||
conditionsCount.increment(); | |||||
conditionsCurrentCount++; | |||||
} | |||||
public List<AbsWrapperData> getConditions() { | |||||
return conditions; | |||||
} | |||||
public BaseWrapper(int wrapperStatus, int wrapperWhereStatus, int conditionWhereStatus, Class<?> classPO) { | |||||
super(wrapperStatus, wrapperWhereStatus, conditionWhereStatus, classPO); | |||||
// Class<?> classPO = (Class<?>) ((ParameterizedType) (this.getClass().getGenericInterfaces()[0])).getActualTypeArguments()[0]; | |||||
// POUtil.getPropertie(classPO); | |||||
} | |||||
/** | |||||
* 此块的完整sql | |||||
* | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
if (conditions.size() == 0) { | |||||
return sql; | |||||
} | |||||
boolean kuohao = 0 == this.getWrapperStatus() && 0 != this.getWrapperWhereStatus(); | |||||
if (kuohao) {//where的条件时 | |||||
sql.append(this.getLinkStr()).append("("); | |||||
} | |||||
conditions.forEach(item -> { | |||||
if (6 != item.getWrapperStatus()) {//6 limit | |||||
sql.append(item.getSQL()); | |||||
} | |||||
}); | |||||
if (kuohao) {//where时 | |||||
sql.append(")"); | |||||
} | |||||
return sql; | |||||
} | |||||
@Override | |||||
public StringBuilder getSQLLimit() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
if (conditions.size() == 0) { | |||||
return sql; | |||||
} | |||||
conditions.forEach(item -> { | |||||
// System.out.println("getSQLLimit"); | |||||
sql.append(item.getSQLLimit()); | |||||
}); | |||||
return sql; | |||||
} | |||||
/** | |||||
* 此块的所有参数 | |||||
* | |||||
* @return | |||||
*/ | |||||
public Map<String, Object> getParam() { | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
conditions.forEach(item -> { | |||||
if (item.getParam() != null) { | |||||
for (Map.Entry<String, Object> entry : item.getParam().entrySet()) { | |||||
param.put(entry.getKey(), entry.getValue()); | |||||
} | |||||
} | |||||
}); | |||||
return param; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
//块包装器只是块,无参数,无逻辑 | |||||
} | |||||
public BaseWrapper selectAllField() { | |||||
addStatement(new SelectAllField(getClassPO())); | |||||
return this; | |||||
} | |||||
public BaseWrapper update(Map<String, Object> setParam) { | |||||
addStatement(new UpdateSet(getClassPO(), setParam)); | |||||
return this; | |||||
} | |||||
public BaseWrapper delete() { | |||||
addStatement(new DeleteFrom(getClassPO())); | |||||
return this; | |||||
} | |||||
public BaseWrapper from() { | |||||
addStatement(new FromTable(getClassPO())); | |||||
return this; | |||||
} | |||||
public BaseWrapper limit(int limit) { | |||||
addStatement(new Limit(getClassPO(), limit, null)); | |||||
return this; | |||||
} | |||||
public BaseWrapper limit(int limit1, int limit2) { | |||||
addStatement(new Limit(getClassPO(), limit1, limit2)); | |||||
return this; | |||||
} | |||||
public BaseWrapper between(String fieldName, Object fieldValue1, Object fieldValue2) { | |||||
List<ConditionGeneralValue> param = new ArrayList<>(); | |||||
param.add(new ConditionGeneralValue(fieldName + "_between1", fieldValue1)); | |||||
param.add(new ConditionGeneralValue(fieldName + "_between2", fieldValue2)); | |||||
ConditionBetween c = new ConditionBetween(getWrapperWhereStatus() | |||||
, getConditionWhereStatus(), getClassPO()); | |||||
c.setFiedName(fieldName); | |||||
c.setFieldValue(param); | |||||
return addWhere(c); | |||||
} | |||||
public BaseWrapper in(String fieldName, List value) { | |||||
return in(fieldName, value.toArray()); | |||||
} | |||||
public BaseWrapper in(String fieldName, Object ...value) { | |||||
if (value == null || value.length==0) { | |||||
return this; | |||||
} | |||||
List<ConditionGeneralValue> param = new ArrayList<>(); | |||||
for (int i=0;i<value.length;i++) { | |||||
String name=fieldName+"_in_"+String.valueOf(i); | |||||
ConditionGeneralValue val=new ConditionGeneralValue(name,value[i]); | |||||
param.add(val); | |||||
} | |||||
ConditionIn c = new ConditionIn(getWrapperWhereStatus() | |||||
, getConditionWhereStatus(), getClassPO()); | |||||
c.setFiedName(fieldName); | |||||
c.setFieldValue(param); | |||||
return addWhere(c); | |||||
} | |||||
/** | |||||
* @param f 字段名称 | |||||
* @param value | |||||
* @return | |||||
*/ | |||||
public BaseWrapper eq(String f, Object value) { | |||||
return addWhere(f, "_eq", value, "="); | |||||
} | |||||
public BaseWrapper neq(String fieldName, Object value) { | |||||
return addWhere(fieldName, "_neq", value, "<>"); | |||||
} | |||||
public BaseWrapper gt(String fieldName, Object value) { | |||||
return addWhere(fieldName, "_gt", value, ">"); | |||||
} | |||||
public BaseWrapper ge(String fieldName, Object value) { | |||||
return addWhere(fieldName, "_ge", value, ">="); | |||||
} | |||||
public BaseWrapper lt(String fieldName, Object value) { | |||||
return addWhere(fieldName, "_lt", value, "<"); | |||||
} | |||||
public BaseWrapper le(String fieldName, Object value) { | |||||
return addWhere(fieldName, "_le", value, "<="); | |||||
} | |||||
public BaseWrapper or(Consumer<? super BaseWrapper> action) { | |||||
return or(true, action); | |||||
} | |||||
public BaseWrapper orderByDefault() { | |||||
addStatement(new OrderByDefault(getClassPO())); | |||||
return this; | |||||
} | |||||
public BaseWrapper like(String fieldName, String fieldValue) { | |||||
if (fieldValue == null) { | |||||
return this; | |||||
} | |||||
ConditionLike c = new ConditionLike(this.getWrapperWhereStatus() | |||||
, this.getConditionWhereStatus(), getClassPO()); | |||||
c.setFiedName(fieldName); | |||||
c.setFieldValue(new ConditionGeneralValue(fieldName + "_like", fieldValue)); | |||||
return addWhere(c); | |||||
} | |||||
public BaseWrapper or(boolean isConditionAnd, Consumer<? super BaseWrapper> action) { | |||||
OrBlock w = new OrBlock(isConditionAnd, this.conditionsCount, this.getClassPO()); | |||||
this.addStatement(w); | |||||
action.accept(w);//执行嵌套的链式调用 | |||||
return this; | |||||
} | |||||
public BaseWrapper where() { | |||||
this.addStatement( | |||||
new StrWhere(this.getWrapperWhereStatus(), | |||||
this.getConditionWhereStatus() | |||||
, getClassPO()) | |||||
); | |||||
return this; | |||||
} | |||||
public BaseWrapper and(Consumer<? super BaseWrapper> action) { | |||||
return and(true, action); | |||||
} | |||||
public BaseWrapper and(boolean isConditionAnd, Consumer<? super BaseWrapper> action) { | |||||
AndBlock w = new AndBlock(isConditionAnd, this.conditionsCount, this.getClassPO()); | |||||
this.addStatement(w); | |||||
action.accept(w);//执行嵌套的链式调用 | |||||
return this; | |||||
} | |||||
/** | |||||
* 添加where语句 | |||||
* | |||||
* @param fieldName 参数名 | |||||
* @param paramSuffix 参数后缀 | |||||
* @param fieldValue 参数值 | |||||
* @param condition 操作符 = > < | |||||
* @return | |||||
*/ | |||||
private BaseWrapper addWhere(String fieldName, String paramSuffix, Object fieldValue, String condition) { | |||||
ConditionGeneral c = new ConditionGeneral(this.getWrapperWhereStatus() | |||||
, this.getConditionWhereStatus(), getClassPO()); | |||||
c.setFiedName(fieldName); | |||||
c.setFieldValue(new ConditionGeneralValue(fieldName + paramSuffix, fieldValue)); | |||||
c.setCondition(condition); | |||||
return addWhere(c); | |||||
} | |||||
/** | |||||
* 添加where 条件语句 | |||||
* | |||||
* @param c | |||||
* @return | |||||
*/ | |||||
private BaseWrapper addWhere(AbsWrapperData c) { | |||||
int conditionWhere = this.getConditionWhereStatus(); | |||||
//若只第一次where,则增加一个where包装,使状态conditionWhere进入and/or状态 | |||||
if (conditionWhere != 1 && conditionWhere != 2) {//默认为and | |||||
WhereBlock ab = new WhereBlock(true, conditionsCount, getClassPO()); | |||||
ab.where().addStatement(c); | |||||
this.addStatement(ab); | |||||
return ab; | |||||
} | |||||
this.addStatement(c); | |||||
return this; | |||||
} | |||||
public BaseWrapper notoption() { | |||||
return this; | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
/** | |||||
* 在整个链式(包含 入嵌套和出嵌套 的条件及块的增量统计) | |||||
*/ | |||||
@Data | |||||
@AllArgsConstructor | |||||
public class ConditionCount { | |||||
private Integer count; | |||||
public int increment(){ | |||||
this.count++; | |||||
return this.count; | |||||
} | |||||
} |
@@ -0,0 +1,17 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
@Data | |||||
@AllArgsConstructor | |||||
public class ConditionGeneralValue { | |||||
/** | |||||
* sql参数名称 | |||||
*/ | |||||
private String name; | |||||
/** | |||||
* sql参数值 | |||||
*/ | |||||
private Object value; | |||||
} |
@@ -0,0 +1,4 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
public interface IWrapper { | |||||
} |
@@ -0,0 +1,7 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
public class Wrapper extends BaseWrapper { | |||||
public Wrapper(Class<?> classPO) { | |||||
super(-1, 0, 0,classPO); | |||||
} | |||||
} |
@@ -0,0 +1,44 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
import com.qmrz.mybatis.sql.statement.AndBlock; | |||||
import com.qmrz.mybatis.sql.statement.ConditionGeneral; | |||||
import java.util.*; | |||||
public class WrapperResolve { | |||||
private BaseWrapper wrapper; | |||||
private StringBuffer sql = new StringBuffer(); | |||||
// private List<String> fieldList = new ArrayList<>(); | |||||
private Map<String,Object> paramList = new LinkedHashMap<>(); | |||||
public WrapperResolve(BaseWrapper wrapper) { | |||||
this.wrapper = wrapper; | |||||
} | |||||
public void getSQL() { | |||||
getSQL(wrapper.getConditions()); | |||||
} | |||||
private void getSQL(List<AbsWrapperData> list) { | |||||
if (list.size() == 0) { | |||||
return; | |||||
} | |||||
sql.append("("); | |||||
list.forEach(item -> { | |||||
getSQL(item); | |||||
}); | |||||
sql.append(")"); | |||||
} | |||||
private void getSQL(AbsWrapperData item) { | |||||
if (item instanceof ConditionGeneral) { | |||||
ConditionGeneral c = (ConditionGeneral) item; | |||||
sql.append(item.getSQL()); | |||||
paramList.put(c.getFieldValue().getName(), c.getFieldValue().getValue()); | |||||
} else if (item instanceof BaseWrapper) { | |||||
getSQL(((AndBlock) item).getConditions()); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,23 @@ | |||||
package com.qmrz.mybatis.sql; | |||||
import java.util.List; | |||||
import java.util.function.Consumer; | |||||
public class WrapperUtil { | |||||
public static boolean hasWhere(BaseWrapper w) { | |||||
List<AbsWrapperData> list = w.getConditions(); | |||||
boolean result = false; | |||||
for (AbsWrapperData absWrapperData : list) { | |||||
if (absWrapperData.getWrapperStatus() == 0) { | |||||
result = true; | |||||
break; | |||||
} | |||||
} | |||||
return result; | |||||
} | |||||
public static Consumer<? super BaseWrapper> consumer(Consumer<? super BaseWrapper> w) { | |||||
return w; | |||||
} | |||||
} |
@@ -0,0 +1,304 @@ | |||||
package com.qmrz.mybatis.sql.sqlnode; | |||||
import com.qmrz.exception.ABException; | |||||
import com.qmrz.mybatis.BasePO; | |||||
import com.qmrz.mybatis.SqlUtil; | |||||
import com.qmrz.mybatis.sql.BaseWrapper; | |||||
import com.qmrz.mybatis.sql.Wrapper; | |||||
import com.qmrz.mybatis.sql.WrapperUtil; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.ibatis.binding.MapperMethod; | |||||
import org.apache.ibatis.scripting.xmltags.DynamicContext; | |||||
import org.apache.ibatis.scripting.xmltags.SqlNode; | |||||
import java.util.Map; | |||||
import java.util.function.Consumer; | |||||
@Slf4j | |||||
@SuppressWarnings("unchecked") | |||||
public class SqlNodeWrapper implements SqlNode { | |||||
/** | |||||
* select、update、delete | |||||
*/ | |||||
private String option; | |||||
private Class<?> classPO; | |||||
private SqlUtil sqlUtil; | |||||
public SqlNodeWrapper(Class<?> classPO, String option) { | |||||
this.option = option; | |||||
this.classPO = classPO; | |||||
this.sqlUtil = new SqlUtil(classPO); | |||||
} | |||||
private void applySQL(DynamicContext context, StringBuilder sql, Map<String, Object>... param) { | |||||
context.appendSql(sql.toString()); | |||||
for (Map<String, Object> stringObjectMap : param) { | |||||
stringObjectMap.forEach((k, v) -> | |||||
context.bind(k, v) | |||||
); | |||||
} | |||||
} | |||||
@Override | |||||
public boolean apply(DynamicContext context) { | |||||
if (option.endsWith("Wrapper")) { | |||||
return applyWrapper(context);//包装器模式解析 | |||||
} else { | |||||
return applyGeneral(context);//普通模式解析 | |||||
} | |||||
} | |||||
/** | |||||
* 普通模式解析 | |||||
* | |||||
* @param context | |||||
* @return | |||||
*/ | |||||
public boolean applyGeneral(DynamicContext context) { | |||||
Object param = context.getBindings().get("_parameter"); | |||||
switch (option) { | |||||
case "select": | |||||
select(context); | |||||
break; | |||||
case "selectOne": | |||||
selectOne(context); | |||||
break; | |||||
case "selectCount": | |||||
selectCountResolve(context); | |||||
break; | |||||
case "update": | |||||
updateResolve(context); | |||||
break; | |||||
case "delete": | |||||
deleteResolve(context); | |||||
break; | |||||
case "insert": | |||||
insertResolve(context); | |||||
break; | |||||
} | |||||
return true; | |||||
} | |||||
private void select(DynamicContext context) { | |||||
selectResolve(context, false); | |||||
} | |||||
private void selectOne(DynamicContext context) { | |||||
selectResolve(context, true); | |||||
} | |||||
private void selectResolve(DynamicContext context, boolean isone) { | |||||
Map<String, Object> param = (Map) context.getBindings().get("_parameter"); | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(sqlUtil.selectAllColumns()); | |||||
sql.append(sqlUtil.fromTable()); | |||||
sql.append(sqlUtil.whereByParam(param.keySet())); | |||||
sql.append(sqlUtil.orderByDefault()); | |||||
if (isone) { | |||||
sql.append(" limit 1"); | |||||
} | |||||
applySQL(context, sql, param); | |||||
} | |||||
private void selectCountResolve(DynamicContext context) { | |||||
Map<String, Object> param = (Map) context.getBindings().get("_parameter"); | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(sqlUtil.selectCount()); | |||||
sql.append(sqlUtil.fromTable()); | |||||
sql.append(sqlUtil.whereByParam(param.keySet())); | |||||
applySQL(context, sql, param); | |||||
} | |||||
private void updateResolve(DynamicContext context) { | |||||
UpdateParam updateParam = (UpdateParam) context.getBindings().get("_parameter"); | |||||
Map<String, Object> set = updateParam.getSetData(); | |||||
Map<String, Object> param = (Map<String, Object>) updateParam.getWhereData(); | |||||
if (param.size() == 0) { | |||||
throw new ABException("至少有一个查询条件"); | |||||
} | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(sqlUtil.updateSet(set.keySet())); | |||||
sql.append(sqlUtil.whereByParam(param.keySet())); | |||||
applySQL(context, sql, set, param); | |||||
} | |||||
private void deleteResolve(DynamicContext context) { | |||||
Map<String, Object> param = (Map) context.getBindings().get("_parameter"); | |||||
if (param.size() == 0) { | |||||
throw new ABException("至少有一个查询条件"); | |||||
} | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(sqlUtil.deleteFrom()); | |||||
sql.append(sqlUtil.whereByParam(param.keySet())); | |||||
applySQL(context, sql, param); | |||||
} | |||||
private void insertResolve(DynamicContext context) { | |||||
Object _parameter = context.getBindings().get("_parameter"); | |||||
Map<String, Object> param; | |||||
if (_parameter instanceof BasePO) { | |||||
// param = new POUtil(classPO).getParamWriteNotNull(_parameter); | |||||
param = ((BasePO)_parameter)._getProxy().getSetList(); | |||||
} else { | |||||
param = (Map) _parameter; | |||||
} | |||||
// Map<String, Object> param = (Map) paramObj; | |||||
StringBuilder sql = new StringBuilder(); | |||||
sql.append(sqlUtil.insert(param.keySet())); | |||||
applySQL(context, sql, param); | |||||
} | |||||
/** | |||||
* 包装器模式解析 | |||||
* | |||||
* @param context | |||||
* @return | |||||
*/ | |||||
public boolean applyWrapper(DynamicContext context) { | |||||
log.info("SqlNodeWrapper apply"); | |||||
BaseWrapper w = null; | |||||
switch (option) { | |||||
case "selectWrapper": | |||||
w = selectWrapper(context, false); | |||||
break; | |||||
case "selectOneWrapper": | |||||
w = selectWrapper(context, true); | |||||
break; | |||||
case "updateWrapper": | |||||
w = updateWrapper(context); | |||||
checkWhereWrapper(w); | |||||
break; | |||||
case "deleteWrapper": | |||||
w = deleteWrapper(context); | |||||
checkWhereWrapper(w); | |||||
break; | |||||
case "select": | |||||
// w = deleteWrapper(context); | |||||
//checkWhereWrapper(w); | |||||
break; | |||||
default: | |||||
throw new ABException("功能 " + option + " 未实现"); | |||||
} | |||||
log.info(w.getSQL().toString()); | |||||
log.info(w.getSQLLimit().toString()); | |||||
log.info(String.valueOf(w.getParam())); | |||||
//配置当前查询语句 | |||||
context.appendSql(w.getSQL().toString()); | |||||
context.appendSql(w.getSQLLimit().toString()); | |||||
//配置当前查询参数 | |||||
w.getParam().forEach((k, v) -> context.bind(k, v)); | |||||
return true; | |||||
} | |||||
private void checkWhereWrapper(BaseWrapper w) { | |||||
if (!WrapperUtil.hasWhere(w)) { | |||||
throw new ABException("必须有where条件"); | |||||
} | |||||
} | |||||
/** | |||||
* 查询解析器 | |||||
* | |||||
* @param context | |||||
* @return | |||||
*/ | |||||
private BaseWrapper selectWrapper(DynamicContext context, boolean isone) { | |||||
Object fn = context.getBindings().get("_parameter"); | |||||
BaseWrapper w = new Wrapper(classPO); | |||||
BaseWrapper result = w.selectAllField().from(); | |||||
//执行表达式 | |||||
if (fn != null) { | |||||
((Consumer<? super BaseWrapper>) fn).accept(result); | |||||
} | |||||
result.orderByDefault(); | |||||
if (isone) { | |||||
result.limit(1); | |||||
} | |||||
return w; | |||||
} | |||||
/** | |||||
* 更新解析器 | |||||
* | |||||
* @param context | |||||
* @return | |||||
*/ | |||||
private BaseWrapper updateWrapper(DynamicContext context) { | |||||
Object _parameter = context.getBindings().get("_parameter"); | |||||
Object fn; | |||||
Map<String, Object> paramUpdateSet; | |||||
if (_parameter instanceof UpdateParam) { | |||||
UpdateParam up = (UpdateParam) _parameter; | |||||
fn = up.getWhereData(); | |||||
paramUpdateSet = up.getSetData(); | |||||
} else { | |||||
//获取update的set参数,支持BasePO实体和map | |||||
MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) _parameter; | |||||
Object obj = paramMap.get("param1"); | |||||
if (obj instanceof Map) { | |||||
paramUpdateSet = (Map<String, Object>) obj; | |||||
} else if (obj instanceof BasePO) { | |||||
paramUpdateSet = ((BasePO) obj)._getProxy().getSetList(); | |||||
// new POUtil(obj.getClass()).getParamWriteNotNull(obj); | |||||
} else { | |||||
throw new ABException("参数不合法"); | |||||
} | |||||
fn = paramMap.get("param2"); | |||||
} | |||||
BaseWrapper w = new Wrapper(classPO); | |||||
BaseWrapper result = w.update(paramUpdateSet); | |||||
log.info(String.valueOf(paramUpdateSet)); | |||||
//执行表达式 | |||||
if (fn != null) { | |||||
((Consumer<? super BaseWrapper>) fn).accept(result); | |||||
} | |||||
return w; | |||||
} | |||||
/** | |||||
* 删除解析器 | |||||
* | |||||
* @param context | |||||
* @return | |||||
*/ | |||||
private BaseWrapper deleteWrapper(DynamicContext context) { | |||||
Object fn = context.getBindings().get("_parameter"); | |||||
BaseWrapper w = new Wrapper(classPO); | |||||
BaseWrapper result = w.delete(); | |||||
//执行表达式 | |||||
if (fn != null) { | |||||
((Consumer<? super BaseWrapper>) fn).accept(result); | |||||
} | |||||
return w; | |||||
} | |||||
} |
@@ -0,0 +1,13 @@ | |||||
package com.qmrz.mybatis.sql.sqlnode; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import java.util.Map; | |||||
@Data | |||||
@AllArgsConstructor | |||||
public class UpdateParam { | |||||
private Map<String,Object> setData; | |||||
private Object whereData; | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.BaseWrapper; | |||||
import com.qmrz.mybatis.sql.ConditionCount; | |||||
/** | |||||
* sql: 无,只包装作用 | |||||
*/ | |||||
public class AndBlock extends BaseWrapper { | |||||
/** | |||||
* @param isConditionAnd | |||||
* @param index 嵌套时,序号继承到新块 | |||||
*/ | |||||
public AndBlock(boolean isConditionAnd, ConditionCount index, Class<?> classPO) { | |||||
super(0, 1, isConditionAnd ? 1 : 2, classPO); | |||||
this.setConditionsCount(index); | |||||
} | |||||
} |
@@ -0,0 +1,55 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.exception.ABException; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import com.qmrz.mybatis.sql.ConditionGeneralValue; | |||||
import lombok.Data; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: linkStr a between #{a1} and #{a2} | |||||
*/ | |||||
@Data | |||||
public class ConditionBetween extends AbsWrapperData { | |||||
/** | |||||
* 条件左则字段名 | |||||
*/ | |||||
private String fiedName; | |||||
private List<ConditionGeneralValue> fieldValue; | |||||
public ConditionBetween(int wrapperWhereStatus, int conditionWhereStatus, Class<?> classPO) { | |||||
super(0, wrapperWhereStatus,conditionWhereStatus,classPO); | |||||
} | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
if (fieldValue.size() != 2) { | |||||
throw new ABException("参数个数应该为2,目前是:" + fieldValue.size()); | |||||
} | |||||
return new StringBuilder() | |||||
.append(this.getLinkStr()) | |||||
.append(fiedName).append(" between ") | |||||
.append("#{").append(fieldValue.get(0).getName()).append("}") | |||||
.append(" and ") | |||||
.append("#{").append(fieldValue.get(1).getName()).append("}"); | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
fieldValue.forEach(item->{ | |||||
param.put(item.getName(), item.getValue()); | |||||
}); | |||||
return param; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
this.renameByParamName(fieldValue); | |||||
} | |||||
} |
@@ -0,0 +1,57 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import com.qmrz.mybatis.sql.ConditionGeneralValue; | |||||
import lombok.Data; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: linkStr a=#{a} | |||||
*/ | |||||
@Data | |||||
public class ConditionGeneral extends AbsWrapperData { | |||||
/** | |||||
* 条件左则字段名 | |||||
*/ | |||||
private String fiedName; | |||||
/** | |||||
* 条件右侧参数名,及参数值 | |||||
*/ | |||||
private ConditionGeneralValue fieldValue; | |||||
private String condition; | |||||
public ConditionGeneral(int wrapperWhereStatus, int conditionWhereStatus, Class<?> classPO) { | |||||
super(0, wrapperWhereStatus, conditionWhereStatus, classPO); | |||||
} | |||||
/** | |||||
* 格式 " and/or fieldname=#{paramname}" | |||||
* | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
return new StringBuilder() | |||||
.append(this.getLinkStr()) | |||||
.append(fiedName).append(condition) | |||||
.append("#{").append(fieldValue.getName()).append("}"); | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
// if (fieldValue == null) { | |||||
// return param; | |||||
// } | |||||
param.put(fieldValue.getName(), fieldValue.getValue()); | |||||
return param; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
this.renameByParamName(fieldValue); | |||||
} | |||||
} |
@@ -0,0 +1,56 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import com.qmrz.mybatis.sql.ConditionGeneralValue; | |||||
import lombok.Data; | |||||
import org.apache.commons.lang.StringUtils; | |||||
import java.util.ArrayList; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: linkStr a in(#{a}) | |||||
*/ | |||||
@Data | |||||
public class ConditionIn extends AbsWrapperData { | |||||
/** | |||||
* 条件左则字段名 | |||||
*/ | |||||
private String fiedName; | |||||
private List<ConditionGeneralValue> fieldValue; | |||||
public ConditionIn(int wrapperWhereStatus, int conditionWhereStatus, Class<?> classPO) { | |||||
super(0, wrapperWhereStatus,conditionWhereStatus,classPO); | |||||
} | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
List<String> list = new ArrayList<>(); | |||||
fieldValue.forEach(item->list.add("#{"+item.getName()+"}")); | |||||
StringBuilder sb= new StringBuilder() | |||||
.append(this.getLinkStr()) | |||||
.append(fiedName).append(" in (") | |||||
.append(StringUtils.join(list.toArray(),",")) | |||||
.append(")"); | |||||
return sb; | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
fieldValue.forEach(item->{ | |||||
param.put(item.getName(), item.getValue()); | |||||
}); | |||||
return param; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
this.renameByParamName(fieldValue); | |||||
} | |||||
} |
@@ -0,0 +1,55 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import com.qmrz.mybatis.sql.ConditionGeneralValue; | |||||
import lombok.Data; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: name like concat('%',#{name},'%') | |||||
*/ | |||||
@Data | |||||
public class ConditionLike extends AbsWrapperData { | |||||
/** | |||||
* 条件左则字段名 | |||||
*/ | |||||
private String fiedName; | |||||
/** | |||||
* 条件右侧参数名,及参数值 | |||||
*/ | |||||
private ConditionGeneralValue fieldValue; | |||||
public ConditionLike(int wrapperWhereStatus, int conditionWhereStatus, Class<?> classPO) { | |||||
super(0, wrapperWhereStatus, conditionWhereStatus, classPO); | |||||
} | |||||
/** | |||||
* 格式 " and/or fieldname=#{paramname}" | |||||
* | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
return new StringBuilder() | |||||
.append(this.getLinkStr()) | |||||
.append(fiedName).append(" like") | |||||
.append(" concat('%',#{").append(fieldValue.getName()).append("},'%')"); | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
Map<String, Object> param = new LinkedHashMap<>(); | |||||
if (fieldValue == null) { | |||||
return param; | |||||
} | |||||
param.put(fieldValue.getName(), fieldValue.getValue()); | |||||
return param; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
this.renameByParamName(fieldValue); | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import lombok.Data; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: detele from tableName | |||||
*/ | |||||
@Data | |||||
public class DeleteFrom extends AbsWrapperData { | |||||
private StringBuilder sql; | |||||
public DeleteFrom(Class<?> classPO) { | |||||
super(40, 0, 0, classPO); | |||||
load(); | |||||
} | |||||
private void load(){ | |||||
this.sql = sqlUtil.deleteFrom(); | |||||
} | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
return new StringBuilder().append(this.sql); | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
return null; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import lombok.Data; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: from tableName | |||||
*/ | |||||
@Data | |||||
public class FromTable extends AbsWrapperData { | |||||
private StringBuilder sql; | |||||
public FromTable( Class<?> classPO) { | |||||
super(2, 0, 0, classPO); | |||||
load(); | |||||
} | |||||
private void load(){ | |||||
this.sql = sqlUtil.fromTable(); | |||||
} | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
return new StringBuilder().append(this.sql); | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
return null; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
} | |||||
} |
@@ -0,0 +1,57 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import lombok.Data; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: from tableName | |||||
*/ | |||||
@Data | |||||
public class Limit extends AbsWrapperData { | |||||
private Integer limit1; | |||||
private Integer limit2; | |||||
public Limit(Class<?> classPO, Integer limit1, Integer limit2) { | |||||
super(6, 0, 0, classPO); | |||||
this.limit1 = limit1; | |||||
this.limit2 = limit2; | |||||
load(); | |||||
} | |||||
private void load() { | |||||
} | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
if (limit1 != null && limit2 != null) { | |||||
sql.append(" limit " + limit1 + "," + limit2); | |||||
}else if (limit1 != null) { | |||||
sql.append(" limit " + limit1); | |||||
} | |||||
return sql; | |||||
} | |||||
@Override | |||||
public StringBuilder getSQLLimit() { | |||||
StringBuilder sql = new StringBuilder(); | |||||
if (limit1 != null && limit2 != null) { | |||||
sql.append(" limit " + limit1 + "," + limit2); | |||||
}else if (limit1 != null) { | |||||
sql.append(" limit " + limit1); | |||||
} | |||||
return sql; | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
return null; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.BaseWrapper; | |||||
import com.qmrz.mybatis.sql.ConditionCount; | |||||
/** | |||||
* sql: 无,只包装作用 | |||||
*/ | |||||
public class OrBlock extends BaseWrapper { | |||||
/** | |||||
* @param isConditionAnd | |||||
* @param index 嵌套时,序号继承到新块 | |||||
*/ | |||||
public OrBlock(boolean isConditionAnd, ConditionCount index, Class<?> classPO) { | |||||
super(0, 2, isConditionAnd ? 1 : 2, classPO); | |||||
this.setConditionsCount(index); | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
package com.qmrz.mybatis.sql.statement; | |||||
import com.qmrz.mybatis.sql.AbsWrapperData; | |||||
import lombok.Data; | |||||
import java.util.Map; | |||||
/** | |||||
* sql: order by ... | |||||
*/ | |||||
@Data | |||||
public class OrderByDefault extends AbsWrapperData { | |||||
public OrderByDefault(Class<?> classPO) { | |||||
super(3, 0, 0, classPO); | |||||
load(); | |||||
} | |||||
private void load(){ | |||||
} | |||||
@Override | |||||
public StringBuilder getSQL() { | |||||
return new StringBuilder().append(sqlUtil.orderByDefault()); | |||||
} | |||||
@Override | |||||
public Map<String, Object> getParam() { | |||||
return null; | |||||
} | |||||
@Override | |||||
protected void renameByParamName() { | |||||
} | |||||
} |