文档章节

Spring Jdbc 泛型使用

zhuyuping
 zhuyuping
发布于 2016/04/11 17:29
字数 1525
阅读 279
收藏 15

其实一直以来 我使用了 很多hibernate mybatis 都挺简单,但是性能 方面 一直感觉一般般,个人偏向使用原生的jdbc 其实写起来 也挺简单的,当能力跨越了这一个层次的时候 ,这些mybatis hibernate 其实并不那么重要了 我其实也不再户什么框架不框架了 ,这里分享一个我常用的jdbc的类 。这是我去年一直使用的类,最开始在一个博客上收集的一个,但是缺少了 很多类,于是我自己补全了 所有的类,使用jdbc 原生类 jdbcTemplate性能 速度 还是很好的。我不太喜欢 mybatis 虽然mybatis mybatis 当类太多 mapper.xml太多的时候阅读起来很烦的。




1.BASEDAO

/**
 * 
 * 
 * @zhuyuping
 * @2014-3-30      
 * @doc:
 */
public abstract class BaseDao<T>  {
	/** 具体操作的实体类对象 */
    private Class<T>       entityClass;

    /** 名称加工处理器 */
    private NameHandler    nameHandler;
	/**
	 * jdbcTemplate
	 */
	@Resource
	protected JdbcTemplate jdbcTemplate;
	/**
	 * nameJdbcTemplate
	 */
	@Resource
	protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    /**
     * 构造方法,获取运行时的具体实体对象
     */
    public BaseDao() {
        Type superclass = getClass().getGenericSuperclass();
        ParameterizedType type = (ParameterizedType) superclass;
        entityClass = (Class<T>) type.getActualTypeArguments()[0];
    }

    /**
     * 获取实际运行时的名称处理器
     *
     * @return
     */
    private NameHandler getActualNameHandler() {
        if (nameHandler == null) {
            synchronized (this) {
                if (nameHandler == null) {
                    nameHandler = this.getNameHandler();
                }
            }
        }
        return nameHandler;
    }

    /**
     * 得到名称处理器,子类覆盖此方法实现自己的名称转换处理器
     *
     * @return
     */
    protected NameHandler getNameHandler() {
        return new DefaultNameHandler();
    }

