package org.nutz.dao.impl.sql; import org.nutz.dao.DaoException; import org.nutz.dao.FieldMatcher; import org.nutz.dao.entity.Entity; import org.nutz.dao.entity.LinkField; import org.nutz.dao.entity.LinkVisitor; import org.nutz.dao.entity.MappingField; import org.nutz.dao.impl.sql.pojo.NoParamsPItem; import org.nutz.dao.jdbc.JdbcExpert; import org.nutz.dao.sql.Pojo; import org.nutz.dao.sql.PojoCallback; import org.nutz.dao.sql.PojoMaker; import org.nutz.dao.sql.SqlType; import org.nutz.dao.util.Pojos; import org.nutz.lang.*; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; import java.util.List; import java.util.Map; public class NutPojoMaker implements PojoMaker { private JdbcExpert expert; public NutPojoMaker(JdbcExpert expert) { this.expert = expert; } public Pojo makePojo(SqlType type) { return expert.createPojo(type); } public Pojo makeInsert(final Entity<?> en) { Pojo pojo = Pojos.pojo(expert, en, SqlType.INSERT); pojo.setEntity(en); pojo.append(Pojos.Items.entityTableName()); pojo.append(Pojos.Items.insertFields()); pojo.append(Pojos.Items.insertValues()); if (expert.isSupportAutoIncrement()) { MappingField mf = en.getIdField(); if (mf != null && mf.isAutoIncreasement()) { if (expert.isSupportGeneratedKeys()) { pojo.setAfter(new GeneratedKeys()); pojo.getContext().attr("RETURN_GENERATED_KEYS", true); } } } return pojo; } public Pojo makeUpdate(Entity<?> en, Object refer) { Pojo pojo = Pojos.pojo(expert, en, SqlType.UPDATE); pojo.setEntity(en); pojo.append(Pojos.Items.entityTableName()); pojo.append(Pojos.Items.updateFields(refer)); return pojo; } public Pojo makeQuery(Entity<?> en) { Pojo pojo = Pojos.pojo(expert, en, SqlType.SELECT); pojo.setEntity(en); pojo.append(Pojos.Items.queryEntityFields()); pojo.append(Pojos.Items.wrap("FROM")); pojo.append(Pojos.Items.entityViewName()); return pojo; } public Pojo makeQuery(String tableName) { return makeQuery(tableName, "*"); } public Pojo makeQuery(String tableName, String fields) { String[] ss = tableName.split(":"); // String idFieldName = ss.length > 1 ? ss[1] : "*";//按id字段来统计,比较快 Pojo pojo = makePojo(SqlType.SELECT); // pojo.append(Pojos.Items.wrap(idFieldName));//与org.nutz.dao.test.normal.QueryTest.query_records_pager()冲突 pojo.append(Pojos.Items.wrap(fields)); pojo.append(Pojos.Items.wrap("FROM")); pojo.append(Pojos.Items.wrap(ss[0])); return pojo; } public Pojo makeDelete(Entity<?> en) { Pojo pojo = Pojos.pojo(expert, en, SqlType.DELETE); pojo.setEntity(en); pojo.append(Pojos.Items.wrap("FROM")); pojo.append(Pojos.Items.entityTableName()); return pojo; } public Pojo makeDelete(String tableName) { Pojo pojo = makePojo(SqlType.DELETE); pojo.append(Pojos.Items.wrap("FROM")); pojo.append(Pojos.Items.wrap(tableName)); return pojo; } public Pojo makeFunc(String tableName, String funcName, String colName) { Pojo pojo = makePojo(SqlType.SELECT); pojo.append(Pojos.Items.wrapf("%s(%s) FROM %s", funcName, colName, tableName)); return pojo; } static class GeneratedKeys implements PojoCallback { public Object invoke(Connection conn, ResultSet rs, final Pojo pojo, Statement stmt) throws SQLException { final ResultSet _rs = stmt.getGeneratedKeys(); Object obj = pojo.getOperatingObject(); if (obj instanceof Map) { obj = Arrays.asList(obj); } Lang.each(obj, new Each<Object>() { public void invoke(int index, Object ele, int length) throws ExitLoop, ContinueLoop, LoopException { try { if (!_rs.next()) throw new ExitLoop(); Object key = _rs.getObject(1); pojo.getEntity().getIdField().setValue(ele, key); } catch (SQLException e) { throw new DaoException(e); } } }); return pojo.getOperatingObject(); } } @Override public Pojo makeQueryByJoin(final Entity<?> en, String regex) { final Pojo pojo = Pojos.pojo(expert, en, SqlType.SELECT); pojo.setEntity(en); pojo.append(new QueryJoinFeilds(en, true)); final int[] index = new int[1]; en.visitOne(null, regex, new LinkVisitor() { public void visit(Object obj, LinkField lnk) { pojo.append(Pojos.Items.wrap(",")); pojo.append(new QueryJoinFeilds(lnk.getLinkedEntity(), false)); index[0]++; } }); pojo.append(Pojos.Items.wrap("FROM")); pojo.append(Pojos.Items.entityViewName()); index[0] = 0; en.visitOne(null, regex, new LinkVisitor() { public void visit(Object obj, LinkField lnk) { Entity<?> lnkEntity = lnk.getLinkedEntity(); String LJ = String.format("LEFT JOIN %s ON %s.%s = %s.%s", lnkEntity.getTableName(), en.getTableName(), lnk.getHostField().getColumnNameInSql(), lnkEntity.getTableName(), lnk.getLinkedField().getColumnNameInSql()); pojo.append(Pojos.Items.wrap(LJ)); index[0]++; } }); return pojo; } @SuppressWarnings("serial") protected static class QueryJoinFeilds extends NoParamsPItem { protected Entity<?> en; protected boolean main; public QueryJoinFeilds(Entity<?> en, boolean main) { this.en = en; this.main = main; } public void joinSql(Entity<?> en, StringBuilder sb) { en = this.en; FieldMatcher fm = getFieldMatcher(); List<MappingField> efs = _en(en).getMappingFields(); int old = sb.length(); for (MappingField ef : efs) { if (fm == null || fm.match(ef.getName())) { sb.append(en.getTableName()).append(".").append(ef.getColumnNameInSql()).append(" as "); if (!main) sb.append(en.getTableName()).append("_z_"); sb.append(ef.getColumnNameInSql()).append(','); } } if (sb.length() == old) throw Lang.makeThrow("No columns be queryed: '%s'", _en(en)); sb.setCharAt(sb.length() - 1, ' '); } } }