动态拼装mysql语句
目前使用Mybatis注解逐渐取代xml成为主流
然而动态注入SQL语句,list传参,动态添加where判断成为程序员比较头疼的问题,目前有三种办法
1.配置xml(不推荐)
2.注解中写xml脚本@Select(<script>...</script>)(不推荐,可读性非常差)
3.使用Java类中的Java方法拼写Mysql语句(推荐,java语句编写,可读性好,易维护)
实例1:两个List入参动态注入MYSQL语句
传入两个List用于分别匹配name和group列,如[p1,p2],[g1,g2,g3,g4]
拼写SQL语句
SELECT * FROM XX
WHERE name=p1 OR name =p2
OR group=g1 OR group =g2 OR group=g3
Java类如下
@SelectProvider(type = SelectSqlProvider.class, method = "selectWithList")
List<GroupProjectVO> groupProjectByList(List projectNames,List groupMembers);
/**
* 内部类
*/
class SelectSqlProvider {
//拼装SQL语句
public String selectWithList(Map map) {
//Mybatis使用map KV形式存储参数,获取arg0,arg1分别获取两个List
List projectNames = (List) map.get("arg0");
List groupMembers = (List) map.get("arg1");
String sqlStr = new SQL() {
{
SELECT("*");
FROM("pkpm_project_def");
WHERE("1=2");
projectNames.stream().forEach(projectName -> {
//WHERE默认使用AND拼装,使用OR()标记条件为或
OR();
//对于字符串需要拼装单引号''
WHERE("name=\'" + projectName+"\'");
});
groupMembers.stream().forEach(groupMember -> {
OR();
WHERE("group_id=" + groupMember);
});
}
}.toString();
System.out.println(sqlStr);
return sqlStr;
}
}
总结:
- @SelectProvider注解 绑定SelectSqlProvider类中的selectWithList方法;
- Mybatis使用map KV形式存储参数,获取arg0,arg1分别对应两个List,以此类推可以获得任意类型参数
- 方法中使用函数WHERE(),FROM()等拼装Mysql语句,使用Java8流遍历List拼装
- WHERE默认使用AND拼装,使用OR()拼装条件修改为或 添加WHERE("1=2") 保证where false or XX or XX格式正确
- 字符串作为值需要拼装单引号''或双引号""
拼写后生成的MYSQL语句
SELECT *
FROM pkpm_project_def
WHERE (1=2)
OR (name='p10')
OR (group_id=1)
OR (group_id=7)
实例2:条件判断动态注入MySQL
public class EmployeeDynaSqlProvider {
//方法中的关键字是区分大小写的 SQL SELECT WHERE
//该方法会根据传递过来的map中的参数内容 动态构建sql语句
public String selectWhitParamSql(Map<String, Object> param) {
return new SQL() {
{
SELECT("*");
FROM("tb_employee");
if (param.get("id")!=null) {
WHERE("id=#{id}");
}
if(param.get("loginname")!=null) {
WHERE("loginname=#{loginname}");
}
if(param.get("password")!=null) {
WHERE("password=#{password}");
}
if(param.get("name")!=null) {
WHERE("name=#{name}");
}
if(param.get("sex")!=null) {
WHERE("sex=#{sex}");
}
if(param.get("age")!=null) {
WHERE("age=#{age}");
}
if(param.get("phone")!=null) {
WHERE("phone=#{phone}");
}
if(param.get("sal")!=null) {
WHERE("sal=#{sal}");
}
if(param.get("state")!=null) {
WHERE("state=#{state}");
}
}
}.toString();
}
}
总结
使用java类动态注入MYSQL语句效率高,本质上就是写了一个java方法,可读性,维护性都很高,而且非常灵活,支持任意类型的sql拼装,推荐