JFinal 表自动绑定插件实现,实现零配置,支持多数据源

以mysql数据库实现为例,其它的db也可基于这种方式自己实现

大概的思路是这样的,为了简少配置,所以不使用注解的方式

首先需要一个工具类来拿到所有的Model类大体的实现方式如下

package com.nmtx.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.jfinal.kit.PathKit;
import com.jfinal.kit.StrKit;

public class ClassUtils {
    public static String classRootPath = null;

	public static List<Class<?>> scanPackage(String packageName) throws ClassNotFoundException {
		List<Class<?>> classList = new ArrayList<Class<?>>();
		String path = getClassRootPath() + "/" + packageName.replace(".", "/");
		List<String> fileNameList = getAllFileName(path);
		for (String fileName : fileNameList) {
			classList.add(Class.forName(fileName));
		}
		return classList;
	}

	public static List<String> getAllFileName(String path) {
		List<String> fileNameList = new ArrayList<String>();
		File rootFile = new File(path);
		if (rootFile.isFile()) {
			String fileName = rootFile.getPath().replace(PathKit.getRootClassPath(), "").replace(File.separator, ".")
					.replaceFirst(".", "");
			String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
			if (prefix.equals("class")) {
				fileNameList.add(fileName.substring(0, fileName.lastIndexOf(".")));
			}
		} else {
			File[] files = rootFile.listFiles();
			if (files != null) {
				for (File file : files) {
					fileNameList.addAll(getAllFileName(file.getPath()));
				}
			}
		}
		return fileNameList;
	}

	public static String getClassRootPath() {
		if (StrKit.isBlank(classRootPath))
			classRootPath = PathKit.getRootClassPath();
		return classRootPath;
	}

	public static void setClassRootPath(String classRootPath) {
		ClassUtils.classRootPath = classRootPath;
	}
}

有了工具类,就去处理自动扫描插件,大概实现是这样的

package com.nmtx.plugins.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.c3p0.C3p0Plugin;
import com.nmtx.plugins.db.impl.TableToModelByUnderline;
import com.nmtx.utils.ClassUtils;

public class AutoTabelPlugin implements IPlugin {
	private String db;
	private ActiveRecordPlugin arp;
	private String pacekageName;
	private String idKey;
	private ITableToModelFormat tableToModelFormate;
	private C3p0Plugin c3p0Plugin;

	public AutoTabelPlugin(C3p0Plugin erpC3p0, ActiveRecordPlugin arp, String db, String packageName, String idKey,
			ITableToModelFormat tableToModelFormate) {
		this.db = db;
		this.arp = arp;
		this.idKey = idKey;
		this.tableToModelFormate = tableToModelFormate;
		this.c3p0Plugin = erpC3p0;
	}

	public AutoTabelPlugin(C3p0Plugin erpC3p0, ActiveRecordPlugin arp, String db, String packageName, String idKey) {
		this.db = db;
		this.arp = arp;
		this.idKey = idKey;
		this.pacekageName = packageName;
		this.tableToModelFormate = new TableToModelByUnderline();
		this.c3p0Plugin = erpC3p0;
	}

	@SuppressWarnings({ "unchecked" })
	public List<Class<? extends Model<?>>> getModelClass() throws ClassNotFoundException {
		List<Class<?>> classes = ClassUtils.scanPackage(pacekageName);
		List<Class<? extends Model<?>>> modelClasses = new ArrayList<Class<? extends Model<?>>>();
		for (Class<?> classer : classes) {
			modelClasses.add((Class<? extends Model<?>>) classer);
		}
		return modelClasses;
	}

	public boolean start() {
		try {
			HashMap<String, String> tableMap = getTableMap();
			List<Class<? extends Model<?>>> modelClasses = getModelClass();
			for (Class<? extends Model<?>> modelClass : modelClasses) {
				String tableName = tableMap.get(modelClass.getSimpleName());
				if (tableName != null) {
					if (StrKit.notBlank(idKey)) {
						arp.addMapping(tableName, idKey, modelClass);
					} else {
						arp.addMapping(tableName, modelClass);
					}

				}
			}
		} catch (ClassNotFoundException e) {
			throw new RuntimeException("auto table mappming is exception" + e);
		}

		return true;
	}

