`
jinnianshilongnian
  • 浏览: 21503087 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2418455
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3008661
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5639353
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:259899
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597268
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250209
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5858833
Group-logo
跟我学Nginx+Lua开...
浏览量:701943
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785142
社区版块
存档分类
最新评论

【第七章】 对JDBC的支持 之 7.3 关系数据库操作对象化 ——跟我学spring3

阅读更多

7.3.1  概述

       所谓关系数据库对象化其实就是用面向对象方式表示关系数据库操作,从而可以复用。

Spring JDBC框架将数据库操作封装为一个RdbmsOperation,该对象是线程安全的、可复用的对象,是所有数据库对象的父类。而SqlOperation继承了RdbmsOperation,代表了数据库SQL操作,如select、update、call等,如图7-4所示。

 

 

图7-4 关系数据库操作对象化支持类

 

数据库操作对象化只要有以下几种类型,所以类型是线程安全及可复用的:

  • 查询:将数据库操作select封装为对象,查询操作的基类是SqlQuery,所有查询都可以使用该类表示,Spring JDBC还提供了一些更容易使用的MappingSqlQueryWithParameters和MappingSqlQuery用于将结果集映射为Java对象,查询对象类还提供了两个扩展UpdatableSqlQuery和SqlFunction;
  • 更新:即增删改操作,将数据库操作insert 、update、delete封装为对象,增删改基类是SqlUpdate,当然还提供了BatchSqlUpdate用于批处理;
  • 存储过程及函数:将存储过程及函数调用封装为对象,基类是SqlCall类,提供了StoredProcedure实现。

 

7.3.2  查询

1)SqlQuery需要覆盖如下方法来定义一个RowMapper,其中parameters参数表示命名参数或占位符参数值列表,而context是由用户传入的上下文数据。

 

java代码:
RowMapper<T> newRowMapper(Object[] parameters, Map context)

 

       SqlQuery提供两类方法:

  • execute及executeByNamedParam方法:用于查询多行数据,其中executeByNamedParam用于支持命名参数绑定参数;
  • findObject及findObjectByNamedParam方法:用于查询单行数据,其中findObjectByNamedParam用于支持命名参数绑定。

 

演示一下SqlQuery如何使用:

 

java代码:
@Test
public void testSqlQuery() {
    SqlQuery query = new UserModelSqlQuery(jdbcTemplate);
    List<UserModel> result = query.execute("name5");
    Assert.assertEquals(0, result.size());
}

 

从测试代码可以SqlQuery使用非常简单,创建SqlQuery实现对象,然后调用相应的方法即可,接下来看一下SqlQuery实现:

 

java代码:
package cn.javass.spring.chapter7;
//省略import
public class UserModelSqlQuery extends SqlQuery<UserModel> {
    public UserModelSqlQuery(JdbcTemplate jdbcTemplate) {
        //super.setDataSource(jdbcTemplate.getDataSource());
        super.setJdbcTemplate(jdbcTemplate);
        super.setSql("select * from test where name=?");
        super.declareParameter(new SqlParameter(Types.VARCHAR));
        compile();
    }
    @Override
    protected RowMapper<UserModel> newRowMapper(Object[] parameters, Map context) {
        return new UserRowMapper();
    }
}
 

 

从测试代码可以看出,具体步骤如下:

一、setJdbcTemplate/ setDataSource:首先设置数据源或JdbcTemplate;

二、setSql("select * from test where name=?"):定义sql语句,所以定义的sql语句都将被编译为PreparedStatement;

三、declareParameter(new SqlParameter(Types.VARCHAR)):对PreparedStatement参数描述,使用SqlParameter来描述参数类型,支持命名参数、占位符描述;

对于命名参数可以使用如new SqlParameter("name", Types.VARCHAR)描述;注意占位符参数描述必须按占位符参数列表的顺序进行描述;

四、编译:可选,当执行相应查询方法时会自动编译,用于将sql编译为PreparedStatement,对于编译的SqlQuery不能再对参数进行描述了。

五、以上步骤是不可变的,必须按顺序执行。

 

 

2)MappingSqlQuery用于简化SqlQuery中RowMapper创建,可以直接在实现mapRow(ResultSet rs, int rowNum)来将行数据映射为需要的形式;

MappingSqlQuery所有查询方法完全继承于SqlQuery。

演示一下MappingSqlQuery如何使用:

 

java代码:
@Test
public void testMappingSqlQuery() {
    jdbcTemplate.update("insert into test(name) values('name5')");
    SqlQuery<UserModel> query = new UserModelMappingSqlQuery(jdbcTemplate);
    Map<String, Object> paramMap = new HashMap<String, Object>();
    paramMap.put("name", "name5");
    UserModel result = query.findObjectByNamedParam(paramMap);
    Assert.assertNotNull(result);
}

 

MappingSqlQuery使用和SqlQuery完全一样,创建MappingSqlQuery实现对象,然后调用相应的方法即可,接下来看一下MappingSqlQuery实现,findObjectByNamedParam方法用于执行命名参数查询:

 

java代码:
package cn.javass.spring.chapter7;
//省略import
public class UserModelMappingSqlQuery extends MappingSqlQuery<UserModel> {
  public UserModelMappingSqlQuery(JdbcTemplate jdbcTemplate) {
    super.setDataSource(jdbcTemplate.getDataSource());
    super.setSql("select * from test where name=:name");
    super.declareParameter(new SqlParameter("name", Types.VARCHAR));
    compile();
  }
  @Override
  protected UserModel mapRow(ResultSet rs, int rowNum) throws SQLException {
    UserModel model = new UserModel();
    model.setId(rs.getInt("id"));
    model.setMyName(rs.getString("name"));
    return model;
  } 
}

 

和SqlQuery唯一不同的是使用mapRow来讲每行数据转换为需要的形式,其他地方完全一样。

1)  UpdatableSqlQuery提供可更新结果集查询支持,子类实现updateRow(ResultSet rs, int rowNum, Map context)对结果集进行更新。

2)  GenericSqlQuery提供setRowMapperClass(Class rowMapperClass)方法用于指定RowMapper实现,在此就不演示了。具体请参考testGenericSqlQuery()方法。

3)  SqlFunctionSQL“函数”包装器,用于支持那些返回单行结果集的查询。该类主要用于返回单行单列结果集。

 

java代码:
@Test
public void testSqlFunction() {
    jdbcTemplate.update("insert into test(name) values('name5')");
    String countSql = "select count(*) from test";
    SqlFunction<Integer> sqlFunction1 = new SqlFunction<Integer>(jdbcTemplate.getDataSource(), countSql);
    Assert.assertEquals(1, sqlFunction1.run());
    String selectSql = "select name from test where name=?";
    SqlFunction<String> sqlFunction2 = new SqlFunction<String>(jdbcTemplate.getDataSource(), selectSql);
    sqlFunction2.declareParameter(new SqlParameter(Types.VARCHAR));
    String name = (String) sqlFunction2.runGeneric(new Object[] {"name5"});
    Assert.assertEquals("name5", name);
}

 

如代码所示,SqlFunction初始化时需要DataSource和相应的sql语句,如果有参数需要使用declareParameter对参数类型进行描述;run方法默认返回int型,当然也可以使用runGeneric返回其他类型,如String等。

 

7.3.3  更新

       SqlUpdate类用于支持数据库更新操作,即增删改(insert、delete、update)操作,该方法类似于SqlQuery,只是职责不一样。

       SqlUpdate提供了update及updateByNamedParam方法用于数据库更新操作,其中updateByNamedParam用于命名参数类型更新。

 

演示一下SqlUpdate如何使用:

 

java代码:
package cn.javass.spring.chapter7;
//省略import
public class InsertUserModel extends SqlUpdate {
    public InsertUserModel(JdbcTemplate jdbcTemplate) {
        super.setJdbcTemplate(jdbcTemplate);
        super.setSql("insert into test(name) values(?)");
        super.declareParameter(new SqlParameter(Types.VARCHAR));
        compile();
    }
}
 

 

 

java代码:
@Test
public void testSqlUpdate() {       
    SqlUpdate insert = new InsertUserModel(jdbcTemplate);
    insert.update("name5");
       
    String updateSql = "update test set name=? where name=?";
    SqlUpdate update = new SqlUpdate(jdbcTemplate.getDataSource(), updateSql, new int[]{Types.VARCHAR, Types.VARCHAR});
    update.update("name6", "name5");
    String deleteSql = "delete from test where name=:name";
 
    SqlUpdate delete = new SqlUpdate(jdbcTemplate.getDataSource(), deleteSql, new int[]{Types.VARCHAR});
    Map<String, Object> paramMap = new HashMap<String, Object>();
    paramMap.put("name", "name5");
    delete.updateByNamedParam(paramMap);
}

 

       InsertUserModel类实现类似于SqlQuery实现,用于执行数据库插入操作,SqlUpdate还提供一种更简洁的构造器SqlUpdate(DataSource ds, String sql, int[] types),其中types用于指定占位符或命名参数类型;SqlUpdate还支持命名参数,使用updateByNamedParam方法来进行命名参数操作。

 

7.3.4  存储过程及函数

       StoredProcedure用于支持存储过程及函数,该类的使用同样类似于SqlQuery。

       StoredProcedure提供execute方法用于执行存储过程及函数。

一、StoredProcedure如何调用自定义函数:

 

java代码:
@Test
public void testStoredProcedure1() {
    StoredProcedure lengthFunction = new HsqldbLengthFunction(jdbcTemplate);
    Map<String,Object> outValues = lengthFunction.execute("test");
    Assert.assertEquals(4, outValues.get("result"));
}   

 

StoredProcedure使用非常简单,定义StoredProcedure实现HsqldbLengthFunction,并调用execute方法执行即可,接下来看一下HsqldbLengthFunction实现:

 

java代码:
package cn.javass.spring.chapter7;
//省略import
public class HsqldbLengthFunction extends StoredProcedure {
    public HsqldbLengthFunction(JdbcTemplate jdbcTemplate) {
        super.setJdbcTemplate(jdbcTemplate);
        super.setSql("FUNCTION_TEST");
        super.declareParameter(
          new SqlReturnResultSet("result", new ResultSetExtractor<Integer>() {
            @Override
            public Integer extractData(ResultSet rs) throws SQLException, DataAccessException {
                while(rs.next()) {
                    return rs.getInt(1);
                }
                return 0;
            }
        }));
        super.declareParameter(new SqlParameter("str", Types.VARCHAR));
        compile();
    }
}

 

StoredProcedure自定义函数使用类似于SqlQuery,首先设置数据源或JdbcTemplate对象,其次定义自定义函数,然后使用declareParameter进行参数描述,最后调用compile(可选)编译自定义函数。

 

接下来看一下mysql自定义函数如何使用:

 

java代码:
@Test
public void testStoredProcedure2() {
    JdbcTemplate mysqlJdbcTemplate = new JdbcTemplate(getMysqlDataSource());
    String createFunctionSql =
        "CREATE FUNCTION FUNCTION_TEST(str VARCHAR(100)) " +
        "returns INT return LENGTH(str)";
    String dropFunctionSql = "DROP FUNCTION IF EXISTS FUNCTION_TEST";
    mysqlJdbcTemplate.update(dropFunctionSql);
    mysqlJdbcTemplate.update(createFunctionSql);
    StoredProcedure lengthFunction = new MysqlLengthFunction(mysqlJdbcTemplate);
    Map<String,Object> outValues = lengthFunction.execute("test");
    Assert.assertEquals(4, outValues.get("result"));
}

 

MysqlLengthFunction自定义函数使用与HsqldbLengthFunction使用完全一样,只是内部实现稍有差别:

 

java代码:
package cn.javass.spring.chapter7;
//省略import
public class MysqlLengthFunction extends StoredProcedure {
    public MysqlLengthFunction(JdbcTemplate jdbcTemplate) {
        super.setJdbcTemplate(jdbcTemplate);
        super.setSql("FUNCTION_TEST");
        super.setFunction(true);
        super.declareParameter(new SqlOutParameter("result", Types.INTEGER));
        super.declareParameter(new SqlParameter("str", Types.VARCHAR));
        compile();
    }
}

 

       MysqlLengthFunction与HsqldbLengthFunction实现不同的地方有两点:

  • setFunction(true)表示是自定义函数调用,即编译后的sql为{?= call …}形式;如果使用hsqldb不能设置为true,因为在hsqldb中{?= call …}和{call …}含义一样;
  • declareParameter(new SqlOutParameter("result", Types.INTEGER)):将自定义函数返回值类型直接描述为Types.INTEGER;SqlOutParameter必须指定name,而不用使用SqlReturnResultSet首先获取结果集,然后再从结果集获取返回值,这是mysql与hsqldb的区别;

 

一、StoredProcedure如何调用存储过程:

 

java代码:
@Test
public void testStoredProcedure3() {
    StoredProcedure procedure = new HsqldbTestProcedure(jdbcTemplate);
    Map<String,Object> outValues = procedure.execute("test");
    Assert.assertEquals(0, outValues.get("outId"));
    Assert.assertEquals("Hello,test", outValues.get("inOutName"));
}

 

 

StoredProcedure存储过程实现HsqldbTestProcedure调用与HsqldbLengthFunction调用完全一样,不同的是在实现时,参数描述稍有不同:

 

java代码:
package cn.javass.spring.chapter7;
//省略import
public class HsqldbTestProcedure extends StoredProcedure {
    public HsqldbTestProcedure(JdbcTemplate jdbcTemplate) {
        super.setJdbcTemplate(jdbcTemplate);
        super.setSql("PROCEDURE_TEST");
        super.declareParameter(new SqlInOutParameter("inOutName", Types.VARCHAR));
        super.declareParameter(new SqlOutParameter("outId", Types.INTEGER));
        compile();
    }
}
  • declareParameter使用SqlInOutParameter描述INOUT类型参数,使用SqlOutParameter描述OUT类型参数,必须按顺序定义,不能颠倒。
     
原创内容,转载请注明出处【http://sishuok.com/forum/blogPost/list/0/2491.html

11
6
分享到:
评论
7 楼 xiefengfeng 2014-08-06  
使用起来,感觉 SqlOperation方式 还不如 JdbcTemplate方式 来得方便。不知道SqlOperation方式是不是有特殊的用处
6 楼 mengfanxin 2013-10-03  
这篇写的不好,没一段能看的懂的,最基本的CRUD都没有
5 楼 jinnianshilongnian 2012-12-21  
slowvic 写道
这种方式看着挺晕的,还是比较喜欢模板方式。

是的
4 楼 slowvic 2012-12-21  
这种方式看着挺晕的,还是比较喜欢模板方式。
3 楼 hquxiezk 2012-09-27  
这种方式看起来很别扭,感觉是鸡肋
2 楼 jinnianshilongnian 2012-09-27  
lsjinpeng 写道
  
 
晕了。。。CRUD看着实现都差不多,但是看着怎么这么晕

其实我不喜欢这种方式 还是直接写sql来的清晰
1 楼 lsjinpeng 2012-09-27  
  
 
晕了。。。CRUD看着实现都差不多,但是看着怎么这么晕

相关推荐

    跟开涛学Spring

    1.32 【第七章】 对JDBC的支持 之 7.3 关系数据库操作对象化 ——跟我学spring3 . . . . . . . . . . . . . .324 1.33 【第七章】 对JDBC的支持 之 7.4 Spring提供的其它帮助 ——跟我学spring3【私塾在线原 创】 ...

    跟我学spring

    7.1节概述Spring对JDBC的支持,7.2节介绍JDBC模板类,7.3节讨论关系数据库操作对象化的方法,7.4节和7.5节介绍Spring提供的其他帮助和集成Spring JDBC及最佳实践。 【第八章】对ORM(对象关系映射)的支持。ORM框架...

    跟我学spring3

    压缩包中的"gen-wo-xue-spring.pdf"可能是教程的概述或部分章节,"跟我学spring3(1-7).pdf"和"跟我学spring3(8-13).pdf"分为了两部分,覆盖了从基础到进阶的内容。"跟我学spring3-源码.rar"包含了示例代码,方便读者...

    JDBC数据类型与数据库字段对应表——mysql篇

    JDBC数据类型与数据库字段对应表——mysql篇 数值型 整型 JDBC tinyint java.lang.Integer smallint mediumint java.lang.Long int bigint java.math.BigInteger

    JDBC数据类型与数据库字段对应表——SQL Server篇

    JDBC数据类型与数据库字段对应表——SQL Server篇 数值型 整型 JDBC tinyint java.lang.Integer smallint int bigint java.lang.Long mediumint java.lang.Long

    跟我学spring3(总共13章)8

    《跟我学Spring3》系列教程是为初学者和有经验的开发者提供的一份全面而深入的Spring框架学习资源。Spring3作为Java企业级应用开发的重要框架,它的核心特性包括依赖注入、AOP(面向切面编程)、数据访问、Web开发等...

    跟我学Spring,Spring3学习资料

    - **概述:** 介绍Spring对JDBC操作的支持,包括如何使用Spring提供的模板类来简化数据库操作。 - **JDBC模板类:** 为简化数据库操作提供了许多便利的方法。 - **关系数据库操作对象化:** 将传统JDBC操作中的结果...

    跟我学Spring3

    《跟我学Spring3》这本书是针对Java开发人员深入学习Spring框架第三版的一份教程。Spring作为Java企业级应用开发中的核心框架,它以其强大的功能、灵活性和模块化设计深受开发者喜爱。Spring3版本在前一版本基础上...

    跟我学Spring3(7.5)对JDBC的支持之集成Spr

    在Spring 3版本中,它提供了对JDBC的全面支持,以帮助开发者更高效、更安全地处理数据库操作。本篇将深入探讨Spring 3如何集成Spring JDBC以及最佳实践。 首先,Spring JDBC的核心组件是JdbcTemplate,它是Spring...

    跟我学spring3(1-13)

    《跟我学Spring3》是一本深入浅出介绍Spring框架的电子书,分为两部分,分别是“跟我学Spring3(8-13).pdf”和“跟我学Spring3(1-7).pdf”,全面覆盖了Spring框架的核心概念和技术。Spring作为Java开发中的主流框架,...

    跟我学spring3(1-7)

    《跟我学Spring3》系列教程涵盖了Spring框架的核心概念和技术,包括IoC(Inversion of Control,控制反转)、DI(Dependency Injection,依赖注入)、资源管理、Spring表达式语言(SpEL)以及面向切面编程(AOP)等...

    Jdbc第五章数据库实例

    **JDBC第五章数据库实例详解** 在Java编程中,JDBC(Java Database Connectivity)是用于与各种数据库进行交互的一组接口和类。JDBC提供了一种标准的API,使得Java开发者能够连接、查询和操作数据库,无论是Oracle...

    跟我学spring3 .pdf

    《跟我学Spring3》这本书是针对Spring框架进行深入解析的一本教程,涵盖了Spring的核心特性,包括IoC(Inversion of Control,控制反转)、DI(Dependency Injection,依赖注入)、AOP(Aspect-Oriented Programming...

    spring对jdbc的支持jar包

    总的来说,Spring对JDBC的支持使得数据库操作更加高效、安全且易于维护。它提供了丰富的API和抽象,帮助开发者避免了繁琐的JDBC代码,使他们能更专注于业务逻辑的实现。在Spring 4.0版本中,这些功能得到了进一步...

    适用SQL Server 2016版本的数据库加载驱动包——sqljdbc42.jar

    在IT行业中,数据库是存储和管理数据的核心工具,而SQL Server 2016是由Microsoft开发的一款企业级的关系型数据库管理系统。它提供了高效的数据存储、查询、分析和安全功能,广泛应用于各种业务系统。在Java应用程序...

    跟我学spring3-源码.

    《跟我学Spring3-源码》教程是一份深入解析Spring框架3.x版本核心源码的教育资源,适合对Java和J2EE技术有一定基础的开发者学习。本教程旨在帮助读者理解Spring框架的工作原理,提高在实际项目中的应用能力。通过...

    JAVA Spring boot JDBC同步不同服务器oracle数据库

    Java Spring Boot 框架与JDBC的集成是企业级应用开发中常见的一种技术组合,尤其在处理数据库交互时。本教程将详细讲解如何利用Spring Boot和JDBC实现跨服务器Oracle数据库的同步。 首先,Spring Boot简化了Java...

    JDBC——连接oracle数据库

    JDBC——连接oracle数据库

    跟我学Spring3(8.1)对ORM的支持之概述Java

    通过阅读《跟我学Spring3(8.1)对ORM的支持之概述Java开发Java经验技巧共3页.pdf》这本书或文档,你可以深入学习Spring如何无缝地集成ORM框架,提升你的Java开发技能。但请注意,压缩包内的"赚钱项目"文件可能与此...

    Spring Data JDBC与JDBC的区别

    3. **ORM支持**: 尽管不如JPA(Java Persistence API)强大,但Spring Data JDBC仍然提供了对象关系映射的能力,将Java对象与数据库表关联。 4. **简化事务管理**: Spring的事务管理器使得事务控制变得简单,无需...

Global site tag (gtag.js) - Google Analytics