Spring的JdbcTemplate使用教程

Spring对数据库的操作在jdbc上面做了基本的封装,让开发者在操作数据库时只需关注SQL语句和查询
结果处理器,即可完成功能(当然,只使用JdbcTemplate,还不能摆脱持久层实现类的编写)。
在配合spring的IoC功能,可以把DataSource注册到JdbcTemplate之中。同时利用spring基于
aop的事务即可完成简单的数据库CRUD操作。
JdbcTemplate的限定命名为org.springframework.jdbc.core.JdbcTemplate。要使用
JdbcTemlate需要导入spring-jdbc和spring-tx两个坐标。

方法说明:

execute方法:
可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:
update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语
句;
query方法及queryForXXX方法:
用于执行查询相关语句;
call方法:
用于执行存储过程、函数相关语句。


使用案例

项目结构:


项目代码

POM.XML

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>

    </dependencies>

实体类:

public class Account implements Serializable {

    private Integer id;
    private String name;
    private Double money;
    //省略getter setter
}
public class Userinfo implements Serializable {

    private Integer id;
    private byte[] images; // 对应mysql数据库longBlob类型
    private String description;  // 对应表的longText类型
    // 省略getter setter
}

相对应account表和userinfo表


jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_ioc
jdbc.username=root
jdbc.password=admin

jbbc配置类:

public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    /**
     * 创建数据源并存入Ioc容器
     * @return
     */
    @Bean
    public DataSource createDataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    /**
     * 创建JdbcTemplate对象
     * @param dataSource
     * @return
     */
    @Bean
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }
    
    // 操作clob和blob
    @Bean
    public LobHandler createLobHandler(){
        return new DefaultLobHandler();
    }


}

主配置类:

@Configuration
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbc.properties")
public class SpringConfiguration {
}

测试类:

/**
    *注释部分为不同写法
 * 测试JdbcTemplate的使用
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringJdbcTemplateTest {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    public void testSave(){
        jdbcTemplate.update("insert into account(money,name)values(?,?)",6789d,"userTest");
    }

    @Test
    public void testUpdate(){
        jdbcTemplate.update("update account set name=?,money=? where id=?","testZZZ",23456d,3);
    }

    @Test
    public void testDelete(){
        jdbcTemplate.update("delete from account where id = ? ",4);
    }

    @Test
    public void testFindOne(){
//        List<Account> accounts =  jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
//        System.out.println(accounts.isEmpty()?"empty":accounts.get(0));

//        Account account = jdbcTemplate.queryForObject("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
//        System.out.println(account);

        Account account = jdbcTemplate.query("select * from account where id = ?", new ResultSetExtractor<Account>() {
            @Override
            public Account extractData(ResultSet rs) throws SQLException, DataAccessException {
                Account account1 = null;
                //1.判断结果集能往下走
                if(rs.next()){
                    account1 = new Account();
                    account1.setId(rs.getInt("id"));
                    account1.setName(rs.getString("name"));
                    account1.setMoney(rs.getDouble("money"));
                }
                return account1;
        }
        }, 1);
        System.out.println(account);
    }

    @Test
    public void testFindAll(){
        List<Account> accountList = jdbcTemplate.query("select * from account where money > ?",new BeanPropertyRowMapper<Account>(Account.class),999d);
        for(Account account : accountList){
            System.out.println(account);
        }
    }

    @Test
    public void testFindCount(){
       Integer count =  jdbcTemplate.queryForObject("select count(*) from account where money > ?",Integer.class,999d);
        System.out.println(count);
    }


    @Test
    public void testQueryForList(){
        /**
         * 得到某个特定类型的集合。类型是方法的第二个参数指定的
         */
        List<Double> list = jdbcTemplate.queryForList("select money from account where money > ?",Double.class,999d);
        for(Double money : list){
            System.out.println(money);
        }

