JFinal3.0自动添加sql文件的工具类

Jfinal3.0有个动态sql的功能用起来还是挺爽的,如果sql文件比较少到没什么,如果sql文件多起来,一个一个的添加sql文件总让人感到不爽。于是自己就写了个自动加载sql文件的工具,代码写得不怎么样,勿喷。

package com.withub.base.utils;

import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.xiaoleilu.hutool.io.FileUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;


/**
 * Created by xxx on 2017/4/7 0007.
 * 用于自动映射sql文件
 */
public abstract class AutoMappingUtils {
    private static Logger logger = LoggerFactory.getLogger(AutoMappingUtils.class);
    private static final String SQL_EXT = "sql";

    //默认路径是项目的相对路径
    public static void auto(ActiveRecordPlugin arp){
        auto(arp,"/");
    }


    public static void auto(ActiveRecordPlugin arp,String path){
        logger.info("开始映射sql文件");
        Path p = Paths.get(path);
        boolean absolute = p.isAbsolute();
        try {
            if(absolute){//是否是绝对路径
                arp.setBaseSqlTemplatePath(p.toString());
                Files.walkFileTree(p,new SQLVisitor(p,arp));//自动映射
            }else{//如果不是绝对路径,那么相对的就是项目的根路径
                String webRootPath = PathKit.getRootClassPath();//获取项目跟路径
                Path absoluteWebPath = Paths.get(webRootPath, path);//获取项目绝对根路径
                //设置模板sql的位置
                arp.setBaseSqlTemplatePath(absoluteWebPath.toString());
                Files.walkFileTree(absoluteWebPath,new SQLVisitor(absoluteWebPath,arp));//自动映射
            }
        } catch (IOException e) {
            throw new RuntimeException("SQL文件自动映射异常!请检查SQL路径");
        }


    }

    /**
     * sql文件访问器
     * */
    private static class SQLVisitor implements FileVisitor<Path>{

        private Path path;
        private ActiveRecordPlugin arp;
        public SQLVisitor(Path path,ActiveRecordPlugin arp){
            this.path = path;
            this.arp = arp;
        }

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            File unknowFile = file.toFile();//未知文件
            String extName = FileUtil.extName(unknowFile);//获取文件扩展名
            boolean b = StrUtil.equalsIgnoreCase(extName, SQL_EXT);
            if(b){//如果相等,说明是sql文件,那么加入sql文件映射中去
                Path relativize = path.relativize(file);
                logger.info("映射sql文件:"+relativize.toFile());
                arp.addSqlTemplate(relativize.toString());//添加sql文件映射
            }
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
            return FileVisitResult.TERMINATE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            return FileVisitResult.CONTINUE;
        }
    }

}

只要指定存放sql文件的目录包括子目录中的.sql文件就会全部加载进去,支持绝对路径,相对路径就是相对于web的路径,希望大家指正。

评论区

JFinal

2017-04-28 12:03

这个功能确实有用,有不少小伙伴们找我要过,感谢你的分享

北流家园网

2017-05-01 20:16

怎么用?

maonima

2017-05-02 15:01

@北流家园网 把这个作为一个工具类,让后在config类中添加一句AutoMappingUtils.auto(ActiveRecordPlugin对象,"目录");

abvcb

2017-05-03 13:42

没太懂, 要把很简单的事情变得这么复杂. 下面是切到 3.0 使用 jfinal 自带 sql 管理时写的一个工具类, 初衷和你相同, 就是不想一个一个引入.



public class SqlTemplateKit {

/**
* 初始化 sql 模板到 ActiveRecord
*
* @param arp ActiveRecordPlugin
* @param basePath sql 文件根目录
* @param suffix 文件后缀
*/
public static void init(ActiveRecordPlugin arp, String basePath, String suffix) {
File baseFolder = new File(basePath);
File[] sqlFiles = baseFolder.listFiles(file -> {
return file.getName().endsWith(suffix);
});
if (CollectionKit.isEmpty(sqlFiles))
return;
for (File sqlFile : sqlFiles) {
arp.addSqlTemplate(sqlFile.getName());
}
}

}



直接结束了就, 我是 用的 java 8 的特性写的, 就算不用 lamda 也不会像楼主这代码看起来这么复杂 = =

至于使用

String sqlBasePath = PathKit.getRootClassPath();
arp.setBaseSqlTemplatePath(sqlBasePath);
SqlTemplateKit.init(arp, sqlBasePath, ".sql");
_MappingKit.mapping(arp);

直接这样就好


路径的话, 其实没必要再判断相对路径或者绝对路径了, jfinal 的 sql 管理, 本身就是需要路径的 arp.setBaseSqlTemplatePath , 那么 sql 文件的路径和这个一样就好, 工具再去判断相对绝对不是很累的.


起初没分享出来, 是觉得这个大家应该都会想到, 毕竟撸代码的不会偷懒就 ...

没有贬低之意, 仅是探讨.

要表达的意思是, 没必要把事情搞的这么复杂.

冰雨

2017-05-04 21:44

/**
*
* 扫描添加Sql模板文件
* @param arp
* @param file
*/
public void scanAddSqlTemplate(ActiveRecordPlugin arp,File file){
if(file.exists() && file.isFile()){
if(file.getName().toUpperCase().endsWith(".SQL")){
String sqlFile = file.getPath().replace(SQL_TEMPLATE_BASEPATH, "");
arp.addSqlTemplate(sqlFile);
System.out.println("-----------------Add SQL Template File "+file.getPath()+"-------------------------");
}
}else{
File[] files = file.listFiles();
for(File f:files){
scanAddSqlTemplate(arp,f);
}
}
}
我是这么做的,没考虑打包成jar包的情况,其实稍微再改造一下就可以了。

maonima

2017-05-06 20:27

@abvcb 学习了

maonima

2017-05-06 20:27

@冰雨 学习了。

小鱼@

2017-05-17 14:59

收藏了

热门分享

扫码入社