	/**
	 * 获取Model和表名的映射
	 * 
	 * @return
	 */
	private HashMap<String, String> getTableMap() {
		HashMap<String, String> map = new HashMap<String, String>();
		Connection connection = null;
		PreparedStatement preStatement = null;
		ResultSet resultSet = null;
		try {
			c3p0Plugin.start();
			connection = c3p0Plugin.getDataSource().getConnection();
			preStatement = connection.prepareStatement(
					"select table_name as tableName from information_schema.tables where table_schema='" + db
							+ "' and table_type='base table'");
			resultSet = preStatement.executeQuery();
			while (resultSet.next()) {
				String tableName = resultSet.getString(1);
				map.put(tableToModelFormate.getTableByModel(tableName), tableName);
			}
		} catch (Exception e) {
			closeConnection(connection, preStatement, resultSet);
			throw new RuntimeException("auto table mappming is exception" + e);
		} finally {
			closeConnection(connection, preStatement, resultSet);
		}
		return map;

	}

	private void closeConnection(Connection connection, PreparedStatement preStatement, ResultSet resultSet) {
		try {
			if (resultSet != null) {
				resultSet.close();
			}
			if (preStatement != null) {
				preStatement.close();
			}
			if (connection != null) {
				connection.close();
			}
		} catch (SQLException e) {
			throw new RuntimeException("auto close db connection  is exception" + e);
		}
	}

	public boolean stop() {
		return true;
	}

}

因为java里的属性一般都是驼峰规则,代码看起来舒服一点,这里以数据库中以大写字母为例,表名为T_USER,对应Model名为User实现如下

接口定义

package com.nmtx.plugins.db;

public interface ITableToModelFormat {
   public String generateTableNameToModelName(String tableName);
}

实现如下

package com.nmtx.plugins.db.impl;

import com.nmtx.plugins.db.ITableToModelFormat;

public class TableToModelByUnderline implements ITableToModelFormat{

	public String generateTableNameToModelName(String tableName) {
		StringBuilder modelName = new StringBuilder();
	    tableName = tableName.substring(2).toLowerCase();
		String tableNames[] = tableName.split("_");
		for(String tableNameTemp:tableNames){
			modelName.append(fisrtStringToUpper(tableNameTemp));
		}
		return modelName.toString();
	}
	
	private String fisrtStringToUpper(String string){
		return string.replaceFirst(string.substring(0, 1),string.substring(0, 1).toUpperCase()); 
	}
	
}

如果不同的格式可以实现不同的方法,根据自己的需求,这样就完成了自动扫描插件,使用起来也方便如下

C3p0Plugin spuC3p0= new C3p0Plugin(getProperty("jdbc.mysql.url"),
				getProperty("jdbc.mysql.username").trim(), getProperty("jdbc.mysql.password").trim(),
				getProperty("jdbc.mysql.driverClass"));
		spuC3p0.setMaxPoolSize(Integer.parseInt(getProperty("jdbc.mysql.maxPool")));
		spuC3p0.setMinPoolSize(Integer.parseInt(getProperty("jdbc.mysql.minPool")));
		spuC3p0.setInitialPoolSize(Integer.parseInt(getProperty("jdbc.mysql.initialPoolSize")));
		ActiveRecordPlugin spuArp = new ActiveRecordPlugin(DbConfigName.SPU, spuC3p0);
		AutoTabelPlugin spuAutoTabelPlugin = new AutoTabelPlugin(spuC3p0, spuArp, getProperty("jdbc.mysql.spu.db"),
				"com.nmtx.manager.model", "ID");
		me.add(spuAutoTabelPlugin);
		me.add(spuArp);

如果有多个就可以配置多个插件,而无需在管映射了,新增Model直接新增即可,不要再管映射

转载于:https://my.oschina.net/u/136848/blog/783131

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值