Skip to content

Commit

Permalink
v1.1.9
Browse files Browse the repository at this point in the history
  • Loading branch information
veasion committed Oct 28, 2022
1 parent 41a7cf3 commit 139ac3b
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 15 deletions.
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# veasion-db

veasion-db 是一个轻量级持久层db框架,除slf4j-api外不依赖任何第三方jar,该框架提供丰富灵活的数据库操作,
veasion-db 是一个轻量级持久层ORM框架,除slf4j-api外不依赖任何第三方jar,该框架提供丰富灵活的数据库操作,
单元测试 query/update 目录下有大量示例及demo。

框架基本支持sql能实现的任意查询或更新,如关联查询、子查询、关联更新、insert select、不同数据库分页扩展等。
框架无需写任何SQL基本支持sql能实现的任意查询或更新,如关联查询、子查询、关联更新、insert select、不同数据库分页扩展等。

框架支持自定义拦截器,内置逻辑删除拦截器,可通过SPI或调用InterceptorUtils.addInterceptor方法加入扩展。
框架支持自定义拦截器,内置逻辑删除、数据隔离拦截器,可通过SPI或调用InterceptorUtils.addInterceptor方法加入扩展。
## maven 依赖
添加 veasion-db 依赖
```xml
<dependency>
<groupId>cn.veasion</groupId>
<artifactId>veasion-db</artifactId>
<version>1.1.8</version>
<version>1.1.9</version>
</dependency>
```
支持sql解析生成veasion-db代码
Expand All @@ -21,7 +21,7 @@ String sql = "select * from t_student where id = 1";
String code = SQLParseUtils.parseSQLConvert(sql);
// 直接把SQL转换成对应的代码,示例参考单元测试 SqlDbConvertTest
// 该功能为扩展功能需要加入第三方依赖
// 该功能为扩展功能需要加入第三方依赖,示例见单元测试 SqlDbConvertTest
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
Expand Down Expand Up @@ -325,7 +325,24 @@ public class InsertTest extends BaseTest {

### 动态查询机制
支持动态查询机制,可通过配置字段注解提前定义查询方式和动态关联、静态关联表。
非常灵活的实现前端传参后端动态查询,具体参考单元测试 QueryCriteriaTest
非常灵活的实现前端传参后端动态查询,支持后端不需要写任何代码,根据前端传参自动关联表进行各种条件的动态查询
<br><br>
动态查询说明:<br>
前端传 { id: 1 } 自动映射成 id = 1 <br>
前端传 { id: [1, 2, 3] } 自动映射成 id in (1,2,3) <br>
前端传 { start_age: 18 } 自动映射成 age >= 18 <br>
前端传 { end_age: 30 } 自动映射成 age <= 30 <br>
前端传 { name: '罗' } 自动映射成 name = '罗' <br>
前端传 { name: '罗%' } 自动映射成 name like '罗%' <br>
前端传 { name: '%罗%' } 自动映射成 name like '%罗%' <br>

动态关联说明:<br>
有一张学生表 t_student 和一张班级表 t_classes
如果前端传了 className 字段(学生表只有 class_id 关联班级表)就会进行自动关联 t_classes 表去查询,不用写任何代码自动根据参数去动态关联表查询。<br>
前端传 { id: 1 } 自动映射成 select * from t_student where id = 1 <br>
前端传 { id: 1, className: '三年二班' } 自动映射成 select s.* from t_student s join t_classes c on s.class_id = c.id where s.id = 1 and c.name = '三年二班' <br>

具体参考单元测试 QueryCriteriaTest

### spring 项目接入 veasion-db
SPI 实现 cn.veasion.db.jdbc.DataSourceProvider 接口
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<groupId>cn.veasion</groupId>
<artifactId>veasion-db</artifactId>
<version>1.1.8</version>
<version>1.1.9</version>

<name>veasion-db</name>
<url>https://github.com/veasion/veasion-db</url>
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/cn/veasion/db/AbstractFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ public T filterExpression(String field, Operator operator, Expression expression
return addFilters(Filter.expression(field, operator, expression));
}

/**
* SQL过滤
*
* @param sqlFilterHandler 获取SQL接口,参数支持字段处理
* @param values 占位符对应值
*/
public T sqlFilter(Filter.SqlFilterHandler sqlFilterHandler, Object... values) {
return addFilter(Filter.sqlFilter(sqlFilterHandler, values));
}

public List<Filter> getFilters() {
return filters;
}
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/cn/veasion/db/base/Filter.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ public static Filter expression(String field, Operator operator, Expression expr
return build(field, operator, expression, null).special();
}

/**
* SQL过滤
*
* @param sqlFilterHandler 获取SQL接口,参数支持字段处理
* @param values 占位符对应值
*/
public static Filter sqlFilter(SqlFilterHandler sqlFilterHandler, Object... values) {
return new SqlFilter(sqlFilterHandler, values);
}

public static Filter AND = build("AND");
public static Filter OR = build("OR");
public static Filter LEFT_BRACKET = build("(");
Expand Down Expand Up @@ -216,4 +226,52 @@ public String toString() {
}
}

