SpringJdbc之queryForXXX大全解读

 

1.查询单个字段


Object queryForObject(String sql, Object[] args, Class requiredType)


其中Class requiredType 参数为返回值的类型(可以为常见的类库中的类类型)比如String.class


参数“requiredType”不可以是自定义的类




2.查询多个字段


Object queryForObject(String sql, Object[] args, RowMapper rowMapper)


其中Rowmapper 需要new一下 给该接口一个类类型,它负责给你返回一个对象(需要什么值要自己set,建议全部set)


如果要把查询结果封装为自定义的类,需要采用第2个方法




//只查询一列:name

String sql = "SELECT NAME FROM CUSTOMER WHERE CUST_ID = ?";

String name = (String)getJdbcTemplate().queryForObject(

sql, new Object[] { custId }, String.class);

return name;

//查询返回自定义的类

String sql = "SELECT * FROM CUSTOMER WHERE CUST_ID = ?";

Customer customer = (Customer)getJdbcTemplate().queryForObject(

sql, new Object[] { custId },

new BeanPropertyRowMapper(Customer.class));

return customer;


我们接着分析下BeanPropertyRowMapper


其实不用看源码都知道思路了: 
new BeanPropertyRowMapper(User.class) 
mapRow(ResultSet rs, int rowNumber)


遍历ResultSet,每一行对应一个User 对象


遍历每一行时,顺序遍历各列,取得该列的值通过反射调用对应的setter方法,赋值给到User 对象


注意到无论是取列名还是取列的值,都是通过index(1~columnCount)来取的

public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
                T mappedObject = BeanUtils.instantiate(this.mappedClass);
                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);

                ResultSetMetaData rsmd = rs.getMetaData();
                int columnCount = rsmd.getColumnCount();
                Set<String> populatedProperties = (isCheckFullyPopulated() ? new HashSet<String>() : null);

                for (int index = 1; index <= columnCount; index++) {
                        String column = JdbcUtils.lookupColumnName(rsmd, index);
                        PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase());
                        if (pd != null) {
                                try {
                                        Object value = getColumnValue(rs, index, pd);
                                    bw.setPropertyValue(pd.getName(), value);
                                        if (populatedProperties != null) {
                                                populatedProperties.add(pd.getName());
                                        }
                                }
                        }
                }

                if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) {
                        throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields " +
                                        "necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties);
                }

                return mappedObject;
        }

注意到mapRow方法里面,populatedProperties变量是用来检查是否所有的property都正确地实现了赋值 
再看看BeanPropertyRowMapper的构造函数:

public BeanPropertyRowMapper(Class<T> mappedClass) {

initialize(mappedClass);

}

protected void initialize(Class<T> mappedClass) {

this.mappedClass = mappedClass;

/*保存field

注意到对于驼峰式命名的field:

例如,对于gameId, mappedFields 会同时保存"gameId"和"game_id"

因此在sql语句中,

select  id as game_id, name from game和

select  id as gameId, name from game的效果是一样的

*/

this.mappedFields = new HashMap<String, PropertyDescriptor>();

//保存property

this.mappedProperties = new HashSet<String>();

PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass);

for (PropertyDescriptor pd : pds) {

if (pd.getWriteMethod() != null) {

this.mappedFields.put(pd.getName().toLowerCase(), pd);

String underscoredName = underscoreName(pd.getName());

if (!pd.getName().toLowerCase().equals(underscoredName)) {

this.mappedFields.put(underscoredName, pd);

}

this.mappedProperties.add(pd.getName());

}

}

}

//1. "game", return "game", unchanged

//2. "gameId", return "game_id"

private String underscoreName(String name) {

//......

}

二、查询返回对象或者list

思路:首先在Bean里面实现RowMapper和序列化接口(序列化可有可无)

接着在maprow方法中将rs取出来的值set到当前Bean对象里面

当然命名也要响应的变化下比如:UserPo,然后返回该对象最

后在new 的RowMapper接口中直接new 该Po就ok

【此方法适用于查询单个对象,或者多个对象组成的List或者Map】


/**
 * 实现数据表与字段的映射
 *
 * @author andy
 *
 */
public class UserInfo implements RowMapper<UserInfo>, Serializable {

    /**
     *
     */
    private static final long serialVersionUID = -8823504831198719837L;

    private Integer id;

    private String uname;

    private Integer unumber;

    private Date uRegisterTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname == null ? null : uname.trim();
    }

    public Integer getUnumber() {
        return unumber;
    }

    public void setUnumber(Integer unumber) {
        this.unumber = unumber;
    }

    public Date getuRegisterTime() {
        return uRegisterTime;
    }

    public void setuRegisterTime(Date uRegisterTime) {
        this.uRegisterTime = uRegisterTime;
    }

    @Override
    public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(rs.getInt("id"));
        userInfo.setUname(rs.getString("uname"));
        userInfo.setUnumber(rs.getInt("unumber"));
        userInfo.setuRegisterTime(rs.getDate("uregister_time"));
        return userInfo;
    }

}
@Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Override
    public UserInfo getById(Integer id) {

        String sql = "SELECT * FROM user_info WHERE id = ?";

        UserInfo userInfo = jdbcTemplate.queryForObject(sql, new UserInfo(),
                new Object[] { id });

        return userInfo;
    }

    @Override
    public List<UserInfo> findAll() {
        String sql = "SELECT * FROM user_info";
        List<UserInfo> userInfos = jdbcTemplate.query(sql, new UserInfo());
        return userInfos;
    }

=======================================================================================

三、第三种方法

使用很少人使用的RowSet

