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