JFinal 自动探测Model 注册插件 AutoScanPlugin

原创
2012/07/18 23:07
阅读数 1.3K

本插件已经整合重构,新版本自动注册model插件请看这个博客

http://my.oschina.net/b1412/blog/68083

 

--------------------------------------------------------------------------------

在ssh等框架中有不少自动扫包注册的功能,当我们类较多的时候可以减少不少的工作。

根据这个思路写了个简单的自动扫包注册Model的插件。
扫描classes下面所以继承了Model的类注册到ActiveRecordPlugin中。数据库表名默认采用骆峰。
比如MobileBind.Java则映射到mobieBind表.另外也可以选择全部大写和全部小写的策略.


/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		DruidPlugin druidPlugin = new DruidPlugin.DruidBuilder(getProperty("url"), getProperty("username"),
				getProperty("password")).build();
		me.add(druidPlugin);
		ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
		arp.setShowSql(true);
      	        SqlReporter.setLogger(true);
		AutoScanPlugin autoScanPligin = new AutoScanPlugin(arp,TableNameStyle.LOWER);
                me.add(autoScanPligin);  //自动扫包注册model插件要在ActiveRecordPlugin之前注册         	
                me.add(arp);	      
       }


package com.jfinal.plugin.autoscan;
import java.io.File;
import java.net.URL;
import java.util.List;

import com.cloud.pxxt.Config;
import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.util.StringKit;

/**
 *  自动扫包
 */
public class AutoScanPlugin implements IPlugin {
	private ActiveRecordPlugin arp;

	private TableNameStyle tableNameStyle;
	
	public AutoScanPlugin(ActiveRecordPlugin arp) {
		this.arp = arp;
	}
	public AutoScanPlugin(ActiveRecordPlugin arp,TableNameStyle tableNameStyle) {
		this.arp = arp;
		this.tableNameStyle = tableNameStyle;
	}

	@Override
	public boolean start() {
		try {
			registModel(AutoScanPlugin.class.getResource("/").getFile(), "classes/");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return true;
	}

	@Override
	public boolean stop() {
		return true;
	}

	private void registModel(String fileDir, String pre) throws Exception {
		List<File> classList = FileSearcher.findFiles(fileDir, "*.class");
		for (File classFile : classList) {
			String className = getClassName(classFile, pre);
			Class clazz = Class.forName(className);
			if (clazz.getSuperclass() == Model.class) {
				String tableName = clazz.getSimpleName();
				if(tableNameStyle==TableNameStyle.UP){
					tableName =tableName.toUpperCase();
				}else if(tableNameStyle==TableNameStyle.LOWER){
					tableName =tableName.toLowerCase();
				}else{
					tableName =StringKit.firstCharToLowerCase(tableName);

				}
				arp.addMapping(tableName, clazz);
			}
		}
	}

	private static String getClassName(File classFile, String pre) {
		String objStr = classFile.toString().replaceAll("\\\\", "/");
		String className;
		className = objStr.substring(objStr.indexOf(pre)+pre.length(),objStr.indexOf(".class"));
		if (className.startsWith("/")) {
			className = className.substring(className.indexOf("/")+1);
		}
		return className.replaceAll("/", ".");
	}

}

package com.jfinal.plugin.autoscan;

public enum TableNameStyle {
	UP,LOWER
}

 
 
  其他还有些自动探测的方法,比如我们约定Model对象都用xxModel.java那么可以在探测的时候直接根据这个文件名规则找到所以Model.
目前这种方式是加载类根据该类的父类是否为Mode作为条件.代价要大一点.

 一些问题.,这样自动探测的表名映射规则是否够用,如果数据库表明不是很规则的可能需要再扩展几个根据类名生存数据库表明的策略,比如oracle数据库很多带下划线的命名方式.
另外这种方式还无法探测jar包里面的Model.以后再实现.
 
  以上给大家提供个思路,请高手不惜赐教.

 虽然JFinal本身已经够简单代码量少了,不过我们还可让写的代码更少一些~



 
展开阅读全文
加载中
点击加入讨论🔥(14) 发布并加入讨论🔥
14 评论
9 收藏
3
分享
返回顶部
顶部