// 使用Fluent MyBatis构造查询语句
mapper.listMaps(new StudentScoreQuery()
.select
.schoolTerm()
.subject()
.count.score("count")
.min.score("min_score")
.max.score("max_score")
.avg.score("avg_score")
.end()
.where.schoolTerm().ge(2000)
.and.subject.in(new String[]{"英语", "数学", "语文"})
.and.score().ge(60)
.and.isDeleted().isFalse()
.end()
.groupBy.schoolTerm().subject().end()
.having.count.score.gt(1).end()
.orderBy.schoolTerm().asc().subject().asc().end()
);
// 使用MyBatis Dynamic SQL构造查询语句
mapper.selectMany(
select(
schoolTerm,
subject,
count(score).as("count"),
min(score).as("min_score"),
max(score).as("max_score"),
avg(score).as("avg_score")
).from(studentScore)
.where(schoolTerm, isGreaterThanOrEqualTo(2000))
.and(subject, isIn("英语", "数学", "语文"))
.and(score, isGreaterThanOrEqualTo(60))
.and(isDeleted, isEqualTo(false))
.groupBy(schoolTerm, subject)
.having(count(score), isGreaterThan(1)) //当前其实还不支持having方法
.orderBy(schoolTerm, subject)
.build(isDeleted, isEqualTo(false))
.render(RenderingStrategies.MYBATIS3)
);
// 使用JOOQ构造查询语句
dslContext.select(
STUDENT_SCORE.GENDER_MAN,
STUDENT_SCORE.SCHOOL_TERM,
STUDENT_SCORE.SUBJECT,
count(STUDENT_SCORE.SCORE).as("count"),
min(STUDENT_SCORE.SCORE).as("min_score"),
max(STUDENT_SCORE.SCORE).as("max_score"),
avg(STUDENT_SCORE.SCORE).as("avg_score")
)
.from(STUDENT_SCORE)
.where(
STUDENT_SCORE.SCHOOL_TERM.ge(2000),
STUDENT_SCORE.SUBJECT.in("英语", "数学", "语文"),
STUDENT_SCORE.SCORE.ge(60),
STUDENT_SCORE.IS_DELETED.eq(false)
)
.groupBy(
STUDENT_SCORE.GENDER_MAN,
STUDENT_SCORE.SCHOOL_TERM,
STUDENT_SCORE.SUBJECT
)
.having(count().ge(1))
.orderBy(
STUDENT_SCORE.SCHOOL_TERM.asc(),
STUDENT_SCORE.SUBJECT.asc()
)
.fetch();
// 使用MyBatis Plus构造查询语句
mapper.selectMaps(new QueryWrapper<StudentScore>()
.select(
"school_term",
"subject",
"count(score) as count",
"min(score) as min_score",
"max(score) as max_score",
"avg(score) as avg_score"
)
.ge("school_term", 2000)
.in("subject", "英语", "数学", "语文")
.ge("score", 60)
.eq("is_deleted", false)
.groupBy("school_term", "subject")
.having("count(score)>1")
.orderByAsc("school_term", "subject")
);
new StudentQuery()
.where.isDeleted().isFalse()
.and.grade().eq(4)
.and.homeCountyId().in(CountyDivisionQuery.class, q -> q
.selectId()
.where.isDeleted().isFalse()
.and.province().eq("浙江省")
.and.city().eq("杭州市")
.end()
).end();
SELECT * FROM student
WHERE is_deleted = false
AND grade = 4
AND home_county_id IN (
SELECT id FROM county_division
WHERE is_deleted = false
AND province = '浙江省'
AND city = '杭州市'
)
JoinBuilder.from(
new StudentQuery("t1", parameter)
.selectAll()
.where.age().eq(34)
.end()
).join(
new HomeAddressQuery("t2", parameter)
.where.address().like("address")
.end()
).on(
l -> l.where.homeAddressId(),
r -> r.where.id()
).endJoin().build();
new StudentUpdate()
.update.name().is(student.getName(), If::notBlank)
.set.phone().is(student.getPhone(), If::notBlank)
.set.email().is(student.getEmail(), If::notBlank)
.set.gender().is(student.getGender(), If::notNull)
.end()
.where.id().eq(student.getId()).end();
<update id="updateById" parameterType="...">
update student
<set>
<if test="name != null">
`name` = #{name,jdbcType=VARCHAR},
</if>
<if test="phone != null">
phone = #{phone,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{email,jdbcType=VARCHAR},
</if>
<if test="gender != null">
gender = #{gender,jdbcType=TINYINT},
</if>
<if test="gmtModified != null">
gmt_modified = #{gmtModified,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
StudentQuery studentQuery = Refs.Query.student.aliasQuery()
.select.age().end()
.where.age().isNull().end()
.groupBy.age().apply("id").end();
if (config.shouldFilterAge()) {
studentQuery.having.max.age().gt(1L).end();
} else if (config.shouldOrder()) {
studentQuery.orderBy.id().desc().end();
}
fluent-mybatis 包含各种公共基础类
fluent-mybatis-test 测试用例
fluent-mybatis-processor 编译期代码生成器
XyzBaseDao:继承BaseDao类型,实现IBaseDao接口,包含获得Entity相关Mapper、Query、Update类型的方法,是Fluent Generator为用户生成的空白Dao类的父类。
XyzMapper:实现IEntityMapper,IRichMapper、IWrapperMapper接口,用于构造Query和Update对象,以及执行IQuery或IUpdate类型的SQL指令。
XyzQuery:继承BaseWrapper、BaseQuery类型,实现IWrapper、IQuery接口,用于组装查询语句的基本容器。
XyzUpdate:继承BaseWrapper、BaseUpdate类型,实现IWrapper、IBaseUpdate接口,用于组装更新语句的基本容器。
XyzSqlProvider:继承BaseSqlProvider类型,用于最终组装SQL语句。
还有XyzMapping、XyzDefaults、XyzFormSetter、XyzEntityHelper:、XyzWrapperHelper等。由fluent-mybatis-processor模块生成的许多类型都会在编写业务代码的时候用到。
// 构造并执行查询语句
List<StudentEntity> users = mapper.listEntity(
new StudentQuery() .select.name().score().end()
.where.userName().like("user").end()
.orderBy.id().asc().end()
.limit(20, 10)
);
// 构造并执行更新语句
int effectedRecordCount = mapper.updateBy(
new StudentUpdate()
.set.userName().is("u2")
.set.isDeleted().is(true)
.set.homeAddressId().isNull().end()
.where.isDeleted().eq(false).end()
);
2021阿里云开发者大会资料
5月29日,2021阿里云开发者大会圆满结束。本次大会的主题是“云让应用创新更简单”,大会探讨了100+技术议题,涵盖开发与运维、云原生、大数据、人工智能、数据库、低代码等领域,阿里妹特意准备了大会议题PDF等资料,以便同学们回顾和学习大会核心技术内容。