springboot自定义jdbc操作库+基于注解切点AOP
发布时间:2018-11-08
技术:springboot+aop
概述
springBoot集成了自定义的jdbc操作类及AOP,因为spring自带的JdbcTemplate在实际项目中并不是那么好用,比如在分页和将数据转为对象时,所以才写了这个工具。另外在使用AOP切点时我们一般使用的execution 这个用法颗粒度有点大,不能很自由的选择指定的方法,但基于自定义注解的切点就很好的解决了这个问题。
详细
1,项目搭建
新建maven项目这里不多说,这里主要看pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--springboot jdbc模块--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--mysql连接数据库jar--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.37</version> </dependency> <!--springboot aop模块--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- springJdbcTemplate操作封装类 超级好用 引入前执行如下命令,在项目redare-devframework-common-2.0.jar 的当前路径下 mvn install:install-file -Dfile=redare-devframework-common-2.0.jar -DgroupId=com.redare.devframework.common -DartifactId=lijin -Dversion=2.0 -Dpackaging=jar start--> <dependency> <groupId>com.redare.devframework.common</groupId> <artifactId>lijin</artifactId> <version>2.0</version> </dependency> <!-- springJdbcTemplate操作封装类 超级好用 end--> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
项目结构如下图:
2 功能讲解:
1,配置数据库连接参数:在resources/application.properties中
//数据库连接地址,端口号,连接名,设置编码格式 jdbc.url=jdbc:mysql://localhost:3306/boot //用户名 jdbc.username=root //密码 jdbc.password=123456 //数据库驱动 jdbc.driverClassName=com.mysql.jdbc.Driver
2,读取配置文件,由于springboot会自动加载resources/application.properties文件,所以直接使用@value注解即可获取,记得写get set 方法。
@Component public class MyConfig { @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Value("${jdbc.driverClassName}") private String driverClassName;
3,配置数据库操作工具类
//这个类起着配置文件的作用 需要用@Configuration 注解 @Configuration public class MySpringJdbc { @Autowired MyConfig myConfig; //配置数据库数据源 @Bean public DataSource masterDataSource() { DataSource dataSource = new DriverManagerDataSource(myConfig.getUrl(),myConfig.getUsername(),myConfig.getPassword()); return dataSource; } @Bean public SpringJdbcHelper jdbcHelper(){ //根据数据库类型选择myslq还是Orcle SpringJdbcHelper jdbcHelper=new MySqlJdbcHelper();// new OracleJdbcHelper() jdbcHelper.setDataSource(masterDataSource()); return jdbcHelper; } }
4,自定义注解,这样可以加上我们需要的方法上,将该方法作为切点
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyLogService { String description() default ""; }
5,aop切面处理类
package com.example.demo.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.Date; /** * Created by Administrator on 2018/11/7. */ @Aspect @Component public class MyAspect { //这里定义了一个切点,凡是加了这个注解的方法都会被进行增加(进行额外的处理) //这个注解我加在控制层的方法上,所以对方法前后进行拦截,获取的都是请求参数 @Pointcut("@annotation(com.example.demo.aop.MyLogService)") public void lockAspect() { } /** * 请求开始前处理方法 * @param result Object * @author zhoukai */ @Before(value = "lockAspect()") public void doBefore(JoinPoint joinPoint) { //通过RequestContextHolder 获取当前请求的request ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); System.out.println("\n"); System.out.println("URL: " + request.getRequestURL().toString());//获取当前请求url System.out.println("request method: " + request.getMethod());//获取请求的方法 System.out.println("remote address: " + request.getRemoteAddr());//获取请求地址 System.out.println("remote port: " + request.getRemotePort());//获取请求的端口 Signature signature = joinPoint.getSignature(); System.out.println("CLASS_METHOD: " + signature.getDeclaringTypeName() + "." + signature.getName()); String params = Arrays.toString(joinPoint.getArgs());//获取方法参数 } /** * 请求拦截后处理方法 * @param result Object * returning 表示被拦截方法的返回值 * 这里的returning 表示返回值,如果方法结束后 我们想获得返回值进行额外操作 */ @AfterReturning(value = "lockAspect()",returning = "result") public void doAfterReturning(Object result) { System.out.println("end============"); } }
6,将注解应用到方法上
@RestController public class TestController { @MyLogService @GetMapping("/test") public String test(){ return "hello world"; } }
7,jdbc辅助类操作示例,由于笔者也不是很喜欢mybatis,还是喜欢直接操作sql。所以用这个还是很方便的。主要包括不带参数插入,带占位符参数插入(含批量操作),查询单条数据,查询多条数据,查询多条数据带占位符参数,分页查询。
package com.example.demo; import com.example.demo.domain.Post; import com.redare.devframework.common.pojo.Page; import com.redare.devframework.common.spring.db.SpringJdbcHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.ArrayList; import java.util.List; /* 实现DemoApplication 接口,以便在启动后执行我们的方法 */ @SpringBootApplication public class DemoApplication implements CommandLineRunner { /* 自动注入jdbcHelper */ @Autowired SpringJdbcHelper jdbcHelper; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } //方法演示 分别展示增删改和查 毕竟业务都是围绕这几个方面展开的 @Override public void run(String... strings) throws Exception { //不带参数insert insertDemoNoParam(jdbcHelper); //带参数insert insertDemoWithParam(jdbcHelper); //查询单条数据 queryOneObject(jdbcHelper); //查询多条数据 queryListObject(jdbcHelper); //查询多条数据带占位符参数 queryListObjectWithParam(jdbcHelper); //分页查询 queryPageObject(jdbcHelper); } private void queryListObjectWithParam(SpringJdbcHelper jdbcHelper) { int id=3; String sql="select id,uid,user_id as userId,created_at as createAt from posts where id < ?"; List<Post> post= jdbcHelper.queryForListBean(sql, Post.class,new Object[]{id}); System.out.println(post.size()); } //和queryForListBean 非常相似,只是多了两个分页参数 private void queryPageObject(SpringJdbcHelper jdbcHelper) { int curpage=1; int pageSize=5; String sql="select id,uid,user_id as userId,created_at as createAt from posts where id <3"; Page<Post> post= jdbcHelper.queryForPageBean(sql,Post.class,curpage,pageSize); System.out.println(post.getResult().size()); } private void queryListObject(SpringJdbcHelper jdbcHelper) { String sql="select id,uid,user_id as userId,created_at as createAt from posts where id <3"; List<Post> post= jdbcHelper.queryForListBean(sql, Post.class); System.out.println(post.size()); } //注意这个的查询结果必须是一条 否则报错 多条结果请用queryForListBean private void queryOneObject(SpringJdbcHelper jdbcHelper) { String sql="select id,uid,user_id as userId,created_at as createAt from posts where id =1"; Post post= jdbcHelper.queryForBean(sql,Post.class); System.out.println(post); } public void insertDemoNoParam(SpringJdbcHelper jdbcHelper){ /* 不带参数 以下两种方式都可以 */ String sql="insert into employ(cus_firstname,cus_surname)values('tom','jack')"; String sql2="insert into employ(cus_firstname,cus_surname)values('tom','jack')"; jdbcHelper.insert(sql); jdbcHelper.update(sql2); } public void insertDemoWithParam(SpringJdbcHelper jdbcHelper){ /* 带参数 通过占位符传递 执行单条sql */ String [] arr={"jack","tome"}; String sql="insert into employ(cus_firstname,cus_surname)values(?,?)"; //jdbcHelper.insert(sql, arr); /* 带参数 通过占位符传递 批量执行 */ //构造参数list List<Object[]> list =new ArrayList<>(); list.add(new String[]{"aa","bb"}); list.add(new String[]{"aa","bb"}); jdbcHelper.batchUpdate(sql,list); } }