com.jeesuite.mybatis.parser.MybatisMapperParser Maven / Gradle / Ivy
package com.jeesuite.mybatis.parser;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarFile;
import org.apache.ibatis.builder.xml.XMLMapperEntityResolver;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.NodeList;
/**
* mybatismapper数据库字段与实体字段映射关系转换工具
* @author jwww
* @date 2015年5月7日上午11:30:42
* @description
* Copyright (c) 2015, [email protected].
*/
public class MybatisMapperParser {
private static final Logger log = LoggerFactory.getLogger(MybatisMapperParser.class);
private static Map> caches = new HashMap>();
private static Map> entityRalateItems = new HashMap>();
private static Map> tableRalateItems = new HashMap>();
private static Map> namespaceRalateColumns = new HashMap>();
private static List entityInfos = new ArrayList<>();
public static List getEntityInfos() {
doParse();
return entityInfos;
}
public static boolean entityHasProperty(Class> entityClass,String propName){
return property2ColumnName(entityClass, propName) != null;
}
public static String columnToPropName(Class> entityClass,String columnName){
doParse();
if(caches.containsKey(entityClass.getName())){
return caches.get(entityClass.getName()).get(columnName);
}
return null;
}
public static String property2ColumnName(Class> entityClass,String propName){
doParse();
Map map = caches.get(entityClass.getName());
if(map != null){
for (String columnName : map.keySet()) {
if(propName.equals(map.get(columnName)))return columnName;
}
}
return null;
}
public static boolean tableHasColumn(String namespace,String columnName){
List list = namespaceRalateColumns.get(namespace);
return list != null && list.contains(columnName.toLowerCase());
}
private synchronized static void doParse(){
if(caches.isEmpty()){
try {
URL resource = Thread.currentThread().getContextClassLoader().getResource("mapper/");
if (resource != null) {
if (resource.getProtocol().equals("file")) {
File mapperDir = new File(resource.getPath());
File[] files = mapperDir.listFiles();
for (File f : files) {
if(f.getName().endsWith("Mapper.xml")){
parseMapperFile(new FileInputStream(f));
}
}
} else if (resource.getProtocol().equals("jar")) {
String jarFilePath = resource.getFile();
jarFilePath = jarFilePath.substring("file:".length(), jarFilePath.length() - "!/mapper/".length());
jarFilePath = java.net.URLDecoder.decode(jarFilePath, "UTF-8");
JarFile jarFile = new JarFile(jarFilePath);
List fileNames = FileUtils.listFiles(jarFile, "Mapper.xml");
if (fileNames != null && fileNames.size() > 0) {
for (String fileName : fileNames) {
InputStream inputStream = jarFile.getInputStream(jarFile.getJarEntry(fileName));
parseMapperFile(inputStream);
}
}
jarFile.close();
} else {
log.error("mapper dir is in unsurport protocol");
}
} else {
log.error("can not find mapper dir");
}
} catch (Exception e) {
log.error("解析mapper文件异常", e);
throw new RuntimeException("解析mapper文件异常");
}
}
}
private static void parseMapperFile(InputStream inputStream) throws Exception {
XPathParser parser = new XPathParser(inputStream,true, null, new XMLMapperEntityResolver());
XNode evalNode = parser.evalNode("/mapper");
String mapperClass = evalNode.getStringAttribute("namespace");
String entityClass = null;
EntityInfo entityInfo = null;
List children = evalNode.getChildren();
for (XNode xNode : children) {
if("resultMap".equals(xNode.getName()) && "BaseResultMap".equals(xNode.getStringAttribute("id"))){
entityClass = xNode.getStringAttribute("type");
entityInfo = new EntityInfo(mapperClass, entityClass);
if(entityInfo.getMapperClass() == null){
log.error("------{}或{}配置路径不正确,请检查对应mapper文件------",entityClass,mapperClass);
}
entityInfos.add(entityInfo);
//
List resultNodes = xNode.getChildren();
for (XNode xNode2 : resultNodes) {
parseResultNode(entityInfo,xNode2);
}
}
}
for (XNode xNode : children) {
if ("select|insert|update|delete".contains(xNode.getName().toLowerCase())) {
String sql = parseSql(xNode);
entityInfo.addSql(xNode.getStringAttribute("id"), sql);
}
}
}
private static void parseResultNode(EntityInfo entityInfo,XNode node){
MapResultItem resultItem = new MapResultItem();
resultItem.setEntityName(entityInfo.getEntityClass().getName());
resultItem.setTableName(entityInfo.getTableName());
resultItem.setColumnName(node.getStringAttribute("column"));
resultItem.setPrimaryKey("id".equals(node.getName().toLowerCase()));
resultItem.setPropertyName(node.getStringAttribute("property"));
resultItem.setType(node.getStringAttribute("jdbcType"));
//
Map resultRalate = caches.get(resultItem.getEntityName());
if(resultRalate == null){
resultRalate = new HashMap();
caches.put(resultItem.getEntityName(), resultRalate);
}
resultRalate.put(resultItem.getColumnName(), resultItem.getPropertyName());
//
List list = entityRalateItems.get(resultItem.getEntityName());
if(list == null){
list = new ArrayList<>();
entityRalateItems.put(resultItem.getEntityName(), list);
}
list.add(resultItem);
//
List list2 = tableRalateItems.get(resultItem.getEntityName());
if(list2 == null){
list2 = new ArrayList<>();
tableRalateItems.put(resultItem.getTableName(), list2);
}
list2.add(resultItem);
//
List tmplist3 = namespaceRalateColumns.get(entityInfo.getMapperClass().getName());
if(tmplist3 == null){
tmplist3 = new ArrayList<>();
namespaceRalateColumns.put(entityInfo.getMapperClass().getName(), tmplist3);
}
tmplist3.add(resultItem.getColumnName());
}
private static String parseSql(XNode node) {
StringBuilder sql = new StringBuilder();
NodeList children = node.getNode().getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
XNode child = node.newXNode(children.item(i));
String data = child.getStringBody("");
sql.append(data);
}
return sql.toString().replaceAll("\\n+\\s+", "").replaceAll("(<\\!\\[CDATA\\[)|(\\]\\]>)", "");
}
}