    /**
     * 插入一条记录
     *
     * @param entity
     */
    public Long insert(T entity) {
        final SqlContext sqlContext = SqlUtils.buildInsertSql(entity, this.getActualNameHandler());
       
        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                PreparedStatement ps = con.prepareStatement(sqlContext.getSql().toString(),
                    new String[] { sqlContext.getPrimaryKey() });
                int index = 0;
                for (Object param : sqlContext.getParams()) {
                    index++;
                    ps.setObject(index, param);
                }
                return ps;
            }
        }, keyHolder);
        return keyHolder.getKey().longValue();
    }

    /**
     * 更新记录
     * 
     * @param entity
     */
    public void update(T entity) {
        SqlContext sqlContext = SqlUtils.buildUpdateSql(entity, this.getActualNameHandler());
        jdbcTemplate.update(sqlContext.getSql().toString(), sqlContext.getParams().toArray());
    }

    /**
     * 删除记录
     *
     * @param id
     */
    public void delete(Serializable id) {
        String tableName = this.getActualNameHandler().getTableName(entityClass.getSimpleName());
        String primaryName = this.getNameHandler().getPrimaryName(entityClass.getSimpleName());
        String sql = "DELETE FROM " + tableName + " WHERE " + primaryName + " = ?";
        jdbcTemplate.update(sql, id);
    }

    /**
     * 删除所有记录
     */
    public void deleteAll() {
        String tableName = this.getActualNameHandler().getTableName(entityClass.getSimpleName());
        String sql = " TRUNCATE TABLE " + tableName;
        jdbcTemplate.execute(sql);
    }

    /**
     * 得到记录
     *
     * @param id
     * @return
     */
    public T getById(Serializable id) {
        String tableName = this.getNameHandler().getTableName(entityClass.getSimpleName());
        String primaryName = this.getNameHandler().getPrimaryName(entityClass.getSimpleName());
        String sql = "SELECT * FROM " + tableName + " WHERE " + primaryName + " = ?";
        return (T) jdbcTemplate.query(sql,
            new DefaultRowMapper(entityClass, this.getActualNameHandler()), id).get(0);
    }

    /**
     * 查询所有记录
     * 
     * @return
     */
    public List<T> findAll() {
        String sql = "SELECT * FROM "
                     + this.getActualNameHandler().getTableName(entityClass.getSimpleName());
        return (List<T>) jdbcTemplate.query(sql,
            new DefaultRowMapper(entityClass, this.getActualNameHandler()));
    }

    /**
     * 查询记录数
     * 
     * @param entity
     * @return
     */
    public int queryCount(T entity) {
        String tableName = this.getActualNameHandler().getTableName(entityClass.getSimpleName());
        StringBuilder countSql = new StringBuilder("select count(*) from ");
        countSql.append(tableName);
        SqlContext sqlContext = SqlUtils.buildQueryCondition(entity, this.getActualNameHandler());
        if (sqlContext.getSql().length() > 0) {
            countSql.append(" where ");
            countSql.append(sqlContext.getSql());
        } 
        return jdbcTemplate.queryForObject(countSql.toString(), sqlContext.getParams().toArray(),Integer.class);
       
    }

   /* *//**
     * 查询分页列表
     * 
     * @param entity
     * @return
     *//*
    public Pager queryPageList(T entity) {
        Pager pager = new Pager();
        PagingOrder pagingOrder = (PagingOrder) entity;
        pager.setCurPage(pagingOrder.getCurPage());
        pager.setItemsPerPage(pagingOrder.getItemsPerPage());

        String tableName = this.getActualNameHandler().getTableName(entityClass.getSimpleName());
        String primaryName = this.getActualNameHandler()
            .getPrimaryName(entityClass.getSimpleName());
        StringBuilder querySql = new StringBuilder("select * from ");
        StringBuilder countSql = new StringBuilder("select count(*) from ");
        querySql.append(tableName);
        countSql.append(tableName);
        //不调用queryCount方法,条件共同组装一次,减少反射获取的次数
        SqlContext sqlContext = SqlUtils.buildQueryCondition(entity, this.getActualNameHandler());
        if (sqlContext.getSql().length() > 0) {
            querySql.append(" where ");
            countSql.append(" where ");
            querySql.append(sqlContext.getSql());
            countSql.append(sqlContext.getSql());
        }
        querySql.append(" order by ");
        querySql.append(primaryName);
        querySql.append(" desc ");
        querySql.append("limit ?,?");
        List<Object> queryParams = new ArrayList<Object>(sqlContext.getParams());
        queryParams.add(pager.getBeginIndex());
        queryParams.add(pager.getItemsPerPage());

        List<T> list = (List<T>) jdbcTemplate.query(querySql.toString(), queryParams.toArray(),
            new DefaultRowMapper(entityClass, this.getActualNameHandler()));

        int totalCount = jdbcTemplate.queryForInt(countSql.toString(), sqlContext.getParams()
            .toArray());
        pager.setList(list);
        pager.setItems(totalCount);
        return pager;
    }*/

}

2.NameHandler

/**
 * 把 驼峰法 改成 下划线 model userName -----> db user_name
 * 
 * @zhuyuping
 * @2015-3-30      
 * @doc:
 */
public class DefaultNameHandler implements NameHandler {


   

    /**
     * 根据实体名获取表名
     *
     * @param entityName
     * @return
     */
    @Override
    public String getTableName(String entityName) {
        //Java属性的骆驼命名法转换回数据库下划线“_”分隔的格式
        return ColumnFormatUtil.underLineName(entityName);
    }

