jfinal自动生成SQL模板文件

创建完数据库表后,需要编写SQL语句,推荐使用SQL模板文件。多年的spring boot开发,前后端已经习惯了使用Post 传递Json,后端统一的Map或者Model接收。Mybatis中直接判断取值赋值执行语句。

问题:jfinal的SQL模板文件在多参数下,需要编写条件语句,参数过多的情况下根据不同的参数查询时写的挺费劲的。

借鉴:在spring boot开发中,编写了自动生成mapper.xm的语句文件,同样在jfinal中一样可以自动生成常用的SQL语句文件。

image.png

这样的语句文件几乎都是自动生成,能够满足很多条件下的接口查询功能。

同样,在jfinal中同样可以!!

实现:

1、实现结果:

#sql("list")

  select * from sys_user where 1=1

  #if(userId)

   user_id=#para(userId)

  #end

  #if(username)

   username=#para(username)

  #end

  #if(password)

   password=#para(password)

  #end

  #if(nickName)

   nick_name=#para(nickName)

  #end

  #if(avatar)

   avatar=#para(avatar)

  #end

  #if(sex)

   sex=#para(sex)

  #end

  #if(phone)

   phone=#para(phone)

  #end

  #if(email)

   email=#para(email)

  #end

  #if(emailVerified)

   email_verified=#para(emailVerified)

  #end

  #if(trueName)

   true_name=#para(trueName)

  #end

  #if(idCard)

   id_card=#para(idCard)

  #end

  #if(birthday)

   birthday=#para(birthday)

  #end

  #if(introduction)

   introduction=#para(introduction)

  #end

  #if(organizationId)

   organization_id=#para(organizationId)

  #end

  #if(state)

   state=#para(state)

  #end

  #if(deleted)

   deleted=#para(deleted)

  #end

  #if(createTime)

   create_time=#para(createTime)

  #end

  #if(updateTime)

   update_time=#para(updateTime)

  #end

  #if(organizationCode)

   organization_code=#para(organizationCode)

  #end

  #if(openId)

   open_id=#para(openId)

  #end

  #if(unionId)

   union_id=#para(unionId)

  #end

#end

2、调用

@Before({ POST.class})

public void cardList() {

Map<String, Object> map = paramMap();

renderJson(appService.cardList(map));

}

public List<ExamCard> cardList(Map<String, Object> map) {

SqlPara sqlPara = Db.getSqlPara("examCard.list", map);

List<ExamCard> list = cardDao.find(sqlPara);

return list;

}

前端不管根据实体类中的任何参数,均可有前端自行组装。(涉及安全方面的需后端处理或拦截)

3、具体代码


import java.io.File;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.ResultSetMetaData;


import cn.hutool.core.io.FileUtil;


public class DatabaseUtil {

private static final String url = "jdbc:mysql://127.0.0.1:3306/web-xxx?characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai";

private static final String user = "root";

private static final String pass = "xxx";


public static void main(String[] args) throws Exception {

String tableName="数据库表名";

String sql = generatorSQL(tableName);

                //生成SQL文件

File file = FileUtil.writeUtf8String(sql, new File("G:\\xxxxx\\src\\main\\resources\\"+tableName+".sql"));

System.out.println(file.getAbsolutePath());

}


/**

* 生成SQL语句

* @param tableName 表明

* @return sql

*/

private static String generatorSQL(String tableName) {

try {

Class.forName("com.mysql.cj.jdbc.Driver");

Connection conn = DriverManager.getConnection(url, user, pass);

PreparedStatement ps = conn.prepareStatement("select * from " + tableName);

ResultSet rs = ps.executeQuery();

ResultSetMetaData data = rs.getMetaData();

// 获得所有列的数目及实际列数

int columnCount = data.getColumnCount();

StringBuilder builder=new StringBuilder();

builder.append("#sql(\"list\")");

builder.append("\r\n");

builder.append("  select * from " + tableName + " where 1=1");

builder.append("\r\n");

for (int i = 1; i < columnCount + 1; i++) {

// 获得指定列的列名

String columnName = data.getColumnName(i);

columnName = changeToJavaFiled(columnName);

builder.append(

"  #if("+columnName+")\r\n" + 

"   and "+data.getColumnName(i)+"=#para("+columnName+")\r\n" + 

"  #end"

);

builder.append("\r\n");

}

builder.append("#end");

conn.close();

return builder.toString();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}


/**

* mysql字段转驼峰形式

* @param field 字段

* @return 驼峰形式值

*/

public static String changeToJavaFiled(String field) {

String[] fields = field.toLowerCase().split("_");

StringBuilder sbuilder = new StringBuilder(fields[0]);

for (int i = 1; i < fields.length; i++) {

char[] cs = fields[i].toCharArray();

cs[0] -= 32;

sbuilder.append(String.valueOf(cs));

}

return sbuilder.toString();

}

}


语录:代码改变世界,Bug影响程序!

评论区

RichardHe

2021-05-12 20:49

这么多if和end,能够用数组加循环解决?有没有自动获取字段列表的办法?不要只写代码,要写思想。

JackHappiness

2021-06-03 11:34

@RichardHe if与end是sql语句中使用,是为了适应不同的查询接口;不然的话需要提供很多的查询接口,仅供参考,具体的实现还需自行设计

RichardHe

2021-06-07 09:26

想少写代码太难了。