SpringBoot整合持久层技术之搭建SpringJDBCTemplate项目实战
现在有了MyBatis之后很少人使用JDBCTemplate来整合项目了,要么就是JPA技术,要么就是Mybatis来操作数据库,今天我搭建一个springboot的template项目,看看其和JPA、Mybatis有什么不同的地方,方便大家一起学习。
什么是JDBCTemplate
JdbcTemplate是Spring提供的一套JDBC模板框架,它主要就是利用AOP技术来解决直接使用JDBC时大量的重复代码的问题,JDBCTemplate虽然没有Mybais那么灵活,但是在处理JDBC上有了很大的一个提升,因为SpringBoot对JDBCTemplate的使用提供了自动化的配置类JdbcTemplateAutoConfiguration。
创建数据库和表
这里是我创建的数据库和表,接下来就是创建SpringBoot项目,具体的创建方法看我上一篇文章:解读SpringBoot整合持久层技术之搭建并整合Spring Data JPA项目实战
pom.xml
引入的pom.xml文件如下所示:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
application.properties
然后就是数据库的配置,这里还是在application.properties中进行配置,具体的代码如下所示:
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url=jdbc:mysql://localhost:3306/book spring.datasource.username=root spring.datasource.password=root
Book实体类
创建Book实体
public class Book { private Integer id; private String name; private String author; private Float price; private String description; //get与set自己加上哈 }
Dao层
数据库访问层
@Repository public class BookMapper { @Autowired JdbcTemplate jdbcTemplate; public int addBook(Book book){ return jdbcTemplate.update("INSERT INTO bookinfo (name,author,price,description) values (?,?,?,?)",book.getName(),book.getAuthor(),book.getPrice(),book.getDescription()); } public int deleteBookById(Integer id){ return jdbcTemplate.update("DELETE FROM bookinfo WHERE id=?",id); } public int updateBookById(Book book){ return jdbcTemplate.update("update bookinfo set name=?,author=?,price=?,description=? where id=?",book.getName(),book.getAuthor(),book.getPrice(),book.getDescription(),book.getId()); } public Book getBookById(Integer id){ return jdbcTemplate.queryForObject("select * from bookinfo where id = ?",new BeanPropertyRowMapper<>(Book.class),id); } public List<Book> getAllBooks(){ return jdbcTemplate.query("select * from book",new BeanPropertyRowMapper<>(Book.class)); } }
为什么 @Repository 只能标注在 DAO 类上呢?
这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。 Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。
**注意:**增删改三种操作类型主要是采用update、batchUpdate方法来完成,query和queryObject是用来进行查询,execute方法可以用来执行任意的SQL,同时call方法可以用来调用存储过程。
特别提醒:当执行查询的操作时需要我们将查询出来的列和属性进行一个对应的操作,就用到了RowMapper,如何属性名和列名都是相同的,那么就可以直接使用BeanPropertyRoeMapper<>(Book.class)来进行实体的数据返回,如果属性名与数据库列名不同,就需要我们实现RowMapper的接口,将列名与实体名逐一对应起来。
BookService层
@Service public class BookService { @Resource BookMapper bookMapper; public int addBook(Book book){ return bookMapper.addBook(book); } public int updateBook(Book book){ return bookMapper.updateBookById(book); } public Book getBookById(int id){ return bookMapper.getBookById(id); } public int deleteBookById(int id){ return bookMapper.deleteBookById(id); } public List<Book> getAllBooks(){ return bookMapper.getAllBooks(); } }
BookController控制层
我咋感觉又回到了写ServletMVC那会了呢。。。
/** * @program: bokecms * @description: 这是一个bookController * @author: zjc **/ @RestController public class BookController { @Autowired BookService bookService; @GetMapping("/bookOps") public void bookOps() { Book book = new Book(); book.setName("java开发程序设计"); book.setAuthor("no"); book.setPrice(80F); book.setDescription("这书有点贵"); int i = bookService.addBook(book); System.out.println("addbook---" + i); Book book2 = new Book(); book2.setName("其他书籍"); book2.setAuthor("张闲闲"); book2.setId(29); int updateBook = bookService.updateBook(book2); System.out.println("updateBook-------" + updateBook); Book selectById = bookService.getBookById(27); System.out.println("selectById-------" + selectById); int deleteBook = bookService.deleteBookById(30); System.out.println("deleteById-----" + deleteBook); List<Book> getAllBooks = bookService.getAllBooks(); System.out.println("getAllBooks----" + getAllBooks); } }
这里我们进行一个增加,增加之后并修改,查看对应的id为27的数据,删除对应id为30的数据。启动项目,浏览器输入:http://localhost:8080/bookOps 查看后台打印输出:
addbook---1 updateBook-------1 selectById-------Book{id=27, name='狂人日记', author='鲁迅', price=23.0, description='null'} deleteById-----1 2020-06-19 22:15:56.351 ERROR 2852 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [select * from book]; nested exception is java.sql.SQLSyntaxErrorException: Table 'book.book' doesn't exist] with root cause java.sql.SQLSyntaxErrorException: Table 'book.book' doesn't exist
太不仔细了,数据库写错了,应该是bookinfo,重新来一遍.
addbook---1 updateBook-------1 selectById-------Book{id=27, name='狂人日记', author='鲁迅', price=23.0, description='null'} deleteById-----1 getAllBooks----[Book{id=1, name='呐喊', author='鲁迅', price=23.0, description='null'}, Book{id=2, name='朝花夕拾', author='鲁迅1', price=24.0, description='null'}, Book{id=3, name='简单生活学', author='鲁迅2', price=30.0, description='null'}, Book{id=4, name='XML基础与案例教程', author='鲁迅3', price=31.0, description='null'}, Book{id=5, name='物联网之源', author='鲁迅4', price=44.0, description='null'}, Book{id=27, name='狂人日记', author='鲁迅', price=23.0, description='null'}, Book{id=29, name='其他书籍', author='张闲闲', price=null, description='null'}, Book{id=32, name='java开发程序设计', author='张闲闲', price=80.0, description='这书有点贵'}]
ok 运行成功!!!希望小伙伴们能够支持一下,相互学习。
项目源码地址我一会附加上面,刚传上去,需要审核。如下: