在复杂应用环境中,数据访问层的设计不仅需要高效,还需要具备灵活性。为了满足对数据库操作的高性能与灵活需求,Jdao提供了全面的持久层解决方案。
Jdao 是Java持久层框架,它结合了Hibernate的抽象性和MyBatis的灵活性。它解决Hibernate和MyBatis的痛点,如过度封装、复杂配置以及SQL维护的挑战。它既适合小型项目,也能胜任大型企业应用,帮助团队在不同场景中灵活应对持久层开发需求
在版本 v2.1.0 中,Jdao特别加强了动态SQL的构建功能,使其更加高效和灵活。本文重点介绍Jdao v2.1.0中动态SQL功能,并展示如何利用这些新特性来构建更高效的数据库操作。
动态SQL允许根据不同的条件或需求动态地生成SQL语句,这对于处理那些条件时有时无、逻辑复杂多变的场景尤为重要。在Jdao中,动态SQL的实现不仅提高了代码的灵活性和可维护性,还增强了SQL语句的安全性,避免了SQL注入等风险。
jdao提供了3种方式构建动态SQL
Jdao提供了构建动态SQL的 if
,where
,choose
,foreach
,set
,trim
等系列标签。
注意:Jdao 没有提供bind标签和$变量替换。原因是实践中,bind标签与$ 会带来一些问题
bind标签
:$符号
:Jdao动态sql性能
动态sql构建效率通常受到构建条件的影响,复杂多条件,多分支的构建条件,程序需要执行更多的判断与基础数据查询,可能导致动态Sql总体执行更慢,这是客观的因素,但是这情况通常不是总体性能决定因素。性能的关键在于底层的实现,条件表达式的分析等;Jdao底层实现了非常高效的sql动态构建性能,它的性能几乎接近直接原生Sql查询的性能。具体的压测数据,请查询Jdao使用文档的jdao性能压测 章节。
# 使用 Maven 安装
<dependency>
<groupId>io.github.donnie4w</groupId>
<artifactId>jdao</artifactId>
<version>2.1.0</version>
</dependency>
<!-- where if -->
<select id="demo1" resultType="io.github.donnie4w.jdao.dao.Hstest">
SELECT * FROM hstest
<where>
<if test="rowname!= 'hello'">
and rowname = #{rowname}
</if>
<if test="id >0">
AND id = #{id}
</if>
</where>
</select>
//测试 where if标签
@Test
public void demo1() throws JdaoException, JdaoClassException, SQLException {
Hstest hs = new Hstest();
hs.setId(31);
hs.setRowname("hello");
List<Hstest> list = jdaoMapper.selectList("io.github.donnie4w.jdao.action.Dynamic.demo1", hs);
}
执行日志
SELECTLIST SQL[SELECT * FROM hstest WHERE id = ?]ARGS[31]
<!-- trim -->
<select id="demo2" resultType="io.github.donnie4w.jdao.dao.Hstest">
SELECT * FROM hstest
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="rowname != null">
AND rowname = #{rowname}
</if>
<if test="id != null">
AND id = #{id}
</if>
</trim>
</select>
//测试 trim
@Test
public void demo2() throws JdaoException, JdaoClassException, SQLException {
Hstest hs = new Hstest();
hs.setId(31);
hs.setRowname("hello");
List<Hstest> list = jdaoMapper.selectList("io.github.donnie4w.jdao.action.Dynamic.demo2", hs);
}
执行日志
SELECTLIST SQL[SELECT * FROM hstest WHERE rowname = ? AND id = ?]ARGS[hello, 31]
@Test
public void testAppendIf() throws JdaoException, SQLException {
Map<String, Object> context = new HashMap<>();
context.put("id", 31);
SqlBuilder builder = SqlBuilder.newInstance();
builder.append("SELECT * FROM HSTEST where 1=1")
.appendIf("id>0", context, "and id=?", context.get("id")) //若表达式id>0成立, 添加SQL : and id=?
.append("ORDER BY id ASC");
List<DataBean> list = builder.selectList();
}
执行日志
信息: [SqlBuilder SQL] SELECT * FROM HSTEST where 1=1 and id=? ORDER BY id ASC [ARGS][31]
@Test
public void testAppendChoose() throws JdaoException, SQLException {
Hstest hstest = new Hstest();
hstest.setRowname("www>>>>2");
hstest.setId(31);
hstest.setValue("2421209491375900");
hstest.setAge(31);
SqlBuilder builder = SqlBuilder.newInstance();
builder.append("SELECT * FROM HSTEST where 1=1")
.appendChoose(hstest, choose -> choose
.when(" age <30 && age>10", "AND age =?", hstest.getAge())
.when("rowname!=null", "AND rowname like ?", "%" + hstest.getRowname() + "%")
.otherwise("AND id >0")).append("limit 2");
List<DataBean> list = builder.selectList();
}
执行日志
信息: [SqlBuilder SQL] SELECT * FROM HSTEST where 1=1 AND rowname like ? limit 2 [ARGS][%www>>>>2%]
//appendForeach
@Test
public void testAppendForeach() throws JdaoException, SQLException {
SqlBuilder builder = SqlBuilder.newInstance();
builder.append("SELECT * FROM hstest where id in")
.appendForeach(null, new int[]{31, 32, 33}, "item", ",", "(", ")", foreachBuilder -> foreachBuilder
.body("#{item}")
);
List<DataBean> list = builder.selectList();
for (DataBean bean : list) {
System.out.println(bean);
}
}
执行日志
信息: [SqlBuilder SQL] SELECT * FROM hstest where id in (?,?,?)[ARGS][31, 32, 33]
Jdao是一种创新的持久层解决方案。主要目的在于 减少编程量,提高生产力,提高性能,支持多数据源整合操作,支持数据读写分离,制定持久层编程规范。 灵活运用Jdao,可以在持久层设计上,减少30%甚至50%以上的编程量,同时形成持久层的统一编程规范,减少持久层错误,同时易于维护和扩展。
Jdao的映射模块实现了SQL与程序分离的特性,映射模块与myBatis的核心功能相同。是除了mybatis和基于myBatis系列的orm外,唯一实现该特性的orm框架.
更多Jdao的详细信息,请查阅 Jdao使用文档
更多Jdao使用示例,请参考 jdaodemo