SqlRowSet set =  queryForRowSet(sql,对象参数数组);

if(set==null){

  new AuthenticationException("null");

}

while(set.next){

遍历:

set.getString(此处参数类型为整形,表示你想要查出来的结果,按照顺序,依次是1、2、3.......索引从1开始)

}

注意该方法适用于:查询单个对象或者List,Map结果的情况

必须谨记若用他查出来一条数据或者一个对象时:

在判断条件的时候必须加set.next&&在跟其他条件,否则会报错"光标位置失效"

时间: 2024-10-12 05:18:57

SpringJdbc之queryForXXX大全解读的相关文章

全面解读java虚拟机(面试考点大全)

学习java以来,jvm的原理已经看过好多遍了,但是许多知识点都串不起来.今天我把jvm相关知识整理了一下,看完之后肯定会对JVM非常的清楚. JVM是虚拟机,也是一种规范,他遵循着冯·诺依曼体系结构的设计原理.冯·诺依曼体系结构中,指出计算机处理的数据和指令都是二进制数,采用存储程序方式不加区分的存储在同一个存储器里,并且顺序执行,指令由操作码和地址码组成,操作码决定了操作类型和所操作的数的数字类型,地址码则指出地址码和操作数.从dos到window8,从unix到ubuntu和CentOS,

meta标签 解读大全

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui" /> width: viewport 的宽度 (范围从 200 到 10,000 ,默认为 980 像素 ) height: viewport 的高度 (范围从 223 到 10,000 ) initial-scale: 初始的缩放比例 (范围从>0到 1

经典创意slogan大全

一句好的广告语,能强烈的激发人的感情,产生心理认同感.对于广告人来说,无论走到哪里,最敏感的就是广告语.一句广告语,可能只有短短几个字或一两句话,却是一个品牌的精华所在.能不能第一时间吸引受众眼球,抓顾客的心,是无数广告人夜不能寐思考的问题.一句简洁.有力的Slogan,汇聚了品牌的理念.企业的价值观.发展愿景,甚至企业的员工.领导习惯,还有当下的市场环境等等方面.例如苹果的:Think different,看似很简单,却直指人心.今天,先知中国命名网小编给大家整理了经典创意slogan大全,供

Jsoup代码解读之六-防御XSS攻击

Jsoup代码解读之八-防御XSS攻击 防御XSS攻击的一般原理 cleaner是Jsoup的重要功能之一,我们常用它来进行富文本输入中的XSS防御. 我们知道,XSS攻击的一般方式是,通过在页面输入中嵌入一段恶意脚本,对输出时的DOM结构进行修改,从而达到执行这段脚本的目的.对于纯文本输入,过滤/转义HTML特殊字符<,>,",'是行之有效的办法,但是如果本身用户输入的就是一段HTML文本(例如博客文章),这种方式就不太有效了.这个时候,就是Jsoup大显身手的时候了. 在前面,我

Excel图表编程应用大全(2):图表编程基础

嵌入式图表和图表工作表图表在工作表中有两种存在方式: 嵌入式图表与工作表的数据在一起,或者与其他的嵌入式图表在一起. 图表工作表是特定的工作表,只包含单独的图表. (1)嵌入式图表当希望图表作为工作表的一部分,与数据或其他图表在一起时,嵌入式图表是最好的选择.Chart对象代表每一个嵌入式图表,包含在ChartObject对象里.每个Excel工作表都有一个ChartObjects集合,包含工作表中每个嵌入式图表.为了在工作表中添加新的嵌入式图表,在集合中添加ChartObject对象,其语法为

java面试基础大全,绝对经典&lt;126-170&gt;&lt;转&gt;

这部分主要是开源Java EE框架方面的内容,包括hibernate.MyBatis.spring.Spring MVC等,由于Struts 2已经是明日黄花,在这里就不讨论Struts 2的面试题,如果需要了解相关内容,可以参考我的另一篇文章<Java面试题集(86-115)>.此外,这篇文章还对企业应用架构.大型网站架构和应用服务器优化等内容进行了简单的探讨,这些内容相信对面试会很有帮助. 126.什么是ORM? 答:对象关系映射(Object-Relational Mapping,简称O

由SpringJdbc引发的一点思考

本来项目中使用的是Hibernate,后来换Mybatis,但由于项目中很多sql语句是动态的,无实体,参数不固定,列也不固定,Mybatis显得太重量了,所以我又选择用spring jdbc这种更轻量的封转替换掉原来的jdbc,更换dao层真心让我想吐了. 其实,无论Spring jdbc,Hibernate,还是mybatis都是对jdbc的封装,封装不变的部分,留下可变的部分让我们自己写. 使用 Spring jdbc,其实最主要的是使用它的三个模板,Spring的JdbcTemplate

三分钟解读springmvc依赖

长期以来都在写SSM框架的项目,却未能深入理解框架的搭建原理,而只是浅薄的理解前辈的架构,然后不断套用,项目做过几个,但框架的内涵却没有把握.小编打算今天从SpringMVC的依赖分析做起,一步步进行系统化学习. 从springFramework的官方文档入手: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#overview-getting-started-with-spring

MVC5 + EF6 + Bootstrap3 (9) HtmlHelper用法大全(下)

文章来源:Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc5-ef6-bs3-get-started-httphelper-part2.html 上一节:MVC5 + EF6 + Bootstrap3 (8) HtmlHelper用法大全(上) 源码下载:点我下载 目录: 说明 Form表单 使用TagBuilder创建自定义标签 强类型HtmlHelper LabelFor数据标签 DisplayFor 和 EditorFor显示和编辑Model