package org.nutz.dao.util; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import org.nutz.dao.Chain; import org.nutz.dao.Condition; import org.nutz.dao.DaoException; import org.nutz.dao.FieldFilter; import org.nutz.dao.FieldMatcher; import org.nutz.dao.entity.Entity; import org.nutz.dao.entity.EntityField; import org.nutz.dao.entity.MappingField; import org.nutz.dao.entity.PkType; import org.nutz.dao.impl.jdbc.NutPojo; import org.nutz.dao.impl.sql.pojo.ConditionPItem; import org.nutz.dao.impl.sql.pojo.EntityTableNamePItem; import org.nutz.dao.impl.sql.pojo.EntityViewNamePItem; import org.nutz.dao.impl.sql.pojo.InsertFieldsPItem; import org.nutz.dao.impl.sql.pojo.InsertValuesPItem; import org.nutz.dao.impl.sql.pojo.PkConditionPItem; import org.nutz.dao.impl.sql.pojo.QueryEntityFieldsPItem; import org.nutz.dao.impl.sql.pojo.SingleColumnCondtionPItem; import org.nutz.dao.impl.sql.pojo.SqlTypePItem; import org.nutz.dao.impl.sql.pojo.StaticPItem; import org.nutz.dao.impl.sql.pojo.UpdateFieldsByChainPItem; import org.nutz.dao.impl.sql.pojo.UpdateFieldsPItem; import org.nutz.dao.jdbc.JdbcExpert; import org.nutz.dao.jdbc.ValueAdaptor; import org.nutz.dao.pager.Pager; import org.nutz.dao.sql.Criteria; import org.nutz.dao.sql.PItem; import org.nutz.dao.sql.Pojo; import org.nutz.dao.sql.PojoCallback; import org.nutz.dao.sql.SqlType; import org.nutz.lang.Lang; import org.nutz.lang.Strings; public abstract class Pojos { // ========================================================== // 以下是创建 POJO 语句元素的帮助方法 public static class Items { public static PItem sqlType() { return new SqlTypePItem(); } public static PItem entityTableName() { return new EntityTableNamePItem(); } public static PItem entityViewName() { return new EntityViewNamePItem(); } public static PItem wrap(String str) { return new StaticPItem(str); } public static PItem wrapf(String fmt, Object... args) { return new StaticPItem(String.format(fmt, args)); } public static PItem insertFields() { return new InsertFieldsPItem(); } public static PItem insertValues() { return new InsertValuesPItem(); } public static PItem updateFields(Object refer) { return new UpdateFieldsPItem(refer); } public static PItem updateFieldsBy(Chain chain) { return new UpdateFieldsByChainPItem(chain); } public static PItem queryEntityFields() { return new QueryEntityFieldsPItem(); } public static PItem cndId(Entity<?> en, Number id) { MappingField mappingField = en.getIdField(); if (mappingField == null) throw new DaoException("expect @Id but NOT found. " + en.getType().getName()); return cndColumn(mappingField, id); } public static PItem cndName(Entity<?> en, String name) { MappingField mappingField = en.getNameField(); if (mappingField == null) throw new DaoException("expect @Name but NOT found. " + en.getType().getName()); return cndColumn(mappingField, name); } public static PItem cndColumn(MappingField mappingField, Object def) { SingleColumnCondtionPItem re = new SingleColumnCondtionPItem(mappingField, def); re.setCasesensitive(mappingField.isCasesensitive()); return re; } public static PItem cndColumn(String colName, MappingField mappingField, Object def) { return new SingleColumnCondtionPItem( colName, mappingField.getTypeClass(), mappingField.getAdaptor(), def); } public static PItem cndPk(Entity<?> en, Object[] pks) { ValueAdaptor[] vas = new ValueAdaptor[en.getCompositePKFields().size()]; int i = 0; for (MappingField mf : en.getCompositePKFields()) vas[i++] = mf.getAdaptor(); return new PkConditionPItem(vas, pks); } public static PItem cndAuto(Entity<?> en, Object obj) { obj = Lang.first(obj); switch (en.getPkType()) { case ID: Number id = null != obj ? ((Number) en.getIdField().getValue(obj)) : null; return cndId(en, id); case NAME: String name = null != obj ? en.getNameField().getValue(obj).toString() : null; return cndName(en, name); case COMPOSITE: Object[] pks = null; if (null != obj) { pks = new Object[en.getCompositePKFields().size()]; int i = 0; for (EntityField ef : en.getCompositePKFields()) pks[i++] = ef.getValue(obj); } return cndPk(en, pks); default: if (Map.class.isAssignableFrom(en.getType())) { return null; // Map形式的话,不一定需要主键嘛 } throw Lang.makeThrow("Don't know how to make fetch key %s:'%s'", en.getType() .getName(), obj); } } public static PItem[] cnd(Condition cnd) { List<PItem> list = new LinkedList<PItem>(); if (null == cnd) {} // 高级条件 else if (cnd instanceof Criteria) { list.add((Criteria) cnd); } // 普通条件 else { list.add(new ConditionPItem(cnd)); } return list.toArray(new PItem[list.size()]); } public static Pager pager(Condition cnd) { if (null == cnd) { return null; } // 高级条件 else if (cnd instanceof Criteria) { return ((Criteria) cnd).getPager(); } // 普通条件 else { return null; } } } // 以上是创建 POJO 语句元素的帮助方法 // ========================================================== public static Pojo createRun(PojoCallback callback) { return new NutPojo().setSqlType(SqlType.RUN).setAfter(callback); } public static List<MappingField> getFieldsForInsert(Entity<?> en, FieldMatcher fm) { List<MappingField> re = new ArrayList<MappingField>(en.getMappingFields().size()); for (MappingField mf : en.getMappingFields()) { if (!mf.isAutoIncreasement() && !mf.isReadonly() && mf.isInsert()) if (null == fm || fm.match(mf.getName())) re.add(mf); } return re; } public static List<MappingField> getFieldsForUpdate(Entity<?> en, FieldMatcher fm, Object refer) { List<MappingField> re = new ArrayList<MappingField>(en.getMappingFields().size()); for (MappingField mf : en.getMappingFields()) { if (mf.isPk()) { if (en.getPkType() == PkType.ID && mf.isId()) continue; if (en.getPkType() == PkType.NAME && mf.isName()) continue; if (en.getPkType() == PkType.COMPOSITE && mf.isCompositePk()) continue; } if (mf.isReadonly() || mf.isAutoIncreasement() || !mf.isUpdate()) continue; else if (null != fm && null != refer && fm.isIgnoreNull() && null == mf.getValue(refer)) continue; if (null == fm || fm.match(mf.getName())) re.add(mf); } return re; } private static final Pattern ptn = Pattern.compile( "^(WHERE|ORDER BY)(.+)", Pattern.CASE_INSENSITIVE); public static String formatCondition(Entity<?> en, Condition cnd) { if (null != cnd) { String str = Strings.trim(cnd.toSql(en)); if (!ptn.matcher(str).find()) return "WHERE " + str; return str; } return ""; } public static Pojo pojo(JdbcExpert expert, Entity<?> en, SqlType type) { Pojo pojo = expert.createPojo(type); pojo.getContext().setFieldMatcher(FieldFilter.get(en.getType())); return pojo; } }