读书人

no sql jdbc orm[五-18]

发布时间: 2013-11-08 17:51:56 作者: rapoo

no sql jdbc orm[5-18]
最近几天在写的一个jdbc orm, 放上来交流学习~~

目标:
no sql, no map , no sql, no map...............................(省略一百遍 ).

约束&特点:
显示代理
操纵proxy domain getter/setter等于构建sql, 重构对象即重构sql
domain对象属性和column名字相同
domain有接口
domain是javabean
某些dao接口参数需要beanproxy(主要是update的接口)
基本没有级联orm


待实现:
多表查询
稍微复杂的sql生成
考虑local&remote Object cache,query cache...

dao example:

** * @version 2007-5-4 * @author xalinx at gmail dot com *  */public class UserDaoImpl extends DaoSupport<User, Long> implements UserDao {private final ParameterizedRowMapper<UserImpl> rowMapper = new AutoRowMapper<UserImpl>() {};public void deleteById(Long id) {// create proxyBeanMonitor<User> monitor = new BeanMonitor<User>();User proxy = monitor.proxy(new UserImpl());// proxy whereproxy.setId(id);monitor.eq();getSimpleDaoTemplate().proxyDelete(monitor);}public User findById(Long id) {// create proxyBeanMonitor<User> monitor = new BeanMonitor<User>();User proxy = monitor.proxy(new UserImpl());// proxy selectproxy.getId();proxy.getUsername();proxy.getPassword();proxy.getNickname();proxy.getCity();proxy.getProv();proxy.getUserStatus();proxy.getCreateTime();proxy.getModifyTime();// proxy whereproxy.setId(id);monitor.eq();return getSimpleDaoTemplate().proxyQueryObject(monitor, rowMapper);}public int findCount() {return getSimpleDaoTemplate().findCount(UserImpl.class);}public void store(User u) {// integrity validateif (u == null || u.getId() <= 0 || u.getUserStatus() < 0 || u.getUsername() == null || u.getPassword() == null|| u.getNickname() == null || u.getCreateTime() == null || u.getModifyTime() == null) {throw new DataIntegrityViolationException(u.toString());}BeanMonitor<User> monitor = new BeanMonitor<User>();User proxy = monitor.proxy(new UserImpl());// proxy insertproxy.setId(u.getId());proxy.setUsername(u.getUsername());proxy.setPassword(u.getPassword());proxy.setNickname(u.getNickname());proxy.setCity(u.getCity());proxy.setProv(u.getProv());proxy.setUserStatus(u.getUserStatus());proxy.setCreateTime(u.getCreateTime());proxy.setModifyTime(u.getModifyTime());// storegetSimpleDaoTemplate().proxyStore(monitor);}public void updateById(BeanMonitor<User> monitor) {User u = monitor.getBean();// integrity validateif (u == null || u.getId() <= 0) {throw new DataIntegrityViolationException(u.toString());}// proxy whereUser proxy = monitor.getProxy();monitor.where();proxy.setId(u.getId());monitor.eq();// updategetSimpleDaoTemplate().proxyUpdate(monitor, u.getId());}public BasePage<User> findPage(UserPageQuery pageQuery) {// create proxyBeanMonitor<User> monitor = new BeanMonitor<User>();User proxy = monitor.proxy(new UserImpl());// proxy selectproxy.getId();proxy.getUsername();proxy.getCreateTime();// proxy whereif (null != pageQuery.getUser().getCity()) {proxy.setCity(pageQuery.getUser().getCity());monitor.eq();}if (null != pageQuery.getEndCreateTime()) {proxy.setCreateTime(pageQuery.getEndCreateTime());monitor.and().leeq();}if (null != pageQuery.getStartCreateTime()) {proxy.setCreateTime(pageQuery.getStartCreateTime());monitor.and().gteq();}if (null != pageQuery.getUser().getUsername()) {proxy.setUsername(pageQuery.getUser().getUsername());monitor.and().like();}// query & orm & pagereturn getSimpleDaoTemplate().proxyQueryPage(monitor, rowMapper, pageQuery);}}
public abstract class AutoBeanHandler<T> implements ParameterizedHandler<T> {/** * The Class of beans produced by this handler. */private Class<T> type = null;/** * The RowProcessor implementation to use when converting rows into beans. */private RowProcessor convert = BasicRowProcessor.instance();public AutoBeanHandler() {type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];}public T handle(ResultSet rs, int rowNum) throws SQLException {return this.convert.toBean(rs, rowNum, type);}public List<T> handle(ResultSet rs) throws SQLException {return this.convert.toBeanList(rs, type);}}public abstract class AutoRowMapper<T> extends AutoBeanHandler<T> implements ParameterizedRowMapper<T> {public T mapRow(ResultSet rs, int rowNum) throws SQLException {return super.handle(rs, rowNum);}} /** * @author alin [xalinx at gmail dot com] * @date 2007-5-11 */public class BeanMonitor<E> {private E bean;private E proxy;private PropertyDescriptor[] allProperties;private List<String> readedPropertyNames;private List<String> writedPropertyNames;private List<Object> writedPropertyValues;private List<Condition> conditions;public E getBean() {return bean;}public E getProxy() {return proxy;}public List<String> getReadedPropertyNames() {return readedPropertyNames;}public List<String> getWritedPropertyNames() {return writedPropertyNames;}public List<Object> getWritedPropertyValues() {return writedPropertyValues;}public List<Condition> getConditions() {return conditions;}private void addReaded(String pName) {if (null == readedPropertyNames) {readedPropertyNames = new ArrayList<String>(allProperties.length * 3 / 2);}readedPropertyNames.add(pName);}private void addWrited(String pName, Object value) {if (null == writedPropertyNames) {writedPropertyNames = new ArrayList<String>(allProperties.length * 3 / 2);writedPropertyValues = new ArrayList<Object>(allProperties.length * 3 / 2);}writedPropertyNames.add(pName);writedPropertyValues.add(value);}private void addCondition(Condition cond) {if (null == conditions) {conditions = new ArrayList<Condition>(allProperties.length * 3 / 2);}conditions.add(cond);}@SuppressWarnings("unchecked")public E proxy(E bean) {this.bean = bean;Class cls = bean.getClass();BeanInfo bi;try {bi = Introspector.getBeanInfo(cls);} catch (IntrospectionException e) {throw new RuntimeException(e);}this.allProperties = bi.getPropertyDescriptors();this.proxy = (E) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new BeanHandler());return proxy;}private class BeanHandler implements InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object invokeResult = method.invoke(bean, args);for (int i = 0; i < allProperties.length; i++) {PropertyDescriptor pd = allProperties[i];// skip default class propertyif (pd.getName().equals("class")) {continue;}if (null != pd.getReadMethod() && pd.getReadMethod().getName().equals(method.getName())) {addReaded(pd.getName());break;} else if (null != pd.getWriteMethod() && pd.getWriteMethod().getName().equals(method.getName())) {// args[0] is suitable?addWrited(pd.getName(), args[0]);break;}}return invokeResult;}}/** * @return */public BeanMonitor<E> like() {addCondition(Condition.LIKE);return this;}/** * @return */public BeanMonitor<E> and() {addCondition(Condition.AND);return this;}/** * @return */public BeanMonitor<E> or() {addCondition(Condition.OR);return this;}/** * ( * * @return */public BeanMonitor<E> start() {addCondition(Condition.START);return this;}/** * } * * @return */public BeanMonitor<E> end() {addCondition(Condition.END);return this;}/** * = */public BeanMonitor<E> eq() {addCondition(Condition.EQ);return this;}/** * <= * * @return */public BeanMonitor<E> leeq() {addCondition(Condition.LE_EQ);return this;}/** * < * * @return */public BeanMonitor<E> le() {addCondition(Condition.LE);return this;}/** * >= * * @return */public BeanMonitor<E> gteq() {addCondition(Condition.GT_EQ);return this;}/** * > * * @return */public BeanMonitor<E> gt() {addCondition(Condition.GT);return this;}public BeanMonitor<E> isNotNull() {addCondition(Condition.IS_NOT_NULL);return this;}public BeanMonitor<E> isNull() {addCondition(Condition.IS_NULL);return this;}private int whereOffset = 0;/** * */public void where() {whereOffset = this.writedPropertyNames.size();}public int getWhereOffset() {return whereOffset;}}/** * @version 2007-5-17 * @author xalinx at gmail dot com * */public class SqlBuilder {private NameMapper nameMapper;public void setNameMapper(NameMapper nameMapper) {this.nameMapper = nameMapper;}private Dialect dialect;public void setDialect(Dialect dialect) {this.dialect = dialect;}public void setDialectFactory(DialectFactory factory) {setDialect(factory.getDialect());}public <T> QueryWrap buildLimitSelect(BeanMonitor<T> beanMonitor, int start, int size) {QueryWrap wrap = buildSelect(beanMonitor);boolean offset = 0 == start ? false : true;wrap.setSql(dialect.getLimitSql(wrap.getSql(), offset));wrap.setValues(dialect.getLimitArguments(start, size, wrap.getValues()));return wrap;}public <T> QueryWrap buildSelect(BeanMonitor<T> monitor) {String tableName = getTableName(monitor);List<String> columns = monitor.getReadedPropertyNames();int columnNum = columns.size();StringBuilder builder = new StringBuilder(128);builder.append("select ");for (int i = 0; i < columnNum; i++) {builder.append(columns.get(i));if (i < columnNum - 1) {builder.append(",");}}builder.append(" from ");builder.append(tableName);buildWhereExpression(monitor, builder);Object[] values = monitor.getWritedPropertyValues().toArray(ArrayKit.EMPTY_OBJECT_ARRAY);return new QueryWrap(builder.toString(), values);}public <T> QueryWrap buildDelete(BeanMonitor<T> monitor) {String tableName = getTableName(monitor);StringBuilder builder = new StringBuilder(128);builder.append("delete from ");builder.append(tableName);buildWhereExpression(monitor, builder);Object[] values = monitor.getWritedPropertyValues().toArray(ArrayKit.EMPTY_OBJECT_ARRAY);return new QueryWrap(builder.toString(), values);}public <T> QueryWrap buildInsert(BeanMonitor<T> monitor) {String tableName = getTableName(monitor);List<String> columns = monitor.getWritedPropertyNames();int columnNum = columns.size();StringBuilder builder = new StringBuilder(128);builder.append("insert into ");builder.append(tableName);builder.append(" (");for (int i = 0; i < columnNum; i++) {builder.append(columns.get(i));if (i < columnNum - 1) {builder.append(",");}}builder.append(") values (");for (int i = 0; i < columnNum; i++) {builder.append("?");if (i < columnNum - 1) {builder.append(",");}}builder.append(")");Object[] values = monitor.getWritedPropertyValues().toArray(ArrayKit.EMPTY_OBJECT_ARRAY);return new QueryWrap(builder.toString(), values);}public <E> QueryWrap buildCount(BeanMonitor<E> monitor) {String tableName = getTableName(monitor);StringBuilder builder = new StringBuilder(128);builder.append("select count(*) from ");builder.append(tableName);buildWhereExpression(monitor, builder);Object[] values = monitor.getWritedPropertyValues().toArray(ArrayKit.EMPTY_OBJECT_ARRAY);return new QueryWrap(builder.toString(), values);}public <E> QueryWrap buildCount(Class<E> entity) {String tableName = getTableName(entity);return new QueryWrap("select count(*) from " + tableName, null);}/** * * * @param monitor * @param id */public <E> QueryWrap buildUpdate(BeanMonitor<E> monitor) {List<String> columns = monitor.getWritedPropertyNames();String tableName = getTableName(monitor);int columnNum = monitor.getWhereOffset();StringBuilder builder = new StringBuilder(128);builder.append("update ");builder.append(tableName);builder.append(" set ");for (int i = 0; i < columnNum; i++) {builder.append(columns.get(i));builder.append("=?");if (i < columnNum - 1) {builder.append(",");}}buildWhereExpression(monitor, builder);Object[] values = monitor.getWritedPropertyValues().toArray(ArrayKit.EMPTY_OBJECT_ARRAY);return new QueryWrap(builder.toString(), values);}private String getTableName(BeanMonitor beanMonitor) {return nameMapper.getTableName(beanMonitor.getBean().getClass().getCanonicalName());}private String getTableName(Class entity) {return nameMapper.getTableName(entity.getCanonicalName());}private <E> void buildWhereExpression(BeanMonitor<E> monitor, StringBuilder builder) {int whereOffset = monitor.getWhereOffset();List<String> columns = monitor.getWritedPropertyNames();// build where expressionif (!CollectionKit.isEmpty(columns) || whereOffset < columns.size()) {int columnNum = columns.size();builder.append(" where");Iterator<Condition> conditions = monitor.getConditions().iterator();for (int i = whereOffset; i < columnNum; i++) {String columnName = columns.get(i);Condition cond = null;while (true) {cond = conditions.next();if (!cond.isCompare()) {builder.append(" ");builder.append(cond.getExpression());} else {break;}}builder.append(" ");builder.append(columnName);builder.append(cond.getExpression());builder.append("?");}}}}/** * @version 2007-5-10 * @author xalinx at gmail dot com * */public class SimpleDaoTemplate extends SimpleJdbcTemplate {private SqlBuilder sqlBuilder;public void setSqlBuilder(SqlBuilder sqlBuilder) {this.sqlBuilder = sqlBuilder;}/** * @param classicJdbcTemplate */public SimpleDaoTemplate(JdbcOperations classicJdbcTemplate) {super(classicJdbcTemplate);}@SuppressWarnings("unchecked")@Overridepublic <T> T queryForObject(String sql, ParameterizedRowMapper<T> rm, Object... args) throws DataAccessException {Object obj = (ObjectUtils.isEmpty(args) ? getJdbcOperations().queryForObject(sql, rm) : getJdbcOperations().queryForObject(sql, args, rm));return obj == null ? null : (T) obj;}public <T> T queryObject(String sql, ParameterizedRowMapper<? extends T> rm, Object... args) {return queryForObject(sql, rm, args);}@SuppressWarnings("unchecked")public <T> List<T> queryForList(String sql, ParameterizedRowMapper<? extends T> rm, Object... args)throws DataAccessException {return (List<T>) (ObjectUtils.isEmpty(args) ? getJdbcOperations().query(sql, rm) : getJdbcOperations().query(sql, args, rm));}public <T> BasePage<T> proxyQueryPage(BeanMonitor<T> beanMonitor, ParameterizedRowMapper<? extends T> rowMapper,PageQuery pageQuery) {QueryWrap wrap = sqlBuilder.buildLimitSelect(beanMonitor, pageQuery.getStart(), pageQuery.getPageSize());List<T> items = queryForList(wrap.getSql(), rowMapper, wrap.getValues());return new BasePage<T>(pageQuery, items);}public <T> List<T> proxyQueryList(BeanMonitor<T> monitor, ParameterizedRowMapper<? extends T> rm) {QueryWrap wrap = sqlBuilder.buildSelect(monitor);return queryForList(wrap.getSql(), rm, wrap.getValues());}public <T> T proxyQueryObject(BeanMonitor<T> monitor, ParameterizedRowMapper<? extends T> rm) {QueryWrap wrap = sqlBuilder.buildSelect(monitor);return queryObject(wrap.getSql(), rm, wrap.getValues());}public <T> void proxyStore(BeanMonitor<T> monitor) {QueryWrap wrap = sqlBuilder.buildInsert(monitor);update(wrap.getSql(), wrap.getValues());}public <T> void proxyDelete(BeanMonitor<T> monitor) {QueryWrap wrap = sqlBuilder.buildDelete(monitor);update(wrap.getSql(), wrap.getValues());}public <E> void proxyUpdate(BeanMonitor<E> monitor, Object id) {QueryWrap wrap = sqlBuilder.buildUpdate(monitor);update(wrap.getSql(), wrap.getValues());}public <E> int findCount(BeanMonitor<E> monitor) {if (null == monitor) {throw new IllegalArgumentException();}QueryWrap wrap = sqlBuilder.buildCount(monitor);return queryForInt(wrap.getSql(), wrap.getValues());}public <E> int findCount(Class<E> entity) {if (null == entity) {throw new IllegalArgumentException();}QueryWrap wrap = sqlBuilder.buildCount(entity);return queryForInt(wrap.getSql(), wrap.getValues());}}

/** * @version 2007-5-9 * @author xalinx at gmail dot com *  */public class DaoSupport<E, ID extends Serializable> extends JdbcDaoSupport {protected JdbcTemplate createJdbcTemplate(DataSource dataSource) {return new DaoTemplate(dataSource);}private SimpleDaoTemplate simpleDaoTemplate;/** * Create a SimpleJdbcTemplate based on the configured JdbcTemplate. */protected void initTemplateConfig() {this.simpleDaoTemplate = new SimpleDaoTemplate(getJdbcTemplate());this.simpleDaoTemplate.setSqlBuilder(sqlBuilder);}/** * Return a SimpleJdbcTemplate wrapping the configured JdbcTemplate. */protected SimpleDaoTemplate getSimpleDaoTemplate() {return simpleDaoTemplate;}private SqlBuilder sqlBuilder;public void setSqlBuilder(SqlBuilder builder) {this.sqlBuilder = builder;initTemplateConfig();}}

读书人网 >其他数据库

热点推荐