`

JdbcTemplateDao

 
阅读更多
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`通用泛型Dao实现的相关知识点,帮助开发者更好地理解和应用这一技术。 首先,让我们了解什么是`JdbcTemplate`。它是Spring框架的一部分,用于处理SQL操作。`JdbcTemplate`提供了一组...

    QQQ_(S+S+H)(Spring_JdbcTemplate_dao)_方式总结

    SSH整合JdbcTemplate_dao)_方式_总结

    spring的jdbctemplate的crud的基类dao

    在本文中,我们讨论了如何利用`JdbcTemplate`来实现一个基类DAO(Data Access Object),用于支持基本的CRUD(Create, Read, Update, Delete)操作。 首先,`BaseDaoInf` 是一个接口,它定义了两个方法:`find` 和 ...

    JDBCTemplate+JavaPOJO实现通用DAO

    在这个"JDBCTemplate+JavaPOJO实现通用DAO"的项目中,我们将探讨如何利用这两者构建一个通用的DAO层。 首先,Java POJO(Plain Old Java Object)是指那些没有特殊约束的简单Java对象,通常用于表示数据库中的实体...

    jdbcTemplate

    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操作总结

    在实际开发中,我们通常会将JdbcTemplate与DAO(Data Access Object)层结合使用,创建特定业务的DAO接口和实现。接口定义了业务操作,实现类则通过JdbcTemplate调用对应的方法。例如: ```java public interface ...

    Spring--JdbcTemplate.pdf

    4. 在DAO类中注入JdbcTemplate对象,这通常是通过Spring的依赖注入特性完成的。 5. 创建与数据库表对应的实体类,用于在Java代码中表示表中的数据。 6. 编写Service和DAO类中实现具体数据库操作的方法,如添加、删除...

    SpringMVC整合jdbcTemplate实例

    4. **创建DAO层**:使用jdbcTemplate,创建DAO接口和实现类,如`UserDao`,实现用户相关的增删改查操作。 5. **编写Service层**:创建Service接口和实现类,如`UserService`,调用DAO进行业务逻辑处理,并进行事务...

    JdbcTemplate使用.doc

    最后,配置DAO实现类的`bean`,并注入`JdbcTemplate`: ```xml &lt;property name="jt" ref="jdbcTemplate"/&gt; ``` 完成上述步骤后,我们就可以在服务层或者控制器层通过@Autowired注解注入`UserDao`,并调用其方法...

    在Java的Servlet中使用Spring JdbcTemplate-Eclipse版

    本资源是一个完整的通过Servlet-Service-Dao-JdbcTemplate访问MySQL数据库的JavaWeb Project,可以直接导入到Eclipse中进行调试运行,注意默认编译器是JDK1.8。

    基于注解的Spring JdbcTemplate

    **基于注解的Spring JdbcTemplate** 在Java世界中,Spring框架是企业级应用开发的首选。Spring JDBC模絫提供了一种简洁的方式来处理数据库操作,而`Spring JdbcTemplate`是这个模絫的核心组件。本教程将深入探讨...

    J2EE 0.2—加入dao\\dataSource\\jdbcTemplate等联系方法

    本话题将详细讲解如何在J2DAO(Data Access Object)模式下,结合dataSource和jdbcTemplate,实现高效且灵活的数据访问功能。 首先,dataSource是Java中的一个接口,它在JDBC(Java Database Connectivity)中扮演...

    一个简单的spring-jdbctemplate扩展

    使用JdbcTemplate扩展,开发者可以创建自定义的DAO接口,这些接口定义了特定的数据库操作,然后在实现类中利用JdbcTemplate提供的模板方法来完成这些操作。例如,可能会有一个`UserDao`接口,其中包含`getUserById`...

    JdbcTemplate简单实例

    **JdbcTemplate简单实例** 在Java开发中,数据库操作是一个非常重要的环节。Spring框架提供了一个强大的...在实际项目中,结合其他Spring组件,如DAO层、Service层,JdbcTemplate能够构建出高效且健壮的数据库访问层。

    Spring JdbcTemplate api

    在Spring框架中,可以为每个DAO配置单独的`JdbcTemplate`实例,或者让DAO类继承`JdbcDaoSupport`类,这样可以通过调用`getJdbcTemplate()`方法来获取`JdbcTemplate`实例。书中提到的做法是为每个DAO添加一个`...

    Spring的JDBCTemplate

    `JDBCTemplate`在内部会自动捕获JDBC异常,并将其转换为Spring DAO层的异常,这使得异常处理更加统一和方便。所有转换后的异常都是非检查异常,开发者可以选择性地捕获这些异常。 示例代码如下: ```java try { ...

    jdbcTemplate分页彻底解决,使用游标滚动

    在Java的Spring框架中,`JdbcTemplate`是一个非常重要的组件,它提供了数据库操作的简单抽象,使得开发者可以方便地执行SQL语句而无需编写复杂的DAO(数据访问对象)层。在处理大量数据时,传统的分页方法可能会导致...

    springmvc JdbcTemplate demo

    3. 创建DAO层:创建一个接口,定义数据库操作的方法,然后创建其实现类,使用@Autowired注入JdbcTemplate。 ```java public interface UserRepository { User getUserById(int id); } public class ...

    Spring框架JdbcTemplate类中查询方法介绍

    Spring 框架 JdbcTemplate 类中查询方法介绍 JdbcTemplate 是 Spring 框架中 org.springframework.jdbc.core 包提供的 JDBC 模板类,它是核心类,其他模板类都是基于它封装完成的。JdbcTemplate 类主要提供四类方法...

    springmvc-jdbcTemplate

    @Autowired protected JdbcTemplate jdbcTemplate; /** SQL语句参数带名称的JDBC模版对象 */ protected NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** 分页SQL语句创建对象 */ protected ...

Global site tag (gtag.js) - Google Analytics