package com.hoss.core.dao; import com.hoss.core.exception.HossSqlException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import java.util.List; import java.util.Map; public interface SqlQueryDao { <T> Page<T> queryPageByConditionModel(Class<T> resultClass,Pageable pageable,String sql,Object conditionModel) throws HossSqlException; <T> Page<T> queryPage(Class<T> resultClass,Pageable pageable,String sql,Object ... params); <T> Page<Map<String,Object>> queryPageByConditionModel(Pageable pageable,String sql,Object conditionMode) throws HossSqlException; <T> Page<Map<String,Object>> queryPage(Pageable pageable,String sql,Object ... params); <T> List<T> queryListByConditionModel(Class<T> resultClass,String sql,Object conditionModel) throws HossSqlException; <T> List<T> queryList(Class<T> resultClass,String sql,Object ... params); <T> List<Map<String,Object>> queryListByConditionModel(String sql,Object conditionModel) throws HossSqlException; <T> List<Map<String,Object>> queryList(String sql,Object ... params); <T> T queryOneByConditionModel(Class<T> resultClass,String sql,Object conditionModel) throws HossSqlException; <T> T queryOne(Class<T> resultClass,String sql,Object ... params); Map<String,Object> queryOneByConditionModel(String sql,Object conditionModel) throws HossSqlException; Map<String,Object> queryOne(String sql,Object ... params); Number queryNumberByConditionMode(String sql,String numberKey,Object conditionModel) throws HossSqlException; Number queryNumber(String sql,String numberKey,Object ... params); Number queryCountByConditionMode(String sql,Object conditionModel) throws HossSqlException; Number queryCount(String sql,Object ... params); Integer execute(String sql,Object ...params); Integer executeByConditionMode(String sql,Object conditionModel) throws HossSqlException; }
package com.hoss.core.dao; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.PostConstruct; import javax.sql.DataSource; import com.hoss.core.util.StringUtil; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.PropertyUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import com.hoss.core.model.Broker; @Repository public class SqlQueryDaoImpl implements SqlQueryDao { private static final String SQL_KEY="#SQL#"; private static final String COUNT_KEY="RESULT_COUNT"; private static final String QUERY_COUNT_SQL=" SELECT COUNT(1) AS "+COUNT_KEY+" FROM ( "+SQL_KEY+" ) QUEYR_COUNT"; private static final String DEFAULT_WEHRE=" 1=1 "; private static final Pattern REGEX= Pattern.compile(":{1}\\w+",Pattern.CASE_INSENSITIVE); private static final Pattern PATTERN=Pattern.compile("\\{[^{]*\\}"); @Autowired private DataSource dataSource; private JdbcTemplate jdbcTemplate; @PostConstruct public void init(){ jdbcTemplate=new JdbcTemplate(dataSource); } @Override public <T> Page<T> queryPageByConditionModel(Class<T> resultClass, Pageable pageable, String sql, Object conditionModel){ SqlAndParams sp=generateSqlAndParams(sql, conditionModel); return queryPage(resultClass, pageable, sp.getSql(),sp.getParams().toArray()); } @Override public <T> Page<T> queryPage(Class<T> resultClass, Pageable pageable, String sql, Object... params) { String newSql=new String ( sql+ getSortSql(pageable.getSort()) ); Long total=queryCount(newSql,params).longValue(); List<T> data=queryList(resultClass, genPageSql(newSql,pageable), params); return new PageImpl<T>(data,pageable,total); } @Override public Page<Map<String, Object>> queryPageByConditionModel(Pageable pageable, String sql, Object conditionMode) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql,conditionMode); return queryPage(pageable, sp.getSql(),sp.getParams().toArray()); } @Override public Page<Map<String, Object>> queryPage(Pageable pageable, String sql, Object... params) { String newSql=new String ( sql+ getSortSql(pageable.getSort()) ); Long total=queryCount(newSql,params).longValue(); List<Map<String,Object>> data=queryList(genPageSql(newSql,pageable), params); return new PageImpl<Map<String,Object>>(data,pageable,total); } @Override public <T> List<T> queryListByConditionModel(Class<T> resultClass, String sql, Object conditionModel) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql,conditionModel); return queryList(resultClass, sp.getSql(), sp.getParams().toArray()); } @Override public <T> List<T> queryList(Class<T> resultClass, String sql, Object... params) { return jdbcTemplate.query(sql,rowMapper(resultClass), params ); } @Override public List<Map<String, Object>> queryListByConditionModel(String sql, Object conditionModel) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql,conditionModel); return queryList(sp.getSql(), sp.getParams().toArray()); } @Override public List<Map<String, Object>> queryList(String sql, Object... params) { System.out.println(sql); return jdbcTemplate.queryForList(sql, params); } @Override public <T> T queryOneByConditionModel(Class<T> resultClass, String sql, Object conditionModel) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql,conditionModel); return queryOne(resultClass,sp.getSql(),sp.getParams().toArray()); } @Override public <T>T queryOne(Class<T> resultClass, String sql, Object... params) { List<T> result=queryList(resultClass, sql, params); if( result==null || result.isEmpty() ) return null; return result.get(0); } @Override public Map<String, Object> queryOneByConditionModel(String sql, Object conditionModel) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql,conditionModel); return queryOne(sp.getSql(),sp.getParams().toArray()); } @Override public Map<String, Object> queryOne(String sql, Object... params) { return jdbcTemplate.queryForMap(sql, params); } @Override public Number queryNumberByConditionMode(String sql, String numberKey, Object conditionModel) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql, conditionModel); return queryNumber(sp.getSql(),numberKey,sp.getParams().toArray()); } @Override public Number queryNumber(String sql, String numberKey, Object... params) { Map<String,Object> map=jdbcTemplate.queryForMap(sql, params); if(map==null) return null; return (Number) map.get(numberKey); } @Override public Number queryCountByConditionMode(String sql, Object conditionModel) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql,conditionModel); return queryCount(sp.getSql(),sp.getParams().toArray()); } @Override public Number queryCount(String sql, Object... params) { String query_count=QUERY_COUNT_SQL.replace(SQL_KEY,sql); return queryNumber(query_count,COUNT_KEY,params); } @Override public Integer execute(String sql, Object... params) { return jdbcTemplate.update(sql,params); } @Override public Integer executeByConditionMode(String sql, Object conditionModel) throws HossSqlException { SqlAndParams sp=generateSqlAndParams(sql,conditionModel); return execute(sp.getSql(),sp.getParams().toArray()); } public String genPageSql(String sql,Pageable pageable){ StringBuffer pageSql=new StringBuffer(sql).append(" "); pageSql.append("limit "); pageSql.append( pageable.getOffset()).append(",").append(pageable.getPageSize()); return pageSql.toString(); } /**获取排序SQl * @param sort * @return */ private String getSortSql(Sort sort){ if(sort == null) return ""; Iterator<Sort.Order> iterator= sort.iterator(); StringBuffer sb=new StringBuffer(); while (iterator.hasNext()){ Sort.Order order=iterator.next(); sb.append(" ").append(order.getProperty()).append(" ").append(order.getDirection()); if( iterator.hasNext() ){ sb.append(","); } } if( sb.length()>0 ) return sb.insert(0," ORDER BY ").toString(); return sb.toString(); } /**生成 预编译 SQL 与参数 * @param sql 原始SQL * @param conditionModel 查询条件模型 * @return * @throws HossSqlException */ private SqlAndParams generateSqlAndParams(String sql,Object conditionModel) throws HossSqlException { String newSql=cleanNullAttributes(sql,conditionModel); Matcher matcher= REGEX.matcher(newSql); StringBuffer sb=new StringBuffer(); SqlAndParams result=new SqlAndParams(); while(matcher.find()){ String key=matcher.group(); String pk=key.replaceFirst(":",""); Object value=getProperty(conditionModel,pk); if(value==null) throw new HossSqlException("param "+key+" is null by SQL :"+sql); else{ matcher.appendReplacement(sb, paramAdd(result.getParams(),value)); } } matcher.appendTail(sb); result.setSql(sb.toString()); return result; } /**清除条件模型中 为NULL 的查询条件 * @param sql * @param conditionModel * @return */ private String cleanNullAttributes(String sql,Object conditionModel){ Matcher sqlMatcher=PATTERN.matcher(sql); StringBuffer sb = new StringBuffer(); while(sqlMatcher.find()){ StringBuffer temp=new StringBuffer(sqlMatcher.group()); temp.deleteCharAt(temp.length()-1).deleteCharAt(0); Matcher conditionMatcher= REGEX.matcher(temp); while(conditionMatcher.find()){ String mapKey=conditionMatcher.group().replaceFirst(":",""); Object value=getProperty(conditionModel,mapKey); if( value == null || (value instanceof String && ((String)value).trim().length()==0) ){ temp=new StringBuffer(DEFAULT_WEHRE); break; } } sqlMatcher.appendReplacement(sb,temp.toString()); } sqlMatcher.appendTail(sb); return sb.toString(); } /**生成 SQL 查询所用到的参数 并生成相应的 预编译所用到的? (主要解决数组和集合参数 转化 SQL in 的问题) * @param params * @param value * @return */ private String paramAdd(List<Object> params,Object value){ int length=0; if( value instanceof Collection ){ Collection<?> collection=(Collection<?>)value; length=collection.size(); params.addAll(collection); }else if( value.getClass().isArray() ){ Object[] array=(Object[])value; length=array.length; Collections.addAll(params,array); }else { length=1; params.add(value); } StringBuffer sb=new StringBuffer(); for(int i=0;i<length;i++){ sb.append("?"); if( i+1<length ) sb.append(","); } return sb.toString(); } /**通过反射获取属性 * @param obj * @param key * @return */ private Object getProperty(Object obj,String key){ if(obj == null) return null; try { return PropertyUtils.getProperty(obj, key); } catch (Exception e) { e.printStackTrace(); } return null; } /**行记录转换pojo * @param cls * @return */ private <T> RowMapper<T> rowMapper(final Class<T> cls){ return new RowMapper<T>(){ private ConcurrentHashMap<String,Method> successCache;//不需要类型转换的 private ConcurrentHashMap<String,PropertyDescriptor> converCache;//需要类型转换的 @Override public T mapRow(ResultSet rs, int rowNum) throws SQLException { if(rowNum==0){ //初始化mapping 需要的缓存 initCache(rs.getMetaData()); } T object= null; try { object = cls.newInstance(); } catch (Exception e) { } if(object==null){ return null; } for(Map.Entry<String, Method> entry : successCache.entrySet()){ //不需要转换的字段 setValue(entry.getValue(),object, getValue(rs,entry.getKey())); } for(PropertyDescriptor propertyDescriptor : converCache.values()){ //需要用到类型转换的字段 String name=propertyDescriptor.getName(); Object value=getValue(rs,name); if( value!=null ){ Class<?> trgetClass=propertyDescriptor.getPropertyType(); Method method=propertyDescriptor.getWriteMethod(); if(value.getClass() == trgetClass || value.getClass().getSuperclass()==trgetClass){ setValue(method,object,value); converCache.remove(name); successCache.put(name,method); }else{ setValue(method,object,value,trgetClass); } } } return object; } //从结果集中获取value private Object getValue(ResultSet rs,String key){ if(key != null){ try{ return rs.getObject(key); }catch (Exception e){ } } return null; } //需要转换设置value private void setValue(Method method,Object trget,Object value,Class<?> trgetClass){ if(value != null){ try{ method.invoke(trget, ConvertUtils.convert(value,trgetClass)); }catch (Exception e){ } } } //需要转换设置value private void setValue(Method method,Object trget,Object value){ if(value != null){ try{ method.invoke(trget,value); }catch (Exception e){ } } } //初始化mapping缓存 private void initCache(ResultSetMetaData rmd){ //缓存mapping 以加快转换的速度 converCache=new ConcurrentHashMap<String, PropertyDescriptor>(); successCache=new ConcurrentHashMap<String,Method>(); PropertyDescriptor [] propertyDescriptors = PropertyUtils.getPropertyDescriptors(cls); for(PropertyDescriptor propertyDescriptor : propertyDescriptors){ if( !propertyDescriptor.getName().equalsIgnoreCase("class") ) converCache.put(propertyDescriptor.getName(), propertyDescriptor); } try { for(int i=1;i<rmd.getColumnCount();i++){ String name=rmd.getColumnLabel(i); if( !converCache.containsKey(name) ){ converCache.remove(name); } } } catch (SQLException e) { e.printStackTrace(); } } }; } class SqlAndParams{ private String sql; private List<Object> params; public SqlAndParams(){ params=new ArrayList<Object>(); } public SqlAndParams(List<Object> params){ this.params=params; } public String getSql() { return sql; } public void setSql(String sql) { this.sql = sql; } public List<Object> getParams() { return params; } public void setParams(List<Object> params) { this.params = params; } } public static void main(String ... args) throws HossSqlException { PropertyDescriptor [] propertyDescriptors = PropertyUtils.getPropertyDescriptors(Broker.class); for(PropertyDescriptor propertyDescriptor : propertyDescriptors){ // converCache.put(key, value) System.out.println(propertyDescriptor.getName()); // propertyDescriptor.getWriteMethod() // propertyDescriptor.getName() // propertyDescriptor.getPropertyType() } } }
相关推荐
本文将深入探讨`JdbcTemplate`通用泛型Dao实现的相关知识点,帮助开发者更好地理解和应用这一技术。 首先,让我们了解什么是`JdbcTemplate`。它是Spring框架的一部分,用于处理SQL操作。`JdbcTemplate`提供了一组...
SSH整合JdbcTemplate_dao)_方式_总结
在本文中,我们讨论了如何利用`JdbcTemplate`来实现一个基类DAO(Data Access Object),用于支持基本的CRUD(Create, Read, Update, Delete)操作。 首先,`BaseDaoInf` 是一个接口,它定义了两个方法:`find` 和 ...
在这个"JDBCTemplate+JavaPOJO实现通用DAO"的项目中,我们将探讨如何利用这两者构建一个通用的DAO层。 首先,Java POJO(Plain Old Java Object)是指那些没有特殊约束的简单Java对象,通常用于表示数据库中的实体...
jdbcTemplate.query(sql, new RowCallbackHandler(){ @Override public void processRow(ResultSet rs) throws SQLException { User u=new User(); u.setId(rs.getInt("id")); u.setUsername(rs...
在实际开发中,我们通常会将JdbcTemplate与DAO(Data Access Object)层结合使用,创建特定业务的DAO接口和实现。接口定义了业务操作,实现类则通过JdbcTemplate调用对应的方法。例如: ```java public interface ...
4. 在DAO类中注入JdbcTemplate对象,这通常是通过Spring的依赖注入特性完成的。 5. 创建与数据库表对应的实体类,用于在Java代码中表示表中的数据。 6. 编写Service和DAO类中实现具体数据库操作的方法,如添加、删除...
4. **创建DAO层**:使用jdbcTemplate,创建DAO接口和实现类,如`UserDao`,实现用户相关的增删改查操作。 5. **编写Service层**:创建Service接口和实现类,如`UserService`,调用DAO进行业务逻辑处理,并进行事务...
最后,配置DAO实现类的`bean`,并注入`JdbcTemplate`: ```xml <property name="jt" ref="jdbcTemplate"/> ``` 完成上述步骤后,我们就可以在服务层或者控制器层通过@Autowired注解注入`UserDao`,并调用其方法...
本资源是一个完整的通过Servlet-Service-Dao-JdbcTemplate访问MySQL数据库的JavaWeb Project,可以直接导入到Eclipse中进行调试运行,注意默认编译器是JDK1.8。
**基于注解的Spring JdbcTemplate** 在Java世界中,Spring框架是企业级应用开发的首选。Spring JDBC模絫提供了一种简洁的方式来处理数据库操作,而`Spring JdbcTemplate`是这个模絫的核心组件。本教程将深入探讨...
本话题将详细讲解如何在J2DAO(Data Access Object)模式下,结合dataSource和jdbcTemplate,实现高效且灵活的数据访问功能。 首先,dataSource是Java中的一个接口,它在JDBC(Java Database Connectivity)中扮演...
使用JdbcTemplate扩展,开发者可以创建自定义的DAO接口,这些接口定义了特定的数据库操作,然后在实现类中利用JdbcTemplate提供的模板方法来完成这些操作。例如,可能会有一个`UserDao`接口,其中包含`getUserById`...
**JdbcTemplate简单实例** 在Java开发中,数据库操作是一个非常重要的环节。Spring框架提供了一个强大的...在实际项目中,结合其他Spring组件,如DAO层、Service层,JdbcTemplate能够构建出高效且健壮的数据库访问层。
在Spring框架中,可以为每个DAO配置单独的`JdbcTemplate`实例,或者让DAO类继承`JdbcDaoSupport`类,这样可以通过调用`getJdbcTemplate()`方法来获取`JdbcTemplate`实例。书中提到的做法是为每个DAO添加一个`...
`JDBCTemplate`在内部会自动捕获JDBC异常,并将其转换为Spring DAO层的异常,这使得异常处理更加统一和方便。所有转换后的异常都是非检查异常,开发者可以选择性地捕获这些异常。 示例代码如下: ```java try { ...
在Java的Spring框架中,`JdbcTemplate`是一个非常重要的组件,它提供了数据库操作的简单抽象,使得开发者可以方便地执行SQL语句而无需编写复杂的DAO(数据访问对象)层。在处理大量数据时,传统的分页方法可能会导致...
3. 创建DAO层:创建一个接口,定义数据库操作的方法,然后创建其实现类,使用@Autowired注入JdbcTemplate。 ```java public interface UserRepository { User getUserById(int id); } public class ...
Spring 框架 JdbcTemplate 类中查询方法介绍 JdbcTemplate 是 Spring 框架中 org.springframework.jdbc.core 包提供的 JDBC 模板类,它是核心类,其他模板类都是基于它封装完成的。JdbcTemplate 类主要提供四类方法...
@Autowired protected JdbcTemplate jdbcTemplate; /** SQL语句参数带名称的JDBC模版对象 */ protected NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** 分页SQL语句创建对象 */ protected ...