spring boot(学习笔记第七课)
- 配置AOP,数据库操作(jdbcTemplate)
学习内容:
- 配置AOP
- 数据库操作(jdbcTemplate)
1. 配置AOP
如果想要在一些既存系统上对系统进行分析,监视,但是又不想改修原有的代码,可以通过AOP (Aspect Of Program)
来实现。
- 在
pom.xml
中引入spring-boot-starter-aop
。<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
- 定义
service
类UserService
,假设这就是想要监视的legency class
。@Service public class UserService { public String getUserById(Integer id){ System.out.println("getUserById"); return "user"; } public void deleteUserById(Integer id){ System.out.println("deleteUserById"); } }
- 定义
AOP
类,对UserService
类进行监视。@Before(value = "userServicePC()")
在函数执行前执行@after(value = "userServicePC()")
在函数执行后执行@AfterReturning(value = "userServicePC()", returning = "result")
在函数返回直前执行@AfterThrowing(value = "userServicePC()", throwing = "e")
在函数抛出异常直前执行。@Around("userServicePC()")
在函数执行前后执行,能够包围函数执行,函数执行就是Object ret = pjp.proceed();
。
@Aspect @Component public class LogAspect { @Pointcut("execution(* com.example.demo.services.*.*(..))") public void userServicePC() { } @Before(value = "userServicePC()") public void before(JoinPoint jp) { String name = jp.getSignature().getName(); System.out.println(name + " is beginning"); } @After(value = "userServicePC()") public void after(JoinPoint jp) { String name = jp.getSignature().getName(); System.out.println(name + " is finishing"); } @AfterReturning(value = "userServicePC()", returning = "result") public void afterReturning(JoinPoint jp, Object result) { String name = jp.getSignature().getName(); System.out.println(name + " is returning " + result); } @AfterThrowing(value = "userServicePC()", throwing = "e") public void afterReturning(JoinPoint jp, Exception e) { String name = jp.getSignature().getName(); System.out.println(name + " is throwing" + e); } @Around("userServicePC()") public Object around(ProceedingJoinPoint pjp) throws Throwable { String name = pjp.getSignature().getName(); AroundClosure ac = new AroundClosure() { @Override public Object run(Object[] args) throws Throwable { return "hello,around"; } }; System.out.println(name + " is arounding before..."); Object ret = pjp.proceed(); System.out.println(name + " is arounding after..."); return ret; } }
注意,@AfterReturning
注解中的returning="result"和注解对应的方法的参数名必须一致。
- 接下来模仿
UserService
在controller
中被执行。@Autowired private UserService us; @GetMapping("/hello") @ResponseBody public String hello() { String name = us.getUserById(1);
- 测试执行的效果。
2. 数据库操作(jdbcTemplate)
可以使用jdbcTemplate
进行简单的数据库操作。在这里,使用postgresql作为DB服务器。
数据库名称: springboot
数据库用户: finlay
数据库密码: 123456
- 数据库服务器安装(postgreSQL 16.3):
>>>postgresql安装 - 数据库客户端安装(A5M2):
>>>DB client安装
- 导入依赖进入pom.xml
spring boot
的jdbc
依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
- 使用
alibaba
的druid
连接池进行jdbc进行连接,导入druid
依赖。<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency>
- 导入
postgreSQL
的驱动依赖。<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency>
- 建立
book
表。create table book ( id serial not null , name character varying(128) default NULL , author character varying(128) default NULL , primary key (id) );
- 调用层次。
- 配置数据库连接。
注意,首先学习单一数据库连接,之后练习多数据库#database spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/springboot spring.datasource.username=finlay spring.datasource.password=123456
- java的代码实现。
- 实现
repository
代码。
查看@Repository public class BookDao { @Autowired JdbcTemplate jdbcTemplate; public int addBook(Book book){ jdbcTemplate.update("insert into " + "book(name,author) values(?,?)", book.getName(), book.getAuthor()); // get max id int maxId = jdbcTemplate.queryForObject( "select max(id) from book",Integer.class); return maxId; } public int updateBook(Book book){ return jdbcTemplate.update("update book set" + " name=?," + " author=?" + " where id=?", book.getName(), book.getAuthor(), book.getId()); } public int deleteBookById(Integer id){ return jdbcTemplate.update("delete from " + "book where id=?", id); } public Book getBookById(Integer id){ return jdbcTemplate.queryForObject("select * from" + " book where id=?", new BeanPropertyRowMapper<>(Book.class),id); } public List<Book> getAllBooks(){ return jdbcTemplate.query("select * from book", new BeanPropertyRowMapper<>(Book.class)); } }
JdbcTemplateAutoConfiguration
–>JdbcTemplateConfiguration
。可见,如果没有spring boot
应用程序没有自定义的JdbcTemplate
,那么会通过@Configuration
注入一个JdbcTemplate
的bean
。这里BookDao
使用spring boot
注入的bean进行数据库的访问。
- 实现
service
代码。通过Autowired
出来repository
的BookDao
,进行数据库的访问,实现起来非常简单。@Service public class BookService { @Autowired BookDao bookDao; public int addBook(Book book){ return bookDao.addBook(book); } public int updateBook(Book book){ return bookDao.updateBook(book); } public int deleteBookById(Integer id){ return bookDao.deleteBookById(id); } public Book getBookById(Integer id){ return bookDao.getBookById(id); } public List<Book> getAllBooks(){ return bookDao.getAllBooks(); } }
- 实现
controller
代码。通过Autowired
出service
的BookService
,实现画面的逻辑,完全不意识DB操作。@GetMapping("/bookOps") @ResponseBody public List<Book> bookOps() { Book book = new Book(); book.setAuthor("finlay"); book.setName("spring boot"); int maxId = bookService.addBook(book); System.out.println("addBook()>>>" + maxId); book = new Book(); book.setId(maxId); book.setName("springboot2"); book.setAuthor("finlay2"); int ret = bookService.updateBook(book); System.out.println("updateBook()>>>" + " ret"); book = bookService.getBookById(maxId); System.out.println("getBookById>>>" + book); return bookService.getAllBooks(); }