    /**
     * 根据表名获取主键名
     *
     * @param entityName
     * @return
     */
    @Override
    public String getPrimaryName(String entityName) {
//        String underlineName = ColumnFormatUtil.underLineName(entityName);
//        //正如前面说到的,数据库列名统一以“_”开始,主键以表名加上“_id” 如user表主键即“_user_id”
//        return  underlineName + PRI_SUFFIX;
    	return "id";
    }

    /**
     * 根据属性名获取列名
     *
     * @param fieldName
     * @return
     */
    @Override
    public String getColumnName(String fieldName) {
        String underlineName = ColumnFormatUtil.underLineName(fieldName);
        
        return  underlineName;
    }
    public static void main(String[] args) {
		System.out.println("DefaultNameHandler.main()"+new DefaultNameHandler().getColumnName("userName"));
		System.out.println("DefaultNameHandler.main()"+new DefaultNameHandler().getTableName("userName"));
	
	}
    
}

 3.Mapper

  

import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import com.zsuper.base.utils.ClassUtils;


/**
 * 
 * 
 * @zhuyuping
 * @2014-3-30      
 * @doc:通用映射器
 */
public class DefaultRowMapper implements RowMapper<Object> {

    /** 转换的目标对象 */
    private Class<?>    clazz;

    /** 名称处理器 */
    private NameHandler nameHandler;

    public DefaultRowMapper(Class<?> clazz, NameHandler nameHandler) {
        this.clazz = clazz;
        this.nameHandler = nameHandler;
    }

    @Override
    public Object mapRow(ResultSet resultSet, int i) throws SQLException {
        Object entity = ClassUtils.newInstance(this.clazz);
        BeanInfo beanInfo = ClassUtils.getSelfBeanInfo(this.clazz);
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            String column = nameHandler.getColumnName(pd.getName());
            Method writeMethod = pd.getWriteMethod();
            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                writeMethod.setAccessible(true);
            }
            try {
                writeMethod.invoke(entity, resultSet.getObject(column));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return entity;
    }
}

  4。Jdbc

   

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import com.zsuper.base.utils.SqlUtils;


public  class JdbcExector  {
	/** 具体操作的实体类对象 */

    /** 名称加工处理器 */
    private NameHandler    nameHandler;

    /** spring jdbcTemplate 对象 */
    @Autowired
    protected JdbcTemplate jdbcTemplate;

    /**
     * 构造方法,获取运行时的具体实体对象
     */
    public JdbcExector() {
    }

    /**
     * 获取实际运行时的名称处理器
     *
     * @return
     */
    private NameHandler getActualNameHandler() {
        if (nameHandler == null) {
            synchronized (this) {
                if (nameHandler == null) {
                    nameHandler = this.getNameHandler();
                }
            }
        }
        return nameHandler;
    }

    /**
     * 得到名称处理器,子类覆盖此方法实现自己的名称转换处理器
     *
     * @return
     */
    protected NameHandler getNameHandler() {
        return new DefaultNameHandler();
    }

    /**
     * 插入一条记录
     *
     * @param entity
     * @throws Exception 
     * @throws IllegalArgumentException 
     */
    public <T> Long insert(T entity) throws Exception {
        final SqlContext sqlContext = SqlUtils.buildInsertSql(entity, this.getActualNameHandler());
        System.out.println(entity+"==="+sqlContext.getSql());
        /*KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                PreparedStatement ps = con.prepareStatement(sqlContext.getSql().toString(),
                    new String[] { sqlContext.getPrimaryKey() });
                int index = 0;
                for (Object param : sqlContext.getParams()) {
                    index++;
                    ps.setObject(index, param);
                }
                return ps;
            }
        }, keyHolder);
        return keyHolder.getKey().longValue();*/
        return null;
    }

    
    public static void main(String[] args) throws Exception {
		//new JdbcExector().insert(TestUser.class);
    	TestUser testUser=new TestUser();
    	testUser.setAge(22);
    	testUser.setCnName("xxx");
    	testUser.setTestUserId(1);
    	SqlContext context=SqlUtils.buildUpdateSql(testUser, new DefaultNameHandler());
    	System.out.println("JdbcExector.main()         "+context.getSql());
	}
   
}
5.SqlContext