//        List<Map<String,Object>> list = jdbcTemplate.queryForList("select * from account where money > ? ",999d);
//        for(Map<String,Object> map : list){
//            for(Map.Entry<String,Object> me : map.entrySet())
//            System.out.println(me.getKey()+","+me.getValue());
//        }
    }

    @Test
    public void testQueryForMap(){
        Map<String,Object> map = jdbcTemplate.queryForMap("select * from account where id = ?",1);
        for(Map.Entry<String,Object> me : map.entrySet()) {
            System.out.println(me.getKey()+","+me.getValue());
        }
    }


    @Test
    public void testQueryForRowSet(){
        SqlRowSet rowSet = jdbcTemplate.queryForRowSet("select * from account where money > ?",999d);
        System.out.println(rowSet);
        while(rowSet.next()){
            String name = rowSet.getString("name");
            System.out.println(name);
        }
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringLobTest {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private LobHandler lobHandler;

    @Test
    public void testWrite(){
        try {
            //准备images的字节数组
            Resource resource = new FileSystemResource("E:\\6.jpg");
            byte[] images = FileCopyUtils.copyToByteArray(resource.getFile());
            //准备description
            String description = "BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。\n" +
                    "在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。\n" +
                    "BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,\n" +
                    "由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。\n" +
                    "根据Eric Raymond的说法,处理BLOB的主要思想就是让文件处理器(如数据库管理器)不去理会文件是什么,\n" +
                    "而是关心如何去处理它。但也有专家强调,这种处理大数据对象的方法是把双刃剑,\n" +
                    "它有可能引发一些问题,如存储的二进制文件过大,会使数据库的性能下降。\n" +
                    "在数据库中存放体积较大的多媒体对象就是应用程序处理BLOB的典型例子。";
            //1.创建Userinfo
            Userinfo userinfo = new Userinfo();
            userinfo.setImages(images);
            userinfo.setDescription(description);

            jdbcTemplate.execute("insert into userinfo(images,description)values(?,?)", new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
                @Override
                protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException {
                    lobCreator.setBlobAsBytes(ps, 1, userinfo.getImages());
                    lobCreator.setClobAsString(ps, 2, userinfo.getDescription());
                }
            });
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Test
    public void testRead(){
//        Userinfo userinfo = jdbcTemplate.queryForObject("select * from userinfo where id = ?",new BeanPropertyRowMapper<Userinfo>(Userinfo.class),1);
        Userinfo userinfo = jdbcTemplate.query("select * from userinfo where id = ?", new ResultSetExtractor<Userinfo>() {
            @Override
            public Userinfo extractData(ResultSet rs) throws SQLException, DataAccessException {
                Userinfo userinfo1 = null;
                if(rs.next()){
                    userinfo1 = new Userinfo();
                    userinfo1.setId(rs.getInt("id"));
                    userinfo1.setImages(lobHandler.getBlobAsBytes(rs,"images"));
                    userinfo1.setDescription(lobHandler.getClobAsString(rs,"description"));
                }
                return userinfo1;
            }
        }, 1);
        System.out.println(userinfo);
    }
}

具名参数使用

在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制. 定位参数的问题在于,一旦参数的顺序发生变化, 就必须改变参数绑定.在 Spring JDBC 框架中, 绑定 SQL 参数的另一种选择是使用具名参数(namedparameter).那么什么是具名参数?具名参数: SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代具名参数只NamedParameterJdbcTemplate 中得到支持。NamedParameterJdbcTemplate可以使用全部jdbcTemplate方法。

在jdbcConfig中加入组件

    @Bean
    public NamedParameterJdbcTemplate createNamedParameterJdbcTemplate(JdbcTemplate jdbcTemplate){
        return new NamedParameterJdbcTemplate(jdbcTemplate);
    }

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringNamedParameterJdbcTemplateTest {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Test
    public void testFind(){
        Map<String,Object> map = new HashMap<>();
        map.put("id",1);
        Account account = jdbcTemplate.queryForObject("select * from account where id = :id",map,new BeanPropertyRowMapper<Account>(Account.class));
        System.out.println(account);
    }


    @Test
    public void testSave(){
        Account account = new Account();
        account.setName("NamedParameterJdbcTemplate");
        account.setMoney(12345d);
        BeanMap beanMap = BeanMap.create(account);
        jdbcTemplate.update("insert into account(name,money)values(:name,:money)",beanMap);
    }
}

猜你喜欢

转载自www.cnblogs.com/heliusKing/p/11877314.html
今日推荐