Spring's JdbcTemplate Tutorial

Spring in the operation of the database jdbc did a basic package, so developers only need to focus on SQL statements and queries in the database when the operation
result processor to complete the function (of course, only JdbcTemplate, still can not get rid of the persistence layer implementation class written).
In the spring of IoC with the feature, you can register the DataSource into JdbcTemplate. While taking advantage of spring-based
aop transaction to complete simple database CRUD operations.
JdbcTemplate defined named org.springframework.jdbc.core.JdbcTemplate. To
JdbcTemlate need to import the spring-jdbc and spring-tx two coordinates.

Method Description:

execute method:
can be used to execute any SQL statement, typically used to execute DDL statements;
Update method and batchUpdate methods:
Update methods for performing add, modify and delete statements; batchUpdate methods for performing batch-related language
sentence;
Query methods and queryForXXX method:
to perform a query related statements;
Call the method:
for executing stored procedures, functions related statements.


Use Cases

Project structure:


Item code

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>

Entity classes:

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
}

Correspond to the account table and table userinfo


jdbc.properties

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

jbbc configuration class:

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();
    }


}

Main configuration class:

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

Test categories:

/**
    *注释部分为不同写法
 * 测试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);
    }
}

Named parameters

In the classical usage of JDBC, SQL parameter is a placeholder? Representation and restricted locations. Parameters to locate the problem is that once the order parameter changes, you must change the parameter binding. In the Spring JDBC framework, tie another option is to use a given SQL parameter named parameter (namedparameter). so what is named parameters? Named parameters:.. SQL by name (preceded by a colon) instead of the location specified by the named parameters easier to maintain, but also enhance the readability of named parameters with placeholders substituted named parameters at run time by the frame class only obtained NamedParameterJdbcTemplate stand by. NamedParameterJdbcTemplate can use all jdbcTemplate method.

Add the assembly jdbcConfig

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

Test categories:

@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);
    }
}

Guess you like

Origin www.cnblogs.com/heliusKing/p/11877314.html