/**
 * 
 * 
 * @zhuyuping
 * @2014-3-30      
 * @doc:sql 上下文 
 */
public class SqlContext {

    public StringBuilder getSql() {
		return sql;
	}

	public void setSql(StringBuilder sql) {
		this.sql = sql;
	}

	public String getPrimaryKey() {
		return primaryKey;
	}

	public void setPrimaryKey(String primaryKey) {
		this.primaryKey = primaryKey;
	}

	public List<Object> getParams() {
		return params;
	}

	public void setParams(List<Object> params) {
		this.params = params;
	}

	/** 执行的sql */
    private StringBuilder sql;

    /** 主键名称 */
    private String        primaryKey;

    /** 参数,对应sql中的?号 */
    private List<Object>  params;

    public SqlContext(StringBuilder sql, String primaryKey, List<Object> params) {
        this.sql = sql;
        this.primaryKey = primaryKey;
        this.params = params;
    }

}

  

© 著作权归作者所有

共有 人打赏支持
zhuyuping
粉丝 305
博文 36
码字总数 51047
作品 0
徐汇
程序员
私信 提问
加载中

评论(1)

程序那些年
程序那些年
不错,收藏了
Spring 中好用的泛型操作API

随着泛型用的越来越多,获取泛型实际类型信息的需求也会出现,如果用原生API,需要很多步操作才能获取到泛型,比如: ParameterizedType parameterizedType = (ParameterizedType) ABServic...

宇的季节
2018/06/06
0
0
Spring框架笔记(二十四)——Spring中的JDBC的两种使用方式

为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架. 作为 Spring JDBC 框架的核心, JDBC 模板的设计目的是为不同类型的 JDBC 操作提供模板方法...

HappyBKs
2015/08/26
0
0
【Java学习路线】新手该如何一步步的学习 Java

新手该如何一步步的学习 Java? 如果真的想学Java,最好要循序渐进,有章有法的学习它! 今天小慕就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容。 首先,给大家分享一张以 企业...

Eddie_yang
2018/11/15
131
0
Spring4新特性——泛型限定式依赖注入

Spring4新特性——泛型限定式依赖注入 Spring4新特性——核心容器的其他改进 Spring4新特性——Web开发的增强 Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC Spring4新特性...

Big_BoBo
2013/12/26
0
0
Spring Boot 整合 MyBatis/通用Mapper/PageHelper分页插件

整合MyBatis 整合通用Mapper 0. 基础知识 通用Mapper一般配置MyBatis, MBG插件使用 个人实践证明,通用Mapper配合其特定的MBG插件不如直接使用官方MBG插件方便 1. POM依赖配置 2. 通用Mappe...

OSC_fly
2018/07/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Cookie 显示用户上次访问的时间

import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.serv......

gwl_
37分钟前
1
0
网络编程

第14天 网络编程 今日内容介绍  网络通信协议  UDP通信  TCP通信 今日学习目标  能够辨别UDP和TCP协议特点  能够说出UDP协议下两个常用类名称  能够说出TCP协议下两个常用类名称...

stars永恒
今天
1
0
二进制相关

二进制 众所周知计算机使用的是二进制,数字的二进制是如何表示的呢? 实际就是逢二进一。比如 2 用二进制就是 10。那么根据此可以推算出 5的二进制等于 10*10+1 即为 101。 在计算机中,负数以...

NotFound403
昨天
3
0
day22:

1、写一个getinterface.sh 脚本可以接受选项[i,I],完成下面任务: 1)使用格式:getinterface.sh [-i interface | -I ip] 2)当用户使用-i选项时,显示指定网卡的IP地址;当用户使用-I选项...

芬野de博客
昨天
2
0
Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现

自Spring Cloud Alibaba发布第一个Release以来,就备受国内开发者的高度关注。虽然Spring Cloud Alibaba还没能纳入Spring Cloud的主版本管理中,但是凭借阿里中间件团队的背景,还是得到不少...

程序猿DD
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部