package org.nutz.dao.impl.jdbc; import java.lang.reflect.Array; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.nutz.dao.Chain; import org.nutz.dao.entity.Entity; import org.nutz.dao.impl.sql.NutStatement; import org.nutz.dao.jdbc.ValueAdaptor; import org.nutz.dao.pager.Pager; 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.dao.util.Pojos; import org.nutz.lang.Lang; public class NutPojo extends NutStatement implements Pojo { private PojoCallback before; private PojoCallback after; /** * 参数表 */ private LinkedList<Object> params; /** * 缓存语句共包括的参数数量 */ private int _pmnum; /** * 当前操作对象 */ private Object obj; /** * 供子类访问的语句元素 */ protected ArrayList<PItem> items; public NutPojo() { super(); params = new LinkedList<Object>(); items = new ArrayList<PItem>(6); _pmnum = -1; append(Pojos.Items.sqlType()); } public ValueAdaptor[] getAdaptors() { ValueAdaptor[] adaptors = new ValueAdaptor[_params_count()]; int i = 0; for (PItem item : items) i = item.joinAdaptor(getEntity(), adaptors, i); return adaptors; } public Object[][] getParamMatrix() { Object[][] re; /* * 木有参数对象,但是有参数,循环一下,看看元素们会给出什么样的参数 */ if (_params_count() > 0 && params.isEmpty()) { re = new Object[1][_params_count()]; int i = 0; for (PItem item : items) i = item.joinParams(getEntity(), null, re[0], i); } /* * 依照参数列表循环获取参数矩阵 */ else { re = new Object[params.size()][_params_count()]; int row = 0; for (Object obj : params) { int i = 0; for (PItem item : items) i = item.joinParams(getEntity(), obj, re[row], i); row++; } } return re; } public String toPreparedStatement() { StringBuilder sb = new StringBuilder(); for (PItem item : items) item.joinSql(getEntity(), sb); return sb.toString(); } public void onBefore(Connection conn) throws SQLException { if (null != before) before.invoke(conn, null, this); } public void onAfter(Connection conn, ResultSet rs) throws SQLException { if (null != after) getContext().setResult(after.invoke(conn, rs, this)); } public Pojo setBefore(PojoCallback before) { this.before = before; return this; } public Pojo setAfter(PojoCallback after) { this.after = after; return this; } public Pojo setPager(Pager pager) { this.getContext().setPager(pager); return this; } public Pojo addParamsBy(Object obj) { if (null == obj) return this; // 集合 if (obj instanceof Collection<?>) for (Object ele : (Collection<?>) obj) addParamsBy(ele); // 数组 else if (obj.getClass().isArray()) { int len = Array.getLength(obj); for (int i = 0; i < len; i++) addParamsBy(Array.get(obj, i)); } // 链: 变成 Map else if (obj instanceof Chain) params.add(((Chain) obj).updateBy(this.getEntity()).toMap()); // 迭带器 : TODO 以后是不是考虑 params 也变成迭代器,这样可以允许无限多的对象被执行 ... else if (obj instanceof Iterator<?>) { Iterator<?> it = (Iterator<?>) obj; while (it.hasNext()) addParamsBy(it.next()); } // 其他对象,直接保存,占一行 else params.add(obj); return this; } public Object getLastParams() { return params.isEmpty() ? null : params.getLast(); } public List<Object> params() { return params; } public Object getOperatingObject() { return obj; } public Pojo setOperatingObject(Object obj) { this.obj = obj; return this; } public Pojo clear() { this.params.clear(); return this; } public Pojo append(PItem... itemAry) { if (null != itemAry) for (PItem item : itemAry) { if (null != item) { items.add(item); item.setPojo(this); } } return this; } public Pojo insertFirst(PItem... itemAry) { items.addAll(0, Lang.list(itemAry)); for (PItem pi : itemAry) pi.setPojo(this); return this; } public Pojo setItem(int index, PItem pi) { items.set(index, pi); pi.setPojo(this); return this; } public PItem getItem(int index) { return items.get(index); } public Pojo removeItem(int index) { items.remove(index); return this; } @Override public NutPojo setSqlType(SqlType sqlType) { return (NutPojo) super.setSqlType(sqlType); } public String toString() { if (SqlType.RUN == this.getSqlType()) { return this.getSqlType().name() + (null == before ? "" : " :before{...}") + (null == after ? "" : " :after{...}"); } return super.toString(); } public Pojo duplicate() { throw Lang.noImplement(); } private int _params_count() { if (_pmnum < 0) { _pmnum = 0; Entity<?> en = getEntity(); for (PItem item : items) { _pmnum += item.paramCount(en); } } return _pmnum; } }