Anterior: ¿Cuál es la diferencia entre el recientemente popular Bean Searcher y MyBatis Plus?
introducir
Bean Searcher es un ORM de solo lectura que se enfoca en consultas avanzadas. Naturalmente, admite tablas conjuntas y evita la conversión DTO/VO, lo que hace posible realizar una recuperación de lista compleja con una línea de código.
Podemos usarlo como un ORM de componente básico , y al mismo tiempo tener una eficiencia de desarrollo cercana al código bajo.
Escenas a utilizar
Bean Searcher aborda requisitos complejos de recuperación no transaccional como:
- Consulta de back-end normal
- Método de búsqueda dinámica
- Consulta de grupo dinámico
En los escenarios anteriores, Bean Searcher puede implementar código back-end con una línea de código.
Pensamiento de diseño (punto de partida)
La razón por la cual la eficiencia del desarrollo se puede mejorar en gran medida
Rendimiento del cuadro
El rendimiento no es el punto de venta principal, pero también es un promedio de 2 a 5 veces mejor que los marcos ORM tradicionales (rendimiento de la capa Java)
Detalles: gitee.com/troyzhxu/be…
repositorio de código
- Github: github.com/troyzhxu/be…
- Gitee: gitee.com/troyzhxu/be…
Documentación y Blog
- Documentación: bs.zhxu.cn/
- Blog: juejin.cn/column/7028…
Cambios en la nueva versión v3.8.0
1. Mejorar la compatibilidad de la base de datos
Se agregó un mecanismo de conversión de parámetros para que Oracle, PgSql y otras bases de datos sean tan fluidas como MySQL.
Referencia: gitee.com/troyzhxu/be…
2. El generador de parámetros admite condiciones SQL personalizadas
自定义 SQL 条件,只能在后端通过参数构建器使用,例如
Map<String, Object> params = MapUtils.builder()
// 生成 SQL 条件:u.id in (select user_id from xxx)
.field(User::getId).sql("$1 in (select user_id from xxx)")
.build();
List<User> users = searcher.searchList(User.class, params);
用 $n
来表示所需引用的第 n
个字段,再如:
Map<String, Object> params = MapUtils.builder()
// 生成 SQL 条件:id < 100 or age > 10
.field(User::getId, User::getAge).sql("$1 < 100 or $2 > 10")
.build();
List<User> users = searcher.searchList(User.class, params);
也可以在自定义的 SQL 片段中使用参数占位符 ?
(作为 JDBC 参数),例如:
Map<String, Object> params = MapUtils.builder()
// 生成 SQL 条件:id < ? or age > ?,两个占位符参数分别为:100,10
.field(User::getId, User::getAge).sql("$1 < ? or $2 > ?", 100, 10)
.build();
List<User> users = searcher.searchList(User.class, params);
3、分组动态查询条件生成机制
- 分组字段 生成
where
条件,其它字段 生成having
条件
例如一个指定了 groupBy
的 SearchBean:
@SearchBean(
tables = "student_course",
groupBy = "course_id" // 按课程 ID 分组
)
public class CourseScore {
@DbField("course_id")
private long courseId;
@DbField("sum(score)") // 该课程的总分(聚合函数:sum)
private long totalScore;
}
当以 courseId
为条件时:
Map<String, Object> params = MapUtils.builder()
.field(CourseScore::getCourseId, 101).op(LessThan.class)
.build();
List<CourseScore> list = searcher.searchList(CourseScore.class, params);
执行 SQL(条件在 where 里):
select course_id, sum(score) from student_course where course_id < 101 group by course_id
当以 totalScore
为条件时:
Map<String, Object> params = MapUtils.builder()
.field(CourseScore::getTotalScore, 500).op(GreateThan.class)
.build();
List<CourseScore> list = searcher.searchList(CourseScore.class, params);
执行 SQL(条件在 having 里):
select course_id, sum(score)
from student_course
group by course_id
having sum(score) > 500
当然两者还可以组合:
Map<String, Object> params = MapUtils.builder()
.field(CourseScore::getCourseId, 101).op(LessThan.class)
.field(CourseScore::getTotalScore, 500).op(GreateThan.class)
.build();
List<CourseScore> list = searcher.searchList(CourseScore.class, params);
执行 SQL:
select course_id, sum(score)
from student_course
where course_id < 101
group by course_id
having sum(score) > 500
4、新增 NotLike 运算符
目前内置的运算符已经有 19 个:
运算符 | 缩写 | SQL 片段 | 是否忽略空值 | 含义 |
---|---|---|---|---|
Equal |
eq |
x = ? |
是 | 等于(是缺省默认的运算符) |
NotEqual |
ne |
x != ? |
是 | 不等于 |
GreaterThan |
gt |
x > ? |
是 | 大于 |
GreaterEqual |
ge |
x >= ? |
是 | 大于等于 |
LessThan |
lt |
x < ? |
是 | 小于 |
LessEqual |
le |
x <= ? |
是 | 小于等于 |
Between |
bt |
x between ?1 and ?2 / x >= ?1 / x <= ?2 |
是 | 在...之间(范围查询) |
NotBetween |
nb |
x not between ?1 and ?2 / x < ?1 / x > ?2 |
是 | 不在...之间(范围查询)(since v3.3) |
Contain |
ct |
x like '%?%' |
是 | 包含(模糊查询)(since v3.2) |
StartWith |
sw |
x like '?%' |
是 | 以...开头(模糊查询) |
EndWith |
ew |
x like '%?' |
是 | 以...结尾(模糊查询) |
OrLike |
ol |
x like ?1 or x like ?2 or ... |
是 | 模糊或匹配(可有多个参数值)(since v3.7) |
NotLike |
nk |
x not like ? |
是 | 反模糊匹配(since v3.8) |
InList |
il / mv |
x in (?, ?, ...) |
是 | 多值查询(InList / il 自 v3.3 新增,之前是 MultiValue / mv ) |
NotIn |
ni |
x not in (?, ?, ...) |
是 | 多值查询(since v3.3) |
IsNull |
nl |
x is null |
否 | 为空(since v3.3) |
NotNull |
nn |
x is not null |
否 | 不为空(since v3.3) |
Empty |
ey |
x is null or x = '' |
否 | 为空(仅适用于 字符串 类型的字段) |
NotEmpty |
ny |
x is not null and x != '' |
否 | 不为空(仅适用于 字符串 类型的字段) |
5、优化注解省略机制
原本若要在实体类字段上省略 @DbFeild
时,必须满足以下三条件之一:
- 实体类省略了
@SearchBean
注解 - 实体类的
@SearchBean
没有指定tables
属性 - 实体类的
@SearchBean
指定了autoMapTo
属性
在 v3.8.0
之前,tables
与 autoMapTo
必须 同时出现 或 同时消失 才可以省略 @DbFeild
注解,例如改成这样即可:
@SearchBean(tables="user", autoMapTo="user")
public class UserVO {
private Long id; // 省略注解 @DbFeild
private Long name; // 省略注解 @DbFeild
}
但是总有小伙伴,不想不想省略 tables
,又不想指向 autoMapTo
,写成这样:
@SearchBean(tables="user")
public class UserVO {
private Long id; // 省略注解 @DbFeild
private Long name; // 省略注解 @DbFeild
}
结果让不少人都收到了异常,参考:github.com/ejlchina/be…
为了让大家少踩坑,v3.8.0
让这也兼容了这种的写法。现在要省略 @DbFeild
,只需满足以下四个条件之一即可:
- 实体类省略了
@SearchBean
注解 - 实体类的
@SearchBean
没有指定tables
属性 - 实体类的
@SearchBean.tables
只含一张表(since v3.8.0) - 实体类的
@SearchBean
指定了autoMapTo
属性
6、其它变更
其它变更就不一一列列举了,大家可以在这里查看:
caracteristicas futuras
- BEP 54: Fragmentos de SQL dentro de las anotaciones admiten plantillas condicionales
- BEP 55: SearchBean admite listas y objetos incrustados
Si te sientes bien, haz clic en Estrella:
- Github: github.com/troyzhxu/be…
- Gitee: gitee.com/troyzhxu/be…
Continúe prestando atención, gracias por apoyar a Bean Searcher en el camino, nos esforzaremos por hacerlo mejor.
Anterior: ¿Cuál es la diferencia entre el recientemente popular Bean Searcher y MyBatis Plus?