- 浏览: 233348 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
tonyyan:
谢谢分享!
Kafka 监控 -
dtyu100:
反手就是一个赞,这相当于是官网druid.io的中文版本,很厉 ...
Druid 大数据分析之快速应用(单机模式) -
sqy:
2018-04-12T01:30:27,527 ERROR [ ...
Druid 大数据分析之快速应用(单机模式) -
wangyudong:
学习了,不错的Spring boot实例,参考着很快写出了RE ...
Spring boot 入门实例 -
string2020:
servlet4规范出来了,求翻译
Java Servlet3.1规范
引用
提供不同数据源和方言实现智能分页,因Spring单例模式,可以利用Cglib实现动态数据源切换方案,基础东西不讲了,直接看代码。
引用
持久超接口,获取操作模板,可以是JdbcTemplate、SqlSessionTemplate等
package com.sunshine.basic.dao; public interface SuperDao<T> { /** * 获取操作模板 * @return */ T getTemplate(); }
引用
查询+分页操作接口
package com.sunshine.basic.dao; import java.sql.SQLException; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.JdbcTemplate; import com.sunshine.basic.dao.page.PagingParameter; import com.sunshine.basic.exception.DaoAccessException; /** * 查询+分页操作接口 * @author OY * @since 2016/01/20 * @see V2.0.0 */ public interface JdbcQueryDao extends SuperDao<JdbcTemplate>{ /*** * 查询单个字段值 * 采用?占位符,如 name=? * @param sql * @param paras * @return * @throws DaoAccessException */ Object getField(String sql, Object...paras) throws DaoAccessException; /** * 查询单个字段值 * 采用?占位符 * @param sql * @param paras * @return * @throws DaoAccessException */ Object getField(String sql, List<Object> paras) throws DaoAccessException; /** * 查询单个字段值 * 采用名称占位符,如 name=:name * @param sql * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ Object getField(String sql, Map<String, Object> paras) throws DaoAccessException; //=================================================================================== /** * 查询单个对象 * 采用?占位符,如 name=? * @param sql * @param paras * @return */ Map<String, Object> getObject(String sql, Object...paras) throws DaoAccessException; /** * 查询单个对象 * 采用?占位符,如 name=? * @param sql * @param paras * @return * @throws DaoAccessException */ Map<String, Object> getObject(String sql, List<Object> paras) throws DaoAccessException; /** * 查询单个对象 * 采用名称占位符,如 name=:name * @param sql * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ Map<String, Object> getObject(String sql, Map<String, Object> paras) throws DaoAccessException; /** * 查询单个对象(封装) * 采用?占位符,如 name=? * @param sql * @param classz * @param paras * @return */ <T> T getObject(String sql, Class<T> classz, Object...paras) throws DaoAccessException; /** * 查询单个对象(封装) * 采用?占位符,如 name=? * @param sql * @param classz * @param paras * @return * @throws DaoAccessException */ <T> T getObject(String sql, Class<T> classz, List<Object> paras) throws DaoAccessException; /** * 查询单个对象(封装) * 采用名称占位符,如 name=:name * @param sql * @param classz * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ <T> T getObject(String sql, Class<T> classz, Map<String, Object> paras) throws DaoAccessException; //==================================================================================================== /** * 查询列表 * 采用?占位符,如 name=? * @param sql SQL语句 * @param paras 参数 * @return * @throws DaoAccessException */ List<Map<String, Object>> getList(String sql, Object...paras) throws DaoAccessException; /** * 查询列表 * 采用?占位符,如 name=? * @param sql * @param paras * @return * @throws DaoAccessException */ List<Map<String, Object>> getList(String sql, List<Object> paras) throws DaoAccessException; /** * 查询列表 * @param sql * @param paras * @return * @throws DaoAccessException */ List<Map<String, Object>> getList(String sql, Map<String, Object> paras) throws DaoAccessException; /** * 查询列表(封装) * 采用?占位符,如 name=? * @param sql SQL语句 * @param classz 结果封装类 * @param paras 参数 * @return * @throws DaoAccessException */ <T> List<T> getList(String sql, Class<T> classz, Object...paras) throws DaoAccessException; /** * 查询列表(封装) * 采用?占位符,如 name=? * @param sql * @param classz * @param paras * @return * @throws DaoAccessException */ <T> List<T> getList(String sql, Class<T> classz, List<Object> paras) throws DaoAccessException; /** * 查询列表(封装) * 采用名称占位符,如 name=:name * @param sql * @param classz * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ <T> List<T> getList(String sql, Class<T> classz, Map<String, Object> paras) throws DaoAccessException; //==================================================================================================== /** * 查询总记录数 * 采用?占位符,如 name=? * @param sql 查询SQL * @param limit 查询限制,limit=0查询不受限制 * @return * @throws SQLException * @throws DaoAccessException */ public int getRecordCounts(String sql, int limit, Object...paras)throws DaoAccessException; /** * 查询记录总数 * 采用?占位符,如 name=? * @param sql * @param limit * @param paras * @return * @throws DaoAccessException */ public int getRecordCounts(String sql, int limit, List<Object> paras)throws DaoAccessException; /** * 查询记录总数 * 采用名称占位符,如 name=:name * @param sql * @param limit * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ public int getRecordCounts(String sql, int limit, Map<String, Object> paras)throws DaoAccessException; /** * 查询分页列表 * 采用?占位符,如 name=? * @param sql 查询SQL * @param pagingParameter 分页对象,pagingParameter=null或无参数构分页对象,不做分页 * @return * @throws SQLException * @throws DaoAccessException */ public List<Map<String, Object>> getRecordData(String sql, PagingParameter pagingParameter, Object...paras)throws DaoAccessException; /** * 查询分页列表 * 采用?占位符,如 name=? * @param sql * @param pagingParameter * @param paras * @return * @throws DaoAccessException */ public List<Map<String, Object>> getRecordData(String sql, PagingParameter pagingParameter, List<Object> paras)throws DaoAccessException; /** * 查询分页列表 * 采用名称占位符,如 name=:name * @param sql * @param pagingParameter * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ public List<Map<String, Object>> getRecordData(String sql, PagingParameter pagingParameter, Map<String, Object> paras)throws DaoAccessException; /** * 查询分页列表(封装) * 采用?占位符,如 name=? * @param <T> * @param sql 查询SQL * @param pagingParameter 分页对象,pagingParameter=null或无参数构分页对象,不做分页 * @param classz * @return * @throws SQLException * @throws DaoAccessException */ public <T> List<T> getRecordData(String sql, Class<T> classz, PagingParameter pagingParameter, Object...paras)throws DaoAccessException; /** * 查询分页列表(封装) * 采用?占位符,如 name=? * @param sql * @param classz * @param pagingParameter * @param paras * @return * @throws DaoAccessException */ public <T> List<T> getRecordData(String sql, Class<T> classz, PagingParameter pagingParameter, List<Object> paras)throws DaoAccessException; /** * 查询分页列表(封装) * 采用名称占位符,如 name=:name * @param sql * @param classz * @param pagingParameter * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ public <T> List<T> getRecordData(String sql, Class<T> classz, PagingParameter pagingParameter, Map<String, Object> paras)throws DaoAccessException; //================================================================================================================== /** * 分页查询结果 * 采用?占位符,如 name=? * @param sql * @param curPage * @param pageSize * @param paras * @return */ public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Object...paras)throws DaoAccessException; /** * 分页查询结果 * 采用?占位符,如 name=? * @param sql * @param curPage * @param pageSize * @param paras * @return * @throws DaoAccessException */ public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, List<Object> paras)throws DaoAccessException; /** * 分页查询结果 * 采用名称占位符,如 name=:name * @param sql * @param curPage * @param pageSize * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Map<String, Object> paras)throws DaoAccessException; /** * 分页查询结果(封装) * 采用?占位符,如 name=? * @param sql * @param curPage * @param pageSize * @param clazz * @param paras * @return */ public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Class<?> clazz, Object...paras)throws DaoAccessException; /** * 分页查询结果(封装) * 采用?占位符,如 name=? * @param sql * @param curPage * @param pageSize * @param clazz * @param paras * @return * @throws DaoAccessException */ public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Class<?> clazz, List<Object> paras)throws DaoAccessException; /** * 分页查询结果(封装) * 采用名称占位符,如 name=:name * @param sql * @param curPage * @param pageSize * @param clazz * @param paras key与占位符名称一致 * @return * @throws DaoAccessException */ public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Class<?> clazz, Map<String, Object> paras)throws DaoAccessException; }
/*更新接口*/ package com.sunshine.basic.dao; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.JdbcTemplate; import com.sunshine.basic.exception.DaoAccessException; public interface JdbcUpdateDao extends SuperDao<JdbcTemplate>{ void update(String sql, Object...paras) throws DaoAccessException; void update(String sql, List<Object> paras) throws DaoAccessException; void update(String sql, Map<String, Object> paras) throws DaoAccessException; }
/*插入接口*/ package com.sunshine.basic.dao; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.JdbcTemplate; import com.sunshine.basic.exception.DaoAccessException; public interface JdbcInsertDao extends SuperDao<JdbcTemplate>{ void insert(String sql, Object...paras) throws DaoAccessException; void insert(String sql, List<Object> paras) throws DaoAccessException; void insert(String sql, Map<String, Object> paras) throws DaoAccessException; }
引用
操作实现,暂未实现更新、插入。定义模板获取方法、SQL解析器由子类实现(设计模式之模板模式)
package com.sunshine.basic.dao; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.sunshine.basic.dao.page.DataStore; import com.sunshine.basic.dao.page.PagingParameter; import com.sunshine.basic.dao.parser.AbstractParser; import com.sunshine.basic.dao.parser.Dialect; import com.sunshine.basic.dao.parser.Parser; import com.sunshine.basic.exception.DaoAccessException; /** * 持久操作 * @author OY * @since 2016/01/20 * @see V2.0.0 */ public abstract class AbstractJdbcCommDao implements JdbcQueryDao, JdbcInsertDao, JdbcUpdateDao{ private Logger log = Logger.getLogger(getClass()); private NamedParameterJdbcTemplate nameJdbTemplate; private JdbcTemplate jdbcTemplate; public NamedParameterJdbcTemplate getNamedJdbcTemplate(){ nameJdbTemplate = new NamedParameterJdbcTemplate( getTemplate()); return nameJdbTemplate; } /** * 子类实现获取JdbcTemplate * @return * @throws DaoAccessException */ public abstract JdbcTemplate getSubJdbcTemplate() throws DaoAccessException ; /** * 子类实现解析器(根据方言构造分页语句) * @return * @throws DaoAccessException */ public abstract Parser getParser() throws DaoAccessException; @Override public final JdbcTemplate getTemplate() { try { jdbcTemplate = getSubJdbcTemplate(); if(jdbcTemplate == null) { log.info("jdbcTemplate is not exits!"); throw new IllegalAccessException("jdbcTemplate is not exits!"); //return SpringApplicationContext.getBean(DEFAULT_JDBC_TEMPLATE, JdbcTemplate.class); } } catch (Exception e) { log.error("jdbcTemplate is not exits!"); e.printStackTrace(); } return jdbcTemplate; } @Override public Object getField(String sql, Object... paras) throws DaoAccessException { log.info("jcbksql-" + sql); Object result = null; try{ result = getTemplate().queryForObject(sql, paras, Object.class); }catch(EmptyResultDataAccessException e){ //不做处理 } return result; } @Override public Object getField(String sql, List<Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getField(sql, paras.toArray()); } @Override public Object getField(String sql, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); Object result = null; try{ result = getNamedJdbcTemplate().queryForObject(sql, paras, Object.class); }catch(EmptyResultDataAccessException e){ //不做处理 } return result; } @Override public Map<String, Object> getObject(String sql, Object... paras) throws DaoAccessException { log.info("jcbksql-" + sql); Map<String, Object> result = null; try{ result = getTemplate().queryForMap(sql, paras); }catch(EmptyResultDataAccessException e){ //不做处理 } return result; } @Override public Map<String, Object> getObject(String sql, List<Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getObject(sql, paras.toArray()); } @Override public Map<String, Object> getObject(String sql, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); Map<String, Object> result = null ; try{ result = getNamedJdbcTemplate().queryForMap(sql, paras); }catch(EmptyResultDataAccessException e){ //不做处理 } return result; } @Override public <T> T getObject(String sql, Class<T> classz, Object... paras) throws DaoAccessException { log.info("jcbksql-" + sql); T result = null; try{ result = getTemplate().queryForObject(sql, paras, new BeanPropertyRowMapper<T>(classz)); }catch(EmptyResultDataAccessException e){ //不做处理 } return result; } @Override public <T> T getObject(String sql, Class<T> classz, List<Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getObject(sql, classz, paras.toArray()); } @Override public <T> T getObject(String sql, Class<T> classz, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); T result = null; try{ result = getNamedJdbcTemplate().queryForObject(sql, paras, new BeanPropertyRowMapper<T>(classz)); }catch(EmptyResultDataAccessException e){ //不做处理 } return result; } @Override public List<Map<String, Object>> getList(String sql, Object... paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getTemplate().queryForList(sql, paras); } @Override public List<Map<String, Object>> getList(String sql, List<Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getList(sql, paras.toArray()); } @Override public List<Map<String, Object>> getList(String sql, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getNamedJdbcTemplate().queryForList(sql, paras); } @Override public <T> List<T> getList(String sql, Class<T> classz, Object... paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getTemplate().query(sql, paras, new BeanPropertyRowMapper<T>(classz)); } @Override public <T> List<T> getList(String sql, Class<T> classz, List<Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getList(sql, classz, paras.toArray()); } @Override public <T> List<T> getList(String sql, Class<T> classz, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); return getNamedJdbcTemplate().query(sql, paras, new BeanPropertyRowMapper<T>(classz)); } @Override public int getRecordCounts(String sql, int limit, Object... paras) throws DaoAccessException { log.info("jcbksql-" + sql); String cSql = getParser().getCountSql(sql); log.info("jcbksql-count-" + cSql); Object result = getField(cSql, paras); return Integer.valueOf((result == null)?"0":String.valueOf(result)); } @Override public int getRecordCounts(String sql, int limit, List<Object> paras) throws DaoAccessException { return getRecordCounts(sql, limit, paras.toArray()); } @Override public int getRecordCounts(String sql, int limit, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); String cSql = getParser().getCountSql(sql); log.info("jcbksql-count-" + cSql); Object result = getField(cSql, paras); return Integer.valueOf((result==null)?"0":String.valueOf(result)); } /** * 增加分页参数(分页启始行、页大小) */ private List<Object> addPageParameters(List<Object> paras, PagingParameter pagingParameter, Parser parser){ List<Object> plist = new ArrayList<Object>(2); /* 结束行或页大小 */ plist.add(pagingParameter.getEndRow(parser.getDialect())); /* 开始 */ plist.add(pagingParameter.getStartRow()); Dialect dialect = parser.getDialect(); switch (dialect) { case mysql: Collections.reverse(plist); /*MYSQL*/ break; default: break; } if(paras != null){ List<Object> temp = Collections.synchronizedList(paras); plist.addAll(0, temp); } return plist; } /** * 增加分页参数(分页启始行、页大小) */ private Map<String, Object> addPageParameters(Map<String, Object> paras, PagingParameter pagingParameter, Parser parser){ Map<String, Object> pMap = new HashMap<String, Object>(2); pMap.put(AbstractParser.START_INDEX_NAME, pagingParameter.getStartRow()); pMap.put(AbstractParser.END_INDEX_NAME, pagingParameter.getEndRow(parser.getDialect())); if(paras != null){ paras.putAll(pMap); return paras; } return pMap; } @Override public List<Map<String, Object>> getRecordData(String sql, PagingParameter pagingParameter, Object... paras) throws DaoAccessException { return getRecordData(sql, pagingParameter, Arrays.asList(paras)); } @Override public List<Map<String, Object>> getRecordData(String sql, PagingParameter pagingParameter, List<Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); Parser parser = getParser(); String pSql = parser.getPageSql(sql); log.info("jcbksql-page-" + pSql + " dialect-" + parser.getDialect().toString()); List<Object> _paras = addPageParameters(paras, pagingParameter, parser); return getList(pSql, _paras); } @Override public List<Map<String, Object>> getRecordData(String sql, PagingParameter pagingParameter, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); Parser parser = getParser(); String pSql = parser.getPageSqlForPlace(sql); log.info("jcbksql-page-" + pSql + " dialect-" + parser.getDialect().toString()); Map<String, Object> _paras = addPageParameters(paras, pagingParameter, parser); return getList(pSql, _paras); } @Override public <T> List<T> getRecordData(String sql, Class<T> classz, PagingParameter pagingParameter, Object... paras) throws DaoAccessException { return getRecordData(sql, classz, pagingParameter, Arrays.asList(paras)); } @Override public <T> List<T> getRecordData(String sql, Class<T> classz, PagingParameter pagingParameter, List<Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); Parser parser = getParser(); String pSql = parser.getPageSqlForPlace(sql); log.info("jcbksql-page-" + pSql + " dialect-" + parser.getDialect().toString()); List<Object> _paras = addPageParameters(paras, pagingParameter, parser); return getList(pSql, classz, _paras); } @Override public <T> List<T> getRecordData(String sql, Class<T> classz, PagingParameter pagingParameter, Map<String, Object> paras) throws DaoAccessException { log.info("jcbksql-" + sql); Parser parser = getParser(); String pSql = parser.getPageSqlForPlace(sql); log.info("jcbksql-page-" + pSql + " dialect-" + parser.getDialect().toString()); Map<String, Object> _paras = addPageParameters(paras, pagingParameter, parser); return getList(pSql, classz, _paras); } @Override public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Object... paras) throws DaoAccessException { return getPageForMap(sql, curPage, pageSize, Arrays.asList(paras)); } @Override public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, List<Object> paras) throws DaoAccessException { int total = getRecordCounts(sql, 0, paras); PagingParameter pp = new PagingParameter(curPage, pageSize, total); List<Map<String, Object>> list = getRecordData(sql, pp, paras); return new DataStore(total,list).getEntity(); } @Override public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Map<String, Object> paras) throws DaoAccessException { int total = getRecordCounts(sql, 0, paras); PagingParameter pp = new PagingParameter(curPage, pageSize, total); List<Map<String, Object>> list = getRecordData(sql, pp, paras); return new DataStore(total,list).getEntity(); } @Override public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Class<?> clazz, Object... paras) throws DaoAccessException { return getPageForMap(sql, curPage, pageSize, clazz, Arrays.asList(paras)); } @Override public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Class<?> clazz, List<Object> paras) throws DaoAccessException { int total = getRecordCounts(sql, 0, paras); PagingParameter pp = new PagingParameter(curPage, pageSize, total); List<?> list = getRecordData(sql, clazz, pp, paras); return new DataStore(total,list).getEntity(); } @Override public Map<String, Object> getPageForMap(String sql, int curPage, int pageSize, Class<?> clazz, Map<String, Object> paras) throws DaoAccessException { int total = getRecordCounts(sql, 0, paras); PagingParameter pp = new PagingParameter(curPage, pageSize, total); List<?> list = getRecordData(sql, clazz, pp, paras); return new DataStore(total,list).getEntity(); } @Override public void update(String sql, Object... paras) throws DaoAccessException { // TODO Auto-generated method stub throw new DaoAccessException("暂不支持该操作!"); } @Override public void update(String sql, List<Object> paras) throws DaoAccessException { // TODO Auto-generated method stub throw new DaoAccessException("暂不支持该操作!"); } @Override public void update(String sql, Map<String, Object> paras) throws DaoAccessException { // TODO Auto-generated method stub throw new DaoAccessException("暂不支持该操作!"); } @Override public void insert(String sql, Object... paras) throws DaoAccessException { // TODO Auto-generated method stub throw new DaoAccessException("暂不支持该操作!"); } @Override public void insert(String sql, List<Object> paras) throws DaoAccessException { // TODO Auto-generated method stub throw new DaoAccessException("暂不支持该操作!"); } @Override public void insert(String sql, Map<String, Object> paras) throws DaoAccessException { // TODO Auto-generated method stub throw new DaoAccessException("暂不支持该操作!"); } }
/*为了实现动态修改数据源名称,增加了适配类*/ package com.sunshine.basic.dao; import org.springframework.beans.BeansException; import org.springframework.jdbc.core.JdbcTemplate; import com.sunshine.basic.dao.AbstractJdbcCommDao; import com.sunshine.basic.dao.parser.AbstractParser; import com.sunshine.basic.dao.parser.Dialect; import com.sunshine.basic.dao.parser.Parser; import com.sunshine.basic.exception.DaoAccessException; import com.sunshine.basic.tools.ApplicationContextTools; /** * 利用JdbcAdapterDaoProxy生成子类代理,然后修改数据源名称 * @see com.sunshine.monitor.comm.dao.adapter.JdbcAdapterDaoProxy * @author OY * */ public abstract class AbstractJdbcAdapterDao extends AbstractJdbcCommDao { /* 静态数据源 */ private String jdbcTemplateName; private Dialect dialect; /** * 子类实现静态JdbcTemplate操作模板及方言 * @param jdbcTemplateName * @param dialect */ public AbstractJdbcAdapterDao(String jdbcTemplateName, Dialect dialect){ this.jdbcTemplateName = jdbcTemplateName; this.dialect = dialect; } /*动态修改数据源名称*/ public final void setJdbcTemplateName(String jdbcTemplateName){ this.jdbcTemplateName = jdbcTemplateName; } @Override public final JdbcTemplate getSubJdbcTemplate() throws DaoAccessException { JdbcTemplate jdbcTemplate = null; try { jdbcTemplate = ApplicationContextTools.getBean( this.jdbcTemplateName, JdbcTemplate.class); if(jdbcTemplate == null) throw new DaoAccessException("JdbcTemplate实例访问失败!"); } catch (BeansException e) { e.printStackTrace(); throw new DaoAccessException("JdbcTemplate实例访问失败!"); } return jdbcTemplate; } @Override public Parser getParser() throws DaoAccessException { return AbstractParser.newParser(this.dialect); } }
/*Oracle实现类*/ package com.sunshine.basic.dao.jdbc; import org.springframework.stereotype.Repository; import com.sunshine.basic.dao.AbstractJdbcAdapterDao; import com.sunshine.basic.dao.parser.Dialect; @Repository("oracleJdbcDao") public class OracleJdbcDao extends AbstractJdbcAdapterDao { public OracleJdbcDao(){ super("jdbcTemplate", Dialect.of("oracle")); } }
/*GreenPum实现类*/ package com.sunshine.basic.dao.jdbc; import org.springframework.stereotype.Repository; import com.sunshine.basic.dao.AbstractJdbcAdapterDao; import com.sunshine.basic.dao.parser.Dialect; /** * @author oy * */ @Repository("greenPlumJdbcDao") public class GreenPlumJdbcDao extends AbstractJdbcAdapterDao { public GreenPlumJdbcDao(){ super("gpJdbcTemplate",Dialect.of("postgresql")); } }
package com.sunshine.basic.dao.proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 生成代理对象 * @author oy * */ public class JdbcAdapterDaoProxy implements MethodInterceptor{ private Object target; public JdbcAdapterDaoProxy(){ } public Object createInstance(Object target){ this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invokeSuper(obj, args); } }
引用
数据库方言及SQL智能分页
package com.sunshine.basic.dao.parser; public interface Parser { /** * 获取总数sql - 如果要支持其他数据库,修改这里就可以 * * @param sql 原查询sql * @return 返回count查询sql */ String getCountSql(String sql); /** * 获取分页sql - 如果要支持其他数据库,修改这里就可以 * * @param sql 原查询sql * @return 返回分页sql */ String getPageSql(String sql); /** * * @param sql * @return */ String getPageSqlForPlace(String sql); /** * 获取方言 * @return */ Dialect getDialect(); /** * 设置方言 * @param dialect */ void setDialect(Dialect dialect); }
package com.sunshine.basic.dao.parser; import com.sunshine.basic.dao.parser.impl.MysqlParser; import com.sunshine.basic.dao.parser.impl.OracleParser; import com.sunshine.basic.dao.parser.impl.PostgreSQLParser; public abstract class AbstractParser implements Parser{ //处理SQL public static final SqlParser sqlParser = new SqlParser(); private Dialect dialect; public static final String END_INDEX_NAME="endIndex"; public static final String START_INDEX_NAME = "startIndex"; public Dialect getDialect(){ return dialect; } public void setDialect(Dialect dialect){ this.dialect = dialect; } public static Parser newParser(Dialect dialect) { Parser parser = null; switch (dialect) { case postgresql: parser = new PostgreSQLParser(); break; case mysql: parser = new MysqlParser(); break; case oracle: parser = new OracleParser(); break; default: break; } if(parser != null) parser.setDialect(dialect); return parser; } public String getCountSql(final String sql) { return sqlParser.getSmartCountSql(sql); } public abstract String getPageSql(String sql); }
package com.sunshine.basic.dao.parser.impl; import com.sunshine.basic.dao.parser.AbstractParser; public class OracleParser extends AbstractParser { @Override public String getPageSql(String sql) { StringBuilder sqlBuilder = new StringBuilder(sql.length() + 120); sqlBuilder.append("select * from ( select tmp_page.*, rownum row_id from ( "); sqlBuilder.append(sql); sqlBuilder.append(" ) tmp_page where rownum <= ? ) where row_id > ?"); return sqlBuilder.toString(); } @Override public String getPageSqlForPlace(String sql) { StringBuilder sqlBuilder = new StringBuilder(sql.length() + 120); sqlBuilder.append("select * from ( select tmp_page.*, rownum row_id from ( "); sqlBuilder.append(sql); sqlBuilder.append(" ) tmp_page where rownum <= :"); sqlBuilder.append(END_INDEX_NAME); sqlBuilder.append(") where row_id > :"); sqlBuilder.append(START_INDEX_NAME); return sqlBuilder.toString(); } }
/*方言*/ package com.sunshine.basic.dao.parser; public enum Dialect { mysql, oracle, postgresql; public static Dialect of(String dialect) { try { Dialect d = Dialect.valueOf(dialect); return d; } catch (IllegalArgumentException e) { String dialects = null; for (Dialect d : Dialect.values()) { if (dialects == null) { dialects = d.toString(); } else { dialects += "," + d; } } throw new IllegalArgumentException("分页dialect参数值错误,可选值为[" + dialects + "]"); } } public static String[] dialects() { Dialect[] dialects = Dialect.values(); String[] ds = new String[dialects.length]; for (int i = 0; i < dialects.length; i++) { ds[i] = dialects[i].toString(); } return ds; } public static String fromJdbcUrl(String jdbcUrl) { String[] dialects = dialects(); for (String dialect : dialects) { if (jdbcUrl.indexOf(":" + dialect + ":") != -1) { return dialect; } } return null; } }
/*SQL智分析,依赖jsqlparse.jar*/ package com.sunshine.basic.dao.parser; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.expression.Function; import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.FromItem; import net.sf.jsqlparser.statement.select.Join; import net.sf.jsqlparser.statement.select.LateralSubSelect; import net.sf.jsqlparser.statement.select.OrderByElement; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectBody; import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SelectItem; import net.sf.jsqlparser.statement.select.SetOperationList; import net.sf.jsqlparser.statement.select.SubJoin; import net.sf.jsqlparser.statement.select.SubSelect; import net.sf.jsqlparser.statement.select.ValuesList; import net.sf.jsqlparser.statement.select.WithItem; import org.apache.log4j.Logger; /** * sql解析类,提供更智能的count查询sql */ public class SqlParser { private static final List<SelectItem> COUNT_ITEM; private static final Alias TABLE_ALIAS; private Logger log = Logger.getLogger(SqlParser.class); static { COUNT_ITEM = new ArrayList<SelectItem>(); COUNT_ITEM.add(new SelectExpressionItem(new Column("count(1)"))); TABLE_ALIAS = new Alias("table_count"); TABLE_ALIAS.setUseAs(false); } // 缓存已经修改过的sql private Map<String, String> CACHE = new ConcurrentHashMap<String, String>(); public void isSupportedSql(String sql) { if (sql.trim().toUpperCase().endsWith("FOR UPDATE")) { throw new RuntimeException("分页不支持包含for update的sql"); } } /** * 获取智能的countSql * * @param sql * @return */ public String getSmartCountSql(String sql) { log.info("Sql parse before:" + sql); //校验是否支持该sql isSupportedSql(sql); if (CACHE.get(sql) != null) { log.info("Count sql parse(Cache):" + CACHE.get(sql)); return CACHE.get(sql); } //解析SQL Statement stmt = null; try { stmt = CCJSqlParserUtil.parse(sql); } catch (Throwable e) { //无法解析的用一般方法返回count语句 String countSql = getSimpleCountSql(sql); CACHE.put(sql, countSql); return countSql; } Select select = (Select) stmt; SelectBody selectBody = select.getSelectBody(); //处理body-去order by processSelectBody(selectBody); //处理with-去order by processWithItemsList(select.getWithItemsList()); //处理为count查询 sqlToCount(select); String result = select.toString(); CACHE.put(sql, result); log.info("Sql parse after:" + sql); return result; } /** * 获取普通的Count-sql * @param sql 原查询sql * @return 返回count查询sql */ public String getSimpleCountSql(final String sql) { isSupportedSql(sql); StringBuilder stringBuilder = new StringBuilder(sql.length() + 40); stringBuilder.append("select count(*) from ("); stringBuilder.append(sql); stringBuilder.append(") tmp_count"); return stringBuilder.toString(); } /** * 将sql转换为count查询 * @param select */ public void sqlToCount(Select select) { SelectBody selectBody = select.getSelectBody(); // 是否能简化count查询 if (selectBody instanceof PlainSelect && isSimpleCount((PlainSelect) selectBody)) { ((PlainSelect) selectBody).setSelectItems(COUNT_ITEM); } else { PlainSelect plainSelect = new PlainSelect(); SubSelect subSelect = new SubSelect(); subSelect.setSelectBody(selectBody); subSelect.setAlias(TABLE_ALIAS); plainSelect.setFromItem(subSelect); plainSelect.setSelectItems(COUNT_ITEM); select.setSelectBody(plainSelect); } } /** * 是否可以用简单的count查询方式 * @param select * @return */ public boolean isSimpleCount(PlainSelect select) { //包含group by的时候不可以 if (select.getGroupByColumnReferences() != null) { return false; } //包含distinct的时候不可以 if (select.getDistinct() != null) { return false; } for (SelectItem item : select.getSelectItems()) { //select列中包含参数的时候不可以,否则会引起参数个数错误 if (item.toString().contains("?")) { return false; } //如果查询列中包含函数,也不可以,函数可能会聚合列 if (item instanceof SelectExpressionItem) { if (((SelectExpressionItem) item).getExpression() instanceof Function) { return false; } } } return true; } /** * 处理selectBody去除Order by * * @param selectBody */ public void processSelectBody(SelectBody selectBody) { if (selectBody instanceof PlainSelect) { processPlainSelect((PlainSelect) selectBody); } else if (selectBody instanceof WithItem) { WithItem withItem = (WithItem) selectBody; if (withItem.getSelectBody() != null) { processSelectBody(withItem.getSelectBody()); } } else { SetOperationList operationList = (SetOperationList) selectBody; if (operationList.getPlainSelects() != null && operationList.getPlainSelects().size() > 0) { List<PlainSelect> plainSelects = operationList.getPlainSelects(); for (PlainSelect plainSelect : plainSelects) { processPlainSelect(plainSelect); } } if (!orderByHashParameters(operationList.getOrderByElements())) { operationList.setOrderByElements(null); } } } /** * 处理PlainSelect类型的selectBody * * @param plainSelect */ public void processPlainSelect(PlainSelect plainSelect) { if (!orderByHashParameters(plainSelect.getOrderByElements())) { plainSelect.setOrderByElements(null); } if (plainSelect.getFromItem() != null) { processFromItem(plainSelect.getFromItem()); } if (plainSelect.getJoins() != null && plainSelect.getJoins().size() > 0) { List<Join> joins = plainSelect.getJoins(); for (Join join : joins) { if (join.getRightItem() != null) { processFromItem(join.getRightItem()); } } } } /** * 处理WithItem * * @param withItemsList */ public void processWithItemsList(List<WithItem> withItemsList) { if (withItemsList != null && withItemsList.size() > 0) { for (WithItem item : withItemsList) { processSelectBody(item.getSelectBody()); } } } /** * 处理子查询 * * @param fromItem */ public void processFromItem(FromItem fromItem) { if (fromItem instanceof SubJoin) { SubJoin subJoin = (SubJoin) fromItem; if (subJoin.getJoin() != null) { if (subJoin.getJoin().getRightItem() != null) { processFromItem(subJoin.getJoin().getRightItem()); } } if (subJoin.getLeft() != null) { processFromItem(subJoin.getLeft()); } } else if (fromItem instanceof SubSelect) { SubSelect subSelect = (SubSelect) fromItem; if (subSelect.getSelectBody() != null) { processSelectBody(subSelect.getSelectBody()); } } else if (fromItem instanceof ValuesList) { } else if (fromItem instanceof LateralSubSelect) { LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem; if (lateralSubSelect.getSubSelect() != null) { SubSelect subSelect = lateralSubSelect.getSubSelect(); if (subSelect.getSelectBody() != null) { processSelectBody(subSelect.getSelectBody()); } } } //Table时不用处理 } /** * 判断Orderby是否包含参数,有参数的不能去 * * @param orderByElements * @return */ public boolean orderByHashParameters(List<OrderByElement> orderByElements) { if (orderByElements == null) { return false; } for (OrderByElement orderByElement : orderByElements) { if (orderByElement.toString().contains("?")) { return true; } } return false; } public static void main(String[] args) { String countSql = new SqlParser() .getSmartCountSql("select count(t.hphm) as GCCS, t.hphm as HPHM, t.hpys as HPYS, t.hpzl as HPZL from veh_passrec t where t.hphm like '粤A_____' and t.gcsj > '2010-02-18 00:00:00' and t.gcsj <= '2010-02-21 23:59:59' group by t.hphm, t.hpys, t.hpzl"); System.out.println(countSql); } }
/*分页参数对象*/ package com.sunshine.basic.dao.page; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import com.sunshine.basic.dao.parser.Dialect; /** * 封装分页参数 */ public class PagingParameter implements Serializable{ private static final long serialVersionUID = -5871263750693828476L; /** 分页起始行,默认为-1,表示不分页,查询全部记录 */ private int curPage = -1; /** 每页显示行数,默认为0,表示不分页,查询全部记录 */ private int pageSize = 0; /** 总记录*/ private int totalRows = 0; /** * 构造方法,不指定分页起始行和每页显示行数,默认不分页,查询全部记录 */ public PagingParameter(){ } /** * 构造方法 * @param start * @param pageSize */ public PagingParameter(int curPage,int pageSize, int totalRows){ this.curPage = curPage; this.pageSize = pageSize; this.totalRows = totalRows; } public int getTotalRows() { return totalRows; } public int getCurPage() { return curPage; } public void setCurPage(int curPage) { this.curPage = curPage; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public void setTotalRows(int totalRows) { this.totalRows = totalRows; } /** * 判断分页参数是否无效,如果返回true(表示分页参数无效)则不分页,查询全部的记录 * * @return */ public boolean isInvalid() { return curPage < 0 || pageSize <= 0; } /** * 构造开始行与结束行 * @return */ public Map<String,Integer> getStartAndEndRow(){ // 总页数 int totalPages = totalPage(); Map<String,Integer> map = null; // 起始行数 int start = (curPage - 1) * pageSize; // 结束行数 int end = 0; if (totalRows < pageSize) { end = totalRows; } else if ((totalRows % pageSize == 0) || (totalRows % pageSize != 0 && curPage < totalPages)) { end = curPage * pageSize; } else if (totalRows % pageSize != 0 && curPage == totalPages) {// 最后一页 end = totalRows; } map = new HashMap<String,Integer>(); map.put("start", start); map.put("end", end); return map ; } /** * 结束行 * @return */ public int getEndRow(Dialect dialect){ int end = 0; switch (dialect) { case mysql: end = pageSize; break; case postgresql: end = pageSize; break; case oracle: end = getOracleEndRow(); break; default: break; } return end; } public int getOracleEndRow(){ int end = 0; int totalPages = totalPage(); if (totalRows < pageSize) { end = totalRows; } else if ((totalRows % pageSize == 0) || (totalRows % pageSize != 0 && curPage < totalPages)) { end = curPage * pageSize; } else if (totalRows % pageSize != 0 && curPage == totalPages) {// 最后一页 end = totalRows; } return end; } /** * 开始行 * @return */ public int getStartRow(){ return (curPage - 1) * pageSize; } /** * 总页数 * @return */ public int totalPage(){ int totalPages = 0; if (pageSize != -1) { int pc = (int)Math.ceil(totalRows/pageSize); totalPages = (pc == 0) ? 1 : pc; } else { totalPages = 1; } return totalPages; } }
发表评论
-
数据接入ElasticSearch方式培训PPT
2018-01-28 11:53 1902写道 数据接入ElasticSearch几种方式总结,涉及 ... -
Apache ftp tools 图片下载支持中文
2017-12-05 23:55 1251写道 Apache Commom net:1) 递归pat ... -
FtpURLConnection 图片下载编码问题
2017-12-05 23:13 860写道 问题:1)Web项目中下载图片,存在下载不全,丢失部 ... -
Kafka 监控
2017-11-18 00:31 5777背景概述 写道 kafka0.9及以前版本ka ... -
Spring Cloud之OAuth2
2017-07-08 12:04 11413备:附件中OAuth2 授权服务器实现源码及PPT 一 ... -
Spring Cloud之Configuration Server
2017-05-19 22:51 1504为什么用spring cloud config 写道 一 ... -
Java Servlet3.1规范
2016-11-25 20:33 1250目录 前言........................ ... -
JMX监控(MBean)
2016-11-23 22:16 4105一、引言 写道 随着企业 IT 规模的不断增长,IT 资 ... -
哈希表在JAVA中如何实现
2016-11-23 20:42 2920一、 复习一下基础知识 1. 截断低位与抹除高位 ... -
Spring boot 入门实例
2016-10-29 00:33 4881写道 Spring Boot是由Pivotal团队提供的全 ... -
Java计算两点经纬度距离及最短运行时间
2016-09-12 21:20 2601概述 经纬度在地图应用中常见,一般结合路网信息库, ... -
计算机软件开源技术、大数据技术等资源教程
2016-08-24 13:01 588基于时间序列化数据引擎排名,很多OLAP工具,根据自身业务 ... -
代码单元与代码点
2016-08-16 17:46 692代码单元与代码点 代码点指编码表(比如Unicode)中某 ... -
Java模块化解决方案
2016-08-15 00:19 4196网络上很多OSGi的文章上来就Activator实例, ... -
深入浅出ClassLoader
2016-08-13 17:06 751你真的了解ClassLoader吗? 这篇文章翻译自zer ... -
Generate axis server code from wsdl
2016-08-04 00:34 12541、为什么需要生成服 ... -
JAVA NIO 之三
2016-01-17 00:35 1735引用 本节采用JDK1.5之后java.util.con ... -
JAVA NIO 之二
2016-01-14 00:35 1979引用 继上节利用JAVA NIO实现简单数据传,本节实现自定 ... -
JAVA NIO 之一
2016-01-12 14:14 1569传统IO 写道 网络传输 ... -
JAVA压缩图片并打成ZIP
2016-01-06 13:48 7446引用 JAVA 获取网络图片或本地图片压缩后打成ZIP,但 ...
相关推荐
总之,通过Spring Cloud实战项目,开发者不仅可以掌握Spring Cloud的核心组件和实践方法,还能深入了解微服务架构的设计理念,从而在实际工作中游刃有余地应对复杂系统的挑战。记得参考Ace-Security模块的README.md...
在本课程中,我们将深入探讨"03Spring Cloud项目实战微服务整合spring boot"的相关知识点。Spring Cloud作为一套微服务解决方案,与Spring Boot相结合,为开发者提供了构建分布式系统中的配置管理、服务发现、断路器...
### Spring3开发实战知识点概述 #### 一、Spring框架简介 Spring框架是一个开源的应用程序框架,主要用于Java平台上的企业级应用程序开发。它提供了一个全面的编程模型,支持从Web到EJB的应用程序开发。Spring的...
Spring WebFlux是Spring框架的一个重要模块,专为构建反应式Web应用而设计。它引入了非阻塞I/O和异步处理的概念,使得应用程序在高并发环境下性能更优,资源利用率更高。在这个"spring-webflux实战.zip"压缩包中,...
Spring Security 是一个强大的且高度可定制的身份验证和访问控制框架,专为 Java 应用程序设计。它提供了全面的安全解决方案,包括登录、授权、权限管理等,广泛应用于Web应用程序和企业级系统。在本实战例子中,...
内容概要:本文详细介绍了Spring Boot的设计和应用,涵盖了从基本概念到高级用法的全方位教学。首先通过环境搭建、首个项目创建、核心概念解析等步骤帮助读者快速上手。接着阐述了Spring Boot的设计原则与最佳实践,...
这种方式减少了代码的依赖性,使得面向对象设计变得更加灵活。 面向切面编程(AOP)是另一种让开发者集中处理应用程序中跨越多个点的功能(例如事务管理、安全检查)的方式。在Spring AOP模块中,开发者可以定义...
通过学习和实践这个实战项目,你可以深入了解Spring和MyBatis如何协同工作,如何设计和实现一个完整的业务流程,以及如何处理异常和事务。同时,这也将帮助你理解企业级应用的架构设计,提升你在实际开发中的技能和...
《Spring实战第四版》是Java开发领域中一本深入讲解Spring框架的经典著作,源代码的提供为读者提供了亲自动手实践的机会,有助于加深理解和应用。在这个压缩包中,包含的文件名为"spring4源码_Code4",我们可以推测...
2019年SpringCloud 微服务实战之气象预报平台实战 包含11章节+项目源码 目录: 第9章 微服务的集中化配置 第8章 API 网关 第7章 微服务的消费 第6章 微服务的注册与发现 第5章 微服务的协调者Spring ...
这本《Vue Spring Boot前后端分离开发实战》的源码提供了深入学习和实践这一技术栈的机会。以下是对其中涉及知识点的详细说明: 1. **Vue.js**:Vue.js是一个轻量级的前端JavaScript框架,以其易学易用、组件化和...
《Spring+Mybatis开发实战》是一本专注于Java企业级应用开发的书籍,主要围绕Spring框架与Mybatis持久层框架的整合应用进行深入讲解。Spring以其强大的依赖注入和面向切面编程能力,为开发者提供了便捷的组件管理和...
Spring Cloud高可用服务设计与实战Spring Cloud高可用服务设计与实战Spring Cloud高可用服务设计与实战
《SpringCloud微服务实战》这本书籍的源代码包含了大量的实践示例和配置,旨在帮助读者深入理解并掌握Spring Cloud在实际开发中的应用。Spring Cloud是一个基于Spring Boot实现的服务发现、配置管理和API网关等...
《Spring Data实战》这本书深入探讨了Spring Data框架的使用,旨在帮助开发者更高效地与数据库进行交互,实现数据访问层的简化。Spring Data是Spring生态中的一个重要组成部分,它提供了对各种数据存储系统的支持,...
4. **MVC框架**:Spring MVC是Spring提供的用于构建Web应用程序的模块,支持RESTful风格的URL设计、模型-视图-控制器模式,以及视图解析等功能。 5. **Spring Boot**:Spring4X中引入的Spring Boot简化了Spring应用...
本实战代码将带你深入理解并实际操作SpringSecurity的核心功能,包括用户认证与授权、注销、权限限制、"记住我"功能以及首页定制。 1. 用户认证与授权:在SpringSecurity中,认证过程是识别用户身份,而授权则是...
Spring MVC 是一个强大的Java web应用程序开发框架,它遵循Model-View-Controller(MVC)设计模式,用于构建可维护性和可扩展性高的企业级应用。本实战教程将深入讲解Spring MVC的关键组件和工作流程,帮助开发者更...