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>

项目结构如下图:

QQ截图20181108101032.png

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

   }

}

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

原文地址:https://www.cnblogs.com/demodashi/p/10492790.html