Skip to content

Instantly share code, notes, and snippets.

@wendal
Created January 3, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wendal/14a0a84b4dbf280e6faa to your computer and use it in GitHub Desktop.
Save wendal/14a0a84b4dbf280e6faa to your computer and use it in GitHub Desktop.
基于XML配置NutDao的Entity, 未测试代码, 正式代码会出现在nutz主库或nutzmore项目.
package org.nutz.dao.impl.entity.xml;
public class IotUser {
private long id;
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private String location;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://nutzam.com/schema/entities" targetNamespace="http://nutzam.com/schema/entities" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="nutz-mapping">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="entity" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="coldefine" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="type" type="xsd:string"></xsd:attribute>
<xsd:attribute name="width" type="xsd:integer"></xsd:attribute>
<xsd:attribute name="precision" type="xsd:integer"></xsd:attribute>
<xsd:attribute name="notNull" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="unsigned" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="auto" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="customType"></xsd:attribute>
<xsd:attribute name="insert" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="update" type="xsd:boolean"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="prev" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="sql" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="el" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="next" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="sql" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="el" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="column" type="xsd:string"></xsd:attribute>
<xsd:attribute name="auto" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="name" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="name" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="coldefine" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="type" type="xsd:string"></xsd:attribute>
<xsd:attribute name="width" type="xsd:integer"></xsd:attribute>
<xsd:attribute name="precision" type="xsd:integer"></xsd:attribute>
<xsd:attribute name="notNull" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="unsigned" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="auto" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="customType"></xsd:attribute>
<xsd:attribute name="insert" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="update" type="xsd:boolean"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="prev" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="sql" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="el" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="next" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="sql" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="el" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="column" type="xsd:string"></xsd:attribute>
<xsd:attribute name="name" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="field" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="coldefine" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="type" type="xsd:string"></xsd:attribute>
<xsd:attribute name="width" type="xsd:integer"></xsd:attribute>
<xsd:attribute name="precision" type="xsd:integer"></xsd:attribute>
<xsd:attribute name="notNull" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="unsigned" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="auto" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="customType"></xsd:attribute>
<xsd:attribute name="insert" type="xsd:boolean"></xsd:attribute>
<xsd:attribute name="update" type="xsd:boolean"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="prev" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="sql" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="el" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="next" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="sql" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="el" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="db"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="column" type="xsd:string"></xsd:attribute>
<xsd:attribute name="name" type="xsd:string" use="required"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="one" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="target" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="field" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="key" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="many" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="target" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="field" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="key" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="manymany" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="target" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="relation" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="from" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="to" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="key" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="index" maxOccurs="unbounded" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="fields" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="unique" type="xsd:boolean"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="type" type="xsd:string" use="required"></xsd:attribute>
<xsd:attribute name="table" type="xsd:string"></xsd:attribute>
<xsd:attribute name="view" type="xsd:string"></xsd:attribute>
<xsd:attribute name="comment" type="xsd:string"></xsd:attribute>
<xsd:attribute name="pks" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="package" type="xsd:string"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<?xml version="1.0" encoding="UTF-8"?>
<p:nutz-mapping package="org.nutz.dao.impl.entity.xml" xmlns:p="http://nutzam.com/schema/entities" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://nutzam.com/schema/entities nutz-dao-0.1.xsd ">
<entity comment="" pks="" table="t_iot_user" type="IotUser" view="">
<id/>
<name/>
<field name="age"></field>
<field column="loc" name="location">
<coldefine auto="true" customType="" insert="true" notNull="true" precision="0" type="" unsigned="true" update="true" width="0"/>
</field>
<one field="level" name="level" target="IotUserLevel"/>
<many field="userId" name="devices" target=""/>
<manymany name="devices" from="uid" relation="user_device" target="IotDevice" to="did"/>
<index fields="age" name="age" unique="true"/>
</entity>
</p:nutz-mapping>
package org.nutz.dao.impl.entity.xml;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.nutz.dao.DB;
import org.nutz.dao.DaoException;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.entity.EntityMaker;
import org.nutz.dao.entity.MacroType;
import org.nutz.dao.entity.MappingField;
import org.nutz.dao.entity.annotation.ColType;
import org.nutz.dao.impl.EntityHolder;
import org.nutz.dao.impl.entity.FieldMacroInfo;
import org.nutz.dao.impl.entity.NutEntity;
import org.nutz.dao.impl.entity.NutEntityIndex;
import org.nutz.dao.impl.entity.field.ManyLinkField;
import org.nutz.dao.impl.entity.field.ManyManyLinkField;
import org.nutz.dao.impl.entity.field.NutMappingField;
import org.nutz.dao.impl.entity.field.OneLinkField;
import org.nutz.dao.impl.entity.info.LinkInfo;
import org.nutz.dao.impl.entity.macro.ElFieldMacro;
import org.nutz.dao.impl.entity.macro.SqlFieldMacro;
import org.nutz.dao.jdbc.JdbcExpert;
import org.nutz.dao.jdbc.Jdbcs;
import org.nutz.dao.sql.Pojo;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.Xmls;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.resource.NutResource;
import org.nutz.resource.Scans;
import org.nutz.trans.Trans;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* 基于XML配置Entity
* @author wendal(wendal1985@gmail.com)
*
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class XmlEntityMaker implements EntityMaker {
private static final Log log = Logs.get();
Map<String, Entity> map = new ConcurrentHashMap<String, Entity>();
DocumentBuilder builder;
private DataSource datasource;
private JdbcExpert expert;
private EntityHolder holder;
protected Map<String, List<Element>> pendingLinks = new ConcurrentHashMap<String, List<Element>>();
public XmlEntityMaker(DataSource datasource, JdbcExpert expert, EntityHolder holder) throws ParserConfigurationException {
builder = Lang.xmls();
this.datasource = datasource;
this.expert = expert;
this.holder = holder;
}
public <T> Entity<T> make(Class<T> type) {
return map.get(type); // 注意, 这里是单纯从缓存中获取已有的Entity, 因为是基于XML的
}
public void setPaths(String ... paths) throws IOException, SAXException {
for (String path : paths) {
addPath(path);
}
try {
verify();
} catch (DaoException e) {
log.info("some relation pending are not complete", e);
}
}
public void addPath(String path) throws IOException, SAXException {
List<NutResource> files = Scans.me().scan(path, ".xml$");
if (files.isEmpty())
return;
for (NutResource resource : files) {
log.debug("load entity xml --> " + resource.getName());
add(resource.getInputStream());
}
}
public void add(InputStream ins) throws IOException, SAXException {
add(builder.parse(ins));
}
public void add(Document document) {
document.normalizeDocument();
Element top = document.getDocumentElement();
if (!top.getNodeName().endsWith("nutz-mapping")) { // 没有nutz-mapping, 自然没啥好说的了
log.info("skip xml without nutz-mapping");
return;
}
String topPackageName = top.getAttribute("package");
for (Element ele : Xmls.children(top, "entity")) { // 一个XML中允许包含多个entity描述
addXmlEntity(ele, topPackageName);
}
}
public void addXmlEntity(final Element ele, String topPackageName) {
String type = ele.getAttribute("type");
if (Strings.isBlank(type)) // xsd有约束,这里再检查一次
throw new DaoException("entity without type!!");
Class<?> klass = null;
try {
klass = loadClass(topPackageName, type); // 尝试载入对应的类
} catch (ClassNotFoundException e) {
throw new DaoException("entity type ClassNotFound : " + type, e);
}
NutEntity<?> en = new NutEntity(klass);
String tableName = null;
if (Strings.isBlank(ele.getAttribute("table"))) {
tableName = Strings.lowerWord(klass.getSimpleName(), '_');
log.warnf("No @Table found, fallback to use table name='%s' for type '%s'", tableName, klass.getName());
} else {
tableName = ele.getAttribute("table");
}
String viewName = Strings.isBlank(ele.getAttribute("view")) ? tableName : ele.getAttribute("view");
en.setTableName(tableName);
en.setViewName(viewName);
// 表注解
String tableComment = ele.getAttribute("comment");
if (!Strings.isBlank(tableComment))
en.setTableComment(tableComment);
// TODO 支持default, readonly 注解所对应的xml配置
// 先塞进去, 主要是为了避免1对1的自我映射
holder.set(en);
map.put(type, en);
// 下面开始处理字段,索引,等等
for (Element e : Xmls.children(ele)) {
String ename = e.getNodeName();
if ("id".equals(ename)) {
addField(en, e, true, false);
} else if ("name".equals(ename)) {
addField(en, e, false, true);
} else if ("field".equals(ename)) {
addField(en, e, false, false);
} else if ("index".equals(ename)) {
String indexName = e.getAttribute("name");
if (Strings.isBlank(indexName)) {
throw new DaoException("index must have a name, entity=" + type);
}
String indexFields = e.getAttribute("fields");
if (Strings.isBlank(indexFields)) {
throw new DaoException("index must have fields, entity=" + type);
}
boolean indexUnique = "true".equals(e.getAttribute("unique"));
NutEntityIndex eIndex = new NutEntityIndex();
eIndex.setName(ename);
eIndex.setUnique(indexUnique);
String[] names = Strings.splitIgnoreBlank(indexFields, ",");
for (String fieldName : names) {
MappingField field = en.getField(fieldName);
if (field == null)
throw new DaoException("index refer not-exist field, entity=" + type + ", field=" + fieldName);
en.addIndex(eIndex);
}
} else if ("one".equals(ename) || "many".equals(ename) || "manymany".equals(ename)) {
String target = e.getAttribute("target");
Class<?> targetClass = null;;
try {
targetClass = loadClass(topPackageName, target);
} catch (ClassNotFoundException e1) {
throw new DaoException("relation ClassNotFound entity=" + en.getType().getName() + ", relation class=" + target);
}
Entity relationEntity = map.get(targetClass);
if (relationEntity == null) {
List<Element> list = pendingLinks.get(en.getType().getName());
if (list == null) {
list = new ArrayList<Element>();
pendingLinks.put(en.getType().getName(), list);
log.debug("add pending relation mapping " + e);
}
e.setAttribute("fullClassName", targetClass.getName());
list.add(e);
} else {
addRelation(en, relationEntity, e);
}
}
}
// 处理一下复合主键
String pks = ele.getAttribute("pks");
if (!Strings.isBlank(pks)) {
String[] tmp = Strings.splitIgnoreBlank(pks, ",");
en.checkCompositeFields(tmp);
}
if (null != datasource && null != expert) {
_checkupEntityFieldsWithDatabase(en);
}
}
public void verify() throws DaoException {
if (pendingLinks.isEmpty())
return;
for (Entry<String, List<Element>> pending : pendingLinks.entrySet()) {
try {
NutEntity en = (NutEntity) map.get(loadClass(null, pending.getKey()));
Iterator<Element> it = pending.getValue().iterator();
while (it.hasNext()) {
Element element = it.next();
NutEntity relation = (NutEntity) map.get(loadClass(null, element.getAttribute("fullClassName")));
addRelation(en, relation, element);
it.remove();
}
} catch (ClassNotFoundException e) {
throw Lang.impossible();
}
pendingLinks.remove(pending.getKey());
}
}
protected void addRelation(NutEntity<?> en, Entity relationEntity, Element e) {
LinkInfo info = new LinkInfo();
info.name = e.getAttribute("name");
try {
info.fieldType = en.getMirror().getField(info.name).getType();
} catch (NoSuchFieldException e1) {
throw new DaoException("field not exist. entity=" + en.getType() + ",field=" + info.name);
}
info.injecting = en.getMirror().getInjecting(info.name);
info.ejecting = en.getMirror().getEjecting(info.name);
String rname = e.getNodeName();
if ("one".equals(rname) || "many".equals(rname)) {
String fieldName = e.getAttribute("field");
MappingField mf = en.getField(fieldName);
if (fieldName == null || mf == null) {
throw new DaoException(String.format("%s <--> %s by field(%s) , but not exist", en.getType(), relationEntity.getType(), fieldName));
}
String key = e.getAttribute("key");
MappingField mfKey = null;
if (!Strings.isBlank(key)) {
mfKey = relationEntity.getField(key);
} else {
mfKey = mf.getTypeMirror().isIntLike() ? relationEntity.getIdField() : relationEntity.getNameField();
}
if (mfKey == null) {
throw new DaoException(String.format("%s <--> %s by field(%s) , but not exist", en.getType(), relationEntity.getType(), mfKey));
}
if ("one".equals(rname)) {
OneLinkField one = new OneLinkField(en, holder, info, relationEntity.getClass(), mf, mfKey);
en.addLinkField(one);
} else {
ManyLinkField many = new ManyLinkField(en, holder, info, relationEntity.getClass(), mf, mfKey);
en.addLinkField(many);
}
} else if ("manymany".equals(rname)) {
// 多对多
String from = e.getAttribute("from");
String to = e.getAttribute("to");
String relation = e.getAttribute("relation");
String key = e.getAttribute("key");
ManyManyLinkField manymany = new ManyManyLinkField(en, holder, info, relationEntity.getType(), from, to, relation, key);
en.addLinkField(manymany);
}
}
protected void addField(NutEntity en, Element ele, boolean isId, boolean isName) {
NutMappingField mf = new NutMappingField(en);
// 处理name属性
String name = ele.getAttribute("name");
if (isId) {
mf.setAsId();
if (!"false".equals(ele.getAttribute("auto")))
mf.setAsAutoIncreasement();
if (Strings.isBlank(name))
mf.setName("id");
else
mf.setName(name);
} else if (isName) {
mf.setAsName();
if (Strings.isBlank(name))
mf.setName("name");
else
mf.setName(name);
} else {
if (Strings.isBlank(name))
throw new DaoException("field must have a name attribute, entity=" + en.getType().getName());
mf.setName(name);
}
name = mf.getName();
try {
Field field = en.getMirror().getField(name);
mf.setType(field.getType());
} catch (NoSuchFieldException e) {
throw new DaoException("not such field in entity=" + en.getType().getName() + ", field=" + name);
}
// 处理column属性
String columnName = ele.getAttribute("column");
if (!Strings.isBlank(columnName))
mf.setColumnName(columnName);
else
mf.setColumnName(name);
// 处理comment属性
if (!Strings.isBlank(ele.getAttribute("comment"))) {
mf.setColumnComment(ele.getAttribute("comment"));
en.setHasColumnComment(true);
}
// 处理一下coldefine, prev, next节点
boolean flag = true;
for (Element e : Xmls.children(ele)) {
String ename = e.getNodeName();
if ("coldefine".equalsIgnoreCase(ename)) {
flag = false;
addColDefine(mf, e);
} else if ("prev".equalsIgnoreCase(ename)) {
_makeMacro(en, mf, e, true);
} else if ("next".equals(ename)) {
_makeMacro(en, mf, e, false);
}
}
if (flag) {
Jdbcs.guessEntityFieldColumnType(mf);
}
// 字段值的适配器
if (expert != null)
mf.setAdaptor(expert.getAdaptor(mf));
mf.setInjecting(en.getMirror().getInjecting(name));
mf.setEjecting(en.getMirror().getEjecting(name));
en.addMappingField(mf);
}
protected void addColDefine(NutMappingField mf, Element ele) {
if (hasAttr(ele, "type"))
mf.setColumnType(ColType.valueOf(ele.getAttribute("type")));
if (hasAttr(ele, "width"))
mf.setWidth(Integer.parseInt(ele.getAttribute("width")));
if (mf.getWidth() == 0 && mf.getColumnType() == ColType.VARCHAR)
mf.setWidth(50);
if (hasAttr(ele, "precision"))
mf.setPrecision(Integer.parseInt(ele.getAttribute("precision")));
if ("true".equals(ele.getAttribute("notNull")))
mf.setAsNotNull();
if ("true".equals(ele.getAttribute("unsigned")))
mf.setAsUnsigned();
// 无视auto设置
// --------------
if (hasAttr(ele, "customType"))
mf.setCustomDbType(ele.getAttribute("customType"));
if ("false".equals(ele.getAttribute("insert")))
mf.setInsert(false);
if ("false".equals(ele.getAttribute("update")))
mf.setUpdate(false);
}
protected boolean hasAttr(Element ele, String attrName) {
return !Strings.isBlank(ele.getAttribute(attrName));
}
protected void _makeMacro(NutEntity en, NutMappingField mf, Element ele, boolean isPrev) {
List<FieldMacroInfo> list = new ArrayList<FieldMacroInfo>();
for(Element e : Xmls.children(ele)) {
String nodeName = e.getNodeName();
DB db = hasAttr(e, "db") ? DB.OTHER : DB.valueOf(e.getAttribute("db"));
if ("sql".equals(nodeName)) {
FieldMacroInfo sql = new FieldMacroInfo(MacroType.SQL, db, Xmls.getText(e));
list.add(sql);
} else if ("el".equals(nodeName)) {
FieldMacroInfo el = new FieldMacroInfo(MacroType.EL, db, Xmls.getText(e));
list.add(el);
}
};
if (isPrev)
en.addBeforeInsertMacro(__macro(mf, list));
else
en.addAfterInsertMacro(__macro(mf, list));
}
private void _checkupEntityFieldsWithDatabase(NutEntity<?> en) {
Connection conn = null;
try {
conn = Trans.getConnectionAuto(datasource);
expert.setupEntityField(conn, en);
}
catch (Exception e) {
if (log.isDebugEnabled())
log.debugf("Fail to setup '%s'(%s) by DB, because: (%s)'%s'",
en.getType().getName(),
en.getTableName(),
e.getClass().getName(),
e.getMessage());
}
finally {
Trans.closeConnectionAuto(conn);
}
}
private Pojo __macro(MappingField ef, List<FieldMacroInfo> infoList) {
FieldMacroInfo theInfo = null;
// 根据当前数据库,找到合适的宏
for (FieldMacroInfo info : infoList) {
if (DB.OTHER == info.getDb()) {
theInfo = info;
} else if (info.getDb().name().equalsIgnoreCase(expert.getDatabaseType())) {
theInfo = info;
break;
}
}
// 如果找到,增加
if (null != theInfo) {
if (theInfo.isEl())
return new ElFieldMacro(ef, theInfo.getValue());
else
return new SqlFieldMacro(ef, theInfo.getValue());
}
return null;
}
protected Class<?> loadClass(String topPackageName, String type) throws ClassNotFoundException {
try {
return Class.forName(type);
} catch (ClassNotFoundException e) {
if (!Strings.isBlank(topPackageName))
return Class.forName(topPackageName + "." + type);
throw e;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment