JdbcTempalte spring-boot使用它 spring 整合

spring boot引入jdbcTemplate 

只要配置好mysql的数据源参数,启动项目,spriong boot就会自动建立jdbcTempalte,直接注入拿来用就行

JDBC常用的增仓改查

/**
     * jdbcTemplate.update适合于insert 、update和delete操作 DML语句 数据操作语句;
     * jdbcTemplate.execute()方法:可用于执行任何sql语句,但是一般用来执行DDL语句 定义语句; create、alter、drop和 truncate
     * jdbcTemplate.queryForList()    可以返回List<user>
     * jdbcTemplate.queryForObject()    可以返回一个User  或者一个字段
     * jdbcTemplate.query()
     *
//jdbcTemplate.update适合于insert 、update和delete操作;  
    /**   
     * (sql,Object...args) 
     */   
    public void save(User user) {  
        jdbcTemplate.update("insert into user_test(name,password) values(?,?)",   
                new Object[]{user.getUsername(),user.getPassword()});  
    }  

    /**   
     * (sql,Object...res,argsType) 
     */   
    @Override  
    public void save(User user) {  
        jdbcTemplate.update(  
                "insert into user_test(name,password) values(?,?)",   
                new Object[]{user.getUsername(),user.getPassword()},   
                new int[]{java.sql.Types.VARCHAR,java.sql.Types.VARCHAR}  
                );  
    }  

    /**
     * (sql,ps)
     */
    public void save( User user) {        
        jdbcTemplate.update("insert into user_test(name,password) values(?,?)",   
                new PreparedStatementSetter(){              
                    @Override  
                    public void setValues(PreparedStatement ps) throws SQLException {  
                        ps.setString(1, user.getUsername());  
                        ps.setString(2, user.getPassword());  
                    }  
        });  

    }  
    /**
     * (sql,Object...args)
     */  
    public void save(User user) {  
        jdbcTemplate.update("insert into user_test(name,password) values(?,?)",   
                             new Object[]{user.getUsername(),user.getPassword()});  
    }  

   //返回插入的主键  
   public List save(final User user) {       
        KeyHolder keyHolder = new GeneratedKeyHolder();   
        jdbcTemplate.update(new PreparedStatementCreator() {                 
        @Override  
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {  
            PreparedStatement ps = connection.prepareStatement("insert into user_test(name,password) values(?,?)", new String[] {"id"});  
            ps.setString(1, user.getUsername());  
            ps.setString(2, user.getPassword());  
            return ps;  
        }  
     },keyHolder);  

      return keyHolder.getKeyList();  
    }  
    /**
     * (sql,ps)
     */  
    @Override  
    public void update(final User user) {  
        jdbcTemplate.update(  
                "update user_test set name=?,password=? where id = ?",   
                new PreparedStatementSetter(){  
                    @Override  
                    public void setValues(PreparedStatement ps) throws SQLException {  
                        ps.setString(1, user.getUsername());  
                        ps.setString(2, user.getPassword());  
                        ps.setInt(3, user.getId());  
                    }  
                }  
        );  
    }  

    /**   
     * (sql,Object...res,argsType) 
     */ 
    @Override  
    public void delete(User user) {  
        Assert.isNull(user, "user is not null");  
        jdbcTemplate.update(  
                "delete from user_test where id = ?",   
                new Object[]{user.getId()},   
                new int[]{java.sql.Types.INTEGER});  
    }  

    @Deprecated 
    public int queryForInt1(){  
        return jdbcTemplate.queryForInt("select count(0) from user_test");  
    }  

    public int queryForInt2(User user){  
        return jdbcTemplate.queryForInt("select count(0) from tb_test1 where username = ?" ,  
                new Object[]{user.getUsername()});  
    }  

    //最全的参数3个  
    public int queryForInt3(User user){  
        return jdbcTemplate.queryForInt("select count(0) from user_testwhere username = ?" ,  
                new Object[]{user.getUsername()},  
                new int[]{java.sql.Types.VARCHAR});  
    }  

    //可以返回是一个基本类型的值  
    @Deprecated  //因为没有查询条件,所以用处不大  
    public String queryForObject1(User user) {  
        return (String) jdbcTemplate.queryForObject("select username from tb_test1 where id = 100",  
                                                    String.class);  
    }  

    //可以返回值是一个对象  
    @Deprecated //因为没有查询条件,所以用处不大  
    public User queryForObject2(User user) {  
        return (User) jdbcTemplate.queryForObject("select * from tb_test1 where id = 100", User.class); //class是结果数据的java类型  
    }  

    @Deprecated //因为没有查询条件,所以用处不大  
    public User queryForObject3(User user) {  
        return (User) jdbcTemplate.queryForObject("select * from tb_test1 where id = 100",   
                    new RowMapper(){  

                        @Override  
                        public Object mapRow(ResultSet rs, int rowNum)throws SQLException {  
                            User user  = new User();  
                            user.setId(rs.getInt("id"));  
                            user.setUsername(rs.getString("username"));  
                            user.setPassword(rs.getString("password"));  
                            return user;  
                        }  
                    }  
        );   
    }  

    public User queryForObject4(User user) {  
        return (User) jdbcTemplate.queryForObject("select * from tb_test1 where id = ?",   
                                                    new Object[]{user.getId()},  
                                                    User.class); //class是结果数据的java类型  实际上这里是做反射,将查询的结果和User进行对应复制  
    }  

    public User queryForObject5(User user) {  
        return (User) jdbcTemplate.queryForObject(  
                "select * from tb_test1 where id = ?",   
                new Object[]{user.getId()},  
                new RowMapper(){  

                    @Override  
                    public Object mapRow(ResultSet rs,int rowNum)throws SQLException {  
                        User user  = new User();  
                        user.setId(rs.getInt("id"));  
                        user.setUsername(rs.getString("username"));  
                        user.setPassword(rs.getString("password"));  
                        return user;  
                    }  

        }); //class是结果数据的java类型  
    }  

    @Override  
    public User queryForObject(User user) {  
        //方法有返回值  
        return (User) jdbcTemplate.queryForObject("select * from tb_test1 where id = ?",  
                new Object[]{user.getId()},  
                new int[]{java.sql.Types.INTEGER},   
                new RowMapper() {  

                    @Override  
                    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {  
                        User user  = new User();  
                        user.setId(rs.getInt("id"));  
                        user.setUsername(rs.getString("username"));  
                        user.setPassword(rs.getString("password"));  
                        return user;  
                    }  
                }  
        );  
    }  

    @SuppressWarnings("unchecked")  
    public List<User> queryForList1(User user) {  
        return (List<User>) jdbcTemplate.queryForList("select * from tb_test1 where username = ?",   
                            new Object[]{user.getUsername()},  
                            User.class);  
    }  

    @SuppressWarnings("unchecked")  
    public List<String> queryForList2(User user) {  
        return (List<String>) jdbcTemplate.queryForList("select username from tb_test1 where sex = ?",   
                            new Object[]{user.getSex()},  
                            String.class);  
    }  

    @SuppressWarnings("unchecked")  
    //最全的参数查询  
    public List<User> queryForList3(User user) {  
        return (List<User>) jdbcTemplate.queryForList("select * from tb_test1 where username = ?",  
                            new Object[]{user.getUsername()},  
                            new int[]{java.sql.Types.VARCHAR},  
                            User.class);  
    }  

    //通过RowCallbackHandler对Select语句得到的每行记录进行解析,并为其创建一个User数据对象。实现了手动的OR映射。  
    public User queryUserById4(String id){  
        final User user  = new User();  

        //该方法返回值为void  
        this.jdbcTemplate.query("select * from tb_test1 where id = ?",   
                new Object[] { id },   
                new RowCallbackHandler() {     

                    @Override    
                    public void processRow(ResultSet rs) throws SQLException {     
                        User user  = new User();  
            user.setId(rs.getInt("id"));  
            user.setUsername(rs.getString("username"));  
            user.setPassword(rs.getString("password"));    
                    }     
        });   

        return user;     
    }  

    @SuppressWarnings("unchecked")  
    @Override  
    public List<User> list(User user) {  
        return jdbcTemplate.query("select * from tb_test1 where username like '%?%'",   
                new Object[]{user.getUsername()},   
                new int[]{java.sql.Types.VARCHAR},   
                new RowMapper(){  

                    @Override  
                    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {  
                        User user  = new User();  
                        user.setId(rs.getInt("id"));  
                        user.setUsername(rs.getString("username"));  
                        user.setPassword(rs.getString("password"));  
                        return user;  
                    }  
        });  
    }  

    //批量操作    适合于增、删、改操作  
    public int[] batchUpdate(final List users) {  

        int[] updateCounts = jdbcTemplate.batchUpdate(  
                "update tb_test1 set username = ?, password = ? where id = ?",  
                new BatchPreparedStatementSetter() {  

                        @Override  
                        public void setValues(PreparedStatement ps, int i) throws SQLException {  
                            ps.setString(1, ((User)users.get(i)).getUsername());  
                            ps.setString(2, ((User)users.get(i)).getPassword());  
                            ps.setLong(3, ((User)users.get(i)).getId());  
                        }  

                        @Override  
                        public int getBatchSize() {  
                            return users.size();  
                        }  
                }   
        );  

        return updateCounts;  
    }  

 的的JdbcTemplate的回调方法

我们做过的很多项目中都会使用弹簧的JdbcTemplate类的进行结果集的查询操作,以前在使用的时候一直都是“拿来主义”,功能实现了就OK了,没有深究什么内容,特别是查询接口的回调内容方法,没有过多的研究过细节内容最近一次使用的JdbcTemplate的进行查询操作,发现了一些有规律的内容,所以就深入学习了一下和大家一起探讨一下:

对于spring的JdbcTemplate进行结果集查询操作,spring给我们开发的是一系列的查询方法,这些查询的方法中回调的接口主有三种:ResultSetExtractor,RowCallbackHandler,RowMapper,这个内容有图有真相:


 

但是这三种回调接口具体的用法和区别,我们一起来看一下:

场景设定,数据库中存在T_USER表,表中存在多条数据,需要将是表中数据映射到用户对象上

       1,org.springframework.jdbc.core。ResultSetExtractor类类

     ResultSetExtractor类类接口中定义的方法如下:

     

的的Java代码  收藏代码

  1. public interface ResultSetExtractor {  
  2.        Object extractData(ResultSet rs)抛出SQLException,   
  3.                                                 DataAccessException异常的;  
  4.     }  

 

        如果使用ResultSetExtractor类类接口作为回调方法,查询方式如下:

  

的的Java代码  收藏代码

  1. List<User> userList = (List<User>)jdbcDao.getJdbcTemplate().  
  2.                                    query("select * from T_USER", new ResultSetExtractor() {  
  3.             @Override  
  4.             public Object extractData(ResultSet rs) throws SQLException,   
  5.                                                             DataAccessException {  
  6.                  List<User> userList = new ArrayList<User>();  
  7.                  while (rs.next()) {  
  8.                     User user = new User();  
  9.                     user.setId(rs.getInt("N_ID"));  
  10.                     user.setName(rs.getString("C_NAME"));  
  11.                     userList.add(user);  
  12.                  }  
  13.                  return userList;  
  14.             }  
  15.     });  

        2、org.springframework.jdbc.core.RowCallbackHandler

              RowCallbackHandler接口中定义的方法如下:

Java代码  收藏代码

  1. public interface RowCallbackHandler {  
  2.       void processRow(ResultSet rs) throws SQLException;  
  3.   
  4. }  

 

        如果使用RowCallbackHandler接口作为回调方法,查询方式如下:

Java代码  收藏代码

  1. final List<User> userList = new ArrayList<User>();  
  2.   jdbcDao.getJdbcTemplate().query("select * from T_USER",   
  3.                                                      new RowCallbackHandler(){  
  4.        @Override  
  5.        public void processRow(ResultSet rs) throws SQLException {  
  6.            User user = new User();  
  7.            user.setId(rs.getInt("N_ID"));  
  8.            user.setName(rs.getString("C_NAME"));  
  9.            userList.add(user);  
  10.        }  
  11.    });  

         3、org.springframework.jdbc.core.RowMapper

               RowMapper接口中定义的方法如下:

               

Java代码  收藏代码

  1. public interface RowMapper {  
  2.         Object mapRow(ResultSet rs, int rowNum) throws SQLException;   
  3. }  

       如果使用RowMapper接口作为回调方法,查询方式如下:

     

Java代码  收藏代码

  1. List<User> userList = (List<User>)jdbcDao.getJdbcTemplate().  
  2. query("select * from T_USER", new RowMapper(){  
  3.             @Override  
  4.             public Object mapRow(ResultSet rs, int rowNumber)   
  5. throws SQLException {  
  6.                 User user = new User();  
  7.                 user.setId(rs.getInt("N_ID"));  
  8.                 user.setName(rs.getString("C_NAME"));  
  9.                 return user;  
  10.             }  
  11.       });  

          通过以上的例子我们可以看出,使用三种回调接口主要的区别是:

         1、使用三种Callback接口作为参数的query方法的返回值不同:

               以ResultSetExtractor作为方法参数的query方法返回Object型结果,要使用查询结果,我们需要对                 其进行强制转型;

               以RowMapper接口作为方法参数的query方法直接返回List型的结果;

               以RowCallbackHandler作为方法参数的query方法,返回值为void;

         2、使用ResultSetExtractor作为Callback接口处理查询结果,我们需要自己声明集合类,自己遍历                        ResultSet,自己根据每行数据组装Customer对象,自己将组装后的Customer对象添加到集合类                    中,方法最终只负责将组装完成的集合返回。

        对于这三个回调接口的区别,spring的官方文档给出的说明是这样描述的:

写道

ResultSetExtractor

This interface is mainly used within the JDBC framework itself. A RowMapper is usually a simpler choice for ResultSet processing, mapping one result object per row instead of one result object for the entire ResultSet.
Note: In contrast to a RowCallbackHandler, a ResultSetExtractor object is typically stateless and thus reusable, as long as it doesn't access stateful resources (such as output streams when streaming LOB contents) or keep result state within the object.

RowCallbackHandler

In contrast to a ResultSetExtractor, a RowCallbackHandler object is typically stateful: It keeps the result state within the object, to be available for later inspection. SeeRowCountCallbackHandler for a usage example.
Consider using a RowMapper instead if you need to map exactly one result object per row, assembling them into a List.

RowMapper

Typically used either for JdbcTemplate's query methods or for out parameters of stored procedures. RowMapper objects are typically stateless and thus reusable; they are an ideal choice for implementing row-mapping logic in a single place.
Alternatively, consider subclassing MappingSqlQuery from the jdbc.object package: Instead of working with separate JdbcTemplate and RowMapper objects, you can build executable query objects (containing row-mapping logic) in that style.

 

通过spring的文档描述我们可以知道:

1、RowMapper应该就是一个精简版的ResultSetExtractor,RowMapper能够直接处理一条结果集内容,而ResultSetExtractor需要我们自己去ResultSet中去取结果集的内容,但是ResultSetExtractor拥有更多的控制权,在使用上可以更灵活;

2、与RowCallbackHandler相比,ResultSetExtractor是无状态的,他不能够用来处理有状态的资源。

备注:在spring3中,这三个接口的内容也做出了修改,其中:ResultSetExtractor类类和的RowMapper的开始支持泛型,返回值的内容也是泛型中的对象,而RowCallbackHandler没有做出任何修改。

结果集处理回调:
RowMapper接口提供mapRow(ResultSet rs, int rowNum)方法将结果集的每一行转换为一个Map,当然可以转换为其他类。
public void testResultSet() { 
  jdbcTemplate.update("insert into TBL_SYS(name) values('name')"); 
 
  String listSql = "select * from TBL_SYS"; 
  List result = jdbcTemplate.query(listSql, new RowMapper<Map>() { 
      @Override 
      public Map mapRow(ResultSet rs, int rowNum) throws SQLException { 
          Map row = new HashMap(); 
          row.put(rs.getInt("id"), rs.getString("name")); 
          return row; 
  }});      
}   
RowCallbackHandler接口也提供方法processRow(ResultSet rs),能将结果集的行转换为需要的形式。
public void testResultSet() { 
  jdbcTemplate.update("insert into TBL_SYS(name) values('name')"); 
 
  String listSql = "select * from TBL_SYS"; 
  final List result = new ArrayList(); 
  jdbcTemplate.query(listSql, new RowCallbackHandler() { 
      @Override 
      public void processRow(ResultSet rs) throws SQLException { 
          Map row = new HashMap(); 
          row.put(rs.getInt("id"), rs.getString("name")); 
          result.add(row); 
  }}); 
}
ResultSetExtractor使用回调方法extractData(ResultSet rs)提供给用户整个结果集,让用户决定如何处理该结果集。
public void testResultSet() {
  jdbcTemplate.update("insert into TBL_SYS(name) values('name')"); 
 
  String listSql = "select * from TBL_SYS"; 
  List result = jdbcTemplate.query(listSql, new ResultSetExtractor<List>() { 
      @Override 
      public List extractData(ResultSet rs) throws SQLException, DataAccessException { 
          List result = new ArrayList(); 
          while(rs.next()) { 
              Map row = new HashMap(); 
              row.put(rs.getInt("id"), rs.getString("name")); 
              result.add(row); 
           } 
           return result; 
  }}); 
}

spring xml整合jdbcTempalte

配置方法
spring注入DataSource
public class JdbcCorporateEventDao implements CorporateEventDao {

    private JdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
}

配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="corporateEventDao" class="com.example.JdbcCorporateEventDao">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- the DataSource (parameterized for configuration via a PropertyPlaceHolderConfigurer) -->
    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

</beans>

Spring注入JdbcTemplate
public class UserServiceImpl implements UserService {  

    private JdbcTemplate jdbcTemplate;  

    public JdbcTemplate getJdbcTemplate() {  
        return jdbcTemplate;  
    }  

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
        this.jdbcTemplate = jdbcTemplate;  
    }  

}
//Spring配置文件

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
        <property name = "dataSource" ref="dataSource">  
</bean>  
<bean id="userService" class="com.hxzy.account.jdbcTemplate.UserServiceImpl">  
     <property name="jdbcTemplate" ref="jdbcTemplate"/>  
</bean>  

org.springframework.jdbc.core.support.JdbcDaoSupport
//JdbcDaoSupport 类需要设置一个DataSource值
public class UserDaoImpl extends JdbcDaoSupport implements UserDao {  

    DataSource  dataSource = null;
    //设置JdbcDaoSupport 的dataSource
    this.setDataSource(dataSource);

    @Override  
    public void save(User user) {  
        String sql = null;  
        this.getJdbcTemplate().update(sql);  
    }  
} 
//Spring配置文件
<bean id="userDao" class="com.hxzy.account.jdbcTemplate.UserDaoImpl">  
           <property name="dataSource" ref="dataSource"/>  
</bean> 

猜你喜欢

转载自blog.csdn.net/qq_27886997/article/details/84969425