@FunctionalInterface
public interface SqlFilterHandler {
String getSQL(ColumnFieldHandler columnFieldHandler);
}

@FunctionalInterface
public interface ColumnFieldHandler {
String asField(String columnField);
}

public static class SqlFilter extends Filter {

private String tableAs;
private SqlFilterHandler sqlFilterHandler;

private SqlFilter(SqlFilterHandler sqlFilterHandler, Object... values) {
this.sqlFilterHandler = sqlFilterHandler;
if (values != null && values.length > 0) {
super.value = Arrays.asList(values);
}
}

@Override
public String getSql() {
if (tableAs != null) {
return sqlFilterHandler.getSQL(field -> FilterUtils.tableAsField(tableAs, field));
} else {
return sqlFilterHandler.getSQL(field -> field);
}
}

@Override
public SqlFilter fieldAs(String tableAs) {
this.tableAs = tableAs;
return this;
}

@Override
public boolean isSpecial() {
return true;
}

@Override
public String toString() {
return getSql();
}
}

}
10 changes: 10 additions & 0 deletions src/main/java/cn/veasion/db/base/Operator.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,14 @@ public enum Operator {
public String getOpt() {
return opt;
}

public static Operator of(String opt) {
for (Operator value : values()) {
if (value.opt.equalsIgnoreCase(opt)) {
return value;
}
}
return null;
}

}
6 changes: 6 additions & 0 deletions src/main/java/cn/veasion/db/jdbc/AbstractSQL.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ protected void appendFilter(Map<String, Class<?>> entityClassMap, List<Filter> f
sql.append(" ").append(filter.getOperator().getOpt()).append(" ");
Expression expression = (Expression) filter.getValue();
appendExpressionValue(entityClassMap, expression);
} else if (filter instanceof Filter.SqlFilter) {
// sql filter
sql.append(filter.getSql());
if (filter.getValue() instanceof Collection) {
values.addAll((Collection<?>) filter.getValue());
}
} else {
throw new FilterException("不支持过滤器:" + filter);
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/cn/veasion/db/jdbc/InsertSQL.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,13 @@ private void insert(Class<?> entityClazz, List<Map<String, Object>> fieldValueMa
Map<String, String> fieldColumns = FieldUtils.entityFieldColumns(entityClazz);
Set<String> fields = fieldValueMapList.get(0).keySet();

if (source instanceof EntityInsert && ((EntityInsert) source).isReplace()) {
if ((source instanceof EntityInsert && ((EntityInsert) source).isReplace()) ||
(source instanceof BatchEntityInsert && ((BatchEntityInsert) source).isReplace())) {
sql.append("REPLACE INTO ");
} else {
sql.append("INSERT INTO ");
}

sql.append(getTableName(entityClazz, null, source)).append(" (");
for (String field : fields) {
appendInsertColumn(fieldColumns.get(field));
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/cn/veasion/db/parser/DbExpressionVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,23 @@ private void appendVarFun(String s, boolean line) {
private void handleComparisonOperator(ComparisonOperator operator, String opt) {
Expression leftExpression = operator.getLeftExpression();
Expression rightExpression = operator.getRightExpression();
leftRight(leftExpression, opt, rightExpression);

if (leftExpression instanceof Function) {
if (havingFilter) {
appendVarFun("having(", false);
} else if (onFilter) {
appendVarFun("on(", false);
} else {
appendVarFun("addFilter(", false);
}
sb.append("Filter.sqlFilter(fieldHandler -> \"").append(operator.toString()).append("\")");
sb.append(")");
if (!onFilter) {
sb.append(";\r\n");
}
} else {
leftRight(leftExpression, opt, rightExpression);
}
}

private void leftRight(Expression leftExpression, String opt, Expression rightExpression) {
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/cn/veasion/db/parser/DbStatementVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.sf.jsqlparser.statement.StatementVisitorAdapter;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.replace.Replace;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.update.Update;

Expand Down Expand Up @@ -63,6 +64,32 @@ public void visit(Insert insert) {
}
}

@Override
public void visit(Replace replace) {
Table table = replace.getTable();
List<Column> columns = replace.getColumns();
ItemsList itemsList = replace.getItemsList();
String var = SQLParseUtils.getVarByTable(table);
String entity = SQLParseUtils.getByTable(table);
sb.append(entity).append(" ").append(var);
sb.append(" = new ").append(entity).append("();\r\n");
if (columns != null && !columns.isEmpty()) {
for (Column column : columns) {
String fieldSetter = FieldUtils.firstCase(SQLParseUtils.columnToField(column.getColumnName()), false);
sb.append(var).append(".set").append(fieldSetter).append("(null);\r\n");
}
}
sb.append("\r\n");
if (itemsList instanceof MultiExpressionList) {
sb.append("List<").append(entity);
sb.append("> list = new ArrayList<>();\r\n");
sb.append("list.add(").append(var).append(");\r\n");
sb.append("BatchEntityInsert batchInsert = new BatchEntityInsert(list).withReplace();");
} else {
sb.append("EntityInsert insert = new EntityInsert(").append(var).append(").withReplace();");
}
}

@Override
public void visit(Delete delete) {
if (delete.getJoins() != null) {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/cn/veasion/db/update/BatchEntityInsert.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class BatchEntityInsert {
private boolean useGeneratedKeys = true;
private AbstractQuery<?> insertSelectQuery;
private List<Map<String, Object>> fieldValueMapList;
private boolean replace;

public <T> BatchEntityInsert(List<T> entityList) {
this.entityList = Objects.requireNonNull(entityList);
Expand All @@ -49,6 +50,18 @@ public BatchEntityInsert setUseGeneratedKeys(boolean useGeneratedKeys) {
return this;
}

public BatchEntityInsert withReplace() {
if (this.insertSelectQuery != null) {
throw new DbException("insert select 方式不支持 replace");
}
this.replace = true;
return this;
}

public boolean isReplace() {
return replace;
}

public boolean isUseGeneratedKeys() {
return useGeneratedKeys;
}
Expand Down
28 changes: 23 additions & 5 deletions src/test/java/cn/veasion/db/parser/SqlDbConvertTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,56 @@ public static void main(String[] args) {
" where t.age > 0 and t.id in (1,2,3) and (name like '%sss%' or name like 'ss%')" +
" and id <= 0 and user_age <> ifnull(age, 0) and `desc` is not null";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
System.out.println("===============================\r\n");
System.out.println("===============================");

sql = "select s.*, t.name from t_student s, t_classes c left join t_user u " +
"on c.id = u.id and c.id > s.age and c.is_deleted = 0" +
"where s.class_id = c.id and c.id > 0 group by s.user_id, c.id " +
"having count(s.id) > 1 and avg(c.age) >= 18 order by c.create_time desc, s.id " +
"limit 10, 10";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
System.out.println("===============================\r\n");
System.out.println("===============================");

sql = "select id, name, (select age from t_classes where id = t.class_id) as '_age' " +
"from (select id, name from t_student where id > 0) t " +
"where t.id in (select id from t_classes where id > 50) and exists (select 1 from t_user) " +
"union select id, name, age from t_user where id > 0 order by id desc limit 10";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
System.out.println("===============================\r\n");
System.out.println("===============================");

sql = "select * from t_score where ifnull(score, 0) = score + 0";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
System.out.println("===============================");

sql = "replace into t_student(id, name, create_time) values(1, 'test', now())";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
System.out.println("===============================");

sql = "insert into t_student(id, name, create_time) select id, name, now() from t_classes where id > 0";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
System.out.println("===============================\r\n");
System.out.println("===============================");

sql = "delete from t_student where id > 0 and age = ifnull(id, 1)";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
System.out.println("===============================\r\n");
System.out.println("===============================");

sql = "update t_student s, t_classes c set age = 18, c.name = 'sss', c.age = now() where s.class_id = c.id and s.id > 0 and c.id < 10";
System.out.println(sql);
System.out.println();
System.out.println(SQLParseUtils.parseSQLConvert(sql));
}

Expand Down
3 changes: 2 additions & 1 deletion src/test/java/cn/veasion/db/query/OtherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ public static void main(String[] args) {
.select("id")
.selectExpression("ifnull(${id}, ${sno})", "`key`")
.filterExpression("id", Operator.EQ, "${id} + 1")
.sqlFilter(handler -> handler.asField("id") + " > ?", 0)
));
studentDao.update(new EU(StudentPO.class, "t")
.updateExpression("id", "${id}")
.filterExpression("id", Operator.EQ, "${id}")
.lt("id", 5)
.sqlFilter(handler -> handler.asField("id") + " < 5")
);
}

Expand Down

0 comments on commit 139ac3b

Please sign in to comment.