前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JFinal 表自动绑定插件实现,实现零配置,支持多数据源

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

作者头像
用户2603479
发布2018-08-15 16:47:54
3120
发布2018-08-15 16:47:54
举报
文章被收录于专栏:JAVA技术站JAVA技术站

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

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

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

代码语言:javascript
复制
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;
	}
}

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

代码语言:javascript
复制
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实现如下

接口定义

代码语言:javascript
复制
package com.nmtx.plugins.db;

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

实现如下

代码语言:javascript
复制
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()); 
	}
	
}

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

代码语言:javascript
复制
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直接新增即可,不要再管映射

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016/11/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档