*\FirstSBDemo\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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.namejr</groupId> <artifactId>FirstSBDemo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 注意,这里需要排除web自带的logging依赖--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10.14</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.11</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency> <!-- 重写数据库的DruidDataSource,和mybatis版本要关联 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.17</version> </dependency> <!-- 补充排除的log4j --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j</artifactId> <version>1.3.8.RELEASE</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <!-- 注册webapp目录为资源目录 --> <directory>src/main/webapp</directory> <targetPath>META-INF/resources</targetPath> <includes> <include>**/**</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <includeSystemScope>true</includeSystemScope> <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments> </configuration> </plugin> <plugin> <!-- 配置jar包打包工具 --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <webResources> <resource> <directory>${project.basedir}/libs</directory> <targetPath>WEB-INF/lib</targetPath> <includes> <include>**/*.jar</include> </includes> </resource> </webResources> </configuration> </plugin> </plugins> </build> </project>
*\FirstSBDemo\src\main\java\com\namejr\StartApplication.java
package com.namejr; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @SpringBootApplication @EnableWebMvc @MapperScan({"com.namejr.dao"}) @ServletComponentScan({"com.namejr.base","com.namejr.controller","com.namejr.service"}) public class StartApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(StartApplication.class, args); } protected SpringApplicationBuilder configuer(SpringApplicationBuilder builder) { return super.configure(builder); } }
*\FirstSBDemo\src\main\java\com\namejr\dao\PublicDao.java
package com.namejr.dao; import org.springframework.stereotype.Repository; import java.util.HashMap; import java.util.List; /* * 公共Dao * */ @Repository public interface PublicDao { // 获取obs信息 List<HashMap<String,String>> getResGuids(); }
*\FirstSBDemo\src\main\java\com\namejr\base\DatabaseConfig.java
package com.namejr.base; import org.apache.ibatis.io.VFS; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import javax.sql.DataSource; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /* * 数据库配置连接处理 * */ @Configuration public class DatabaseConfig { @Value("${mybatis.type-aliases-package}") private String typeAliasesPackage; @Value("${mybatis.mapper-locations}") private String mapperLocations; @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); sessionFactory.setTypeAliasesPackage(typeAliasesPackage); if(mapperLocations.contains(",")){ String[] tempMapperLocations=mapperLocations.split(",",-1); List<Resource> tempResourceList=new ArrayList<>(); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); for(int i= 0;i<tempMapperLocations.length;i++){ tempResourceList.addAll(Arrays.asList(resolver.getResources(tempMapperLocations[i]))); } Resource[] tempResourceInfos=new Resource[tempResourceList.size()]; for(int i=0;i<tempResourceList.size();i++){ tempResourceInfos[i]=tempResourceList.get(i); } sessionFactory.setMapperLocations(tempResourceInfos); }else { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); sessionFactory.setMapperLocations(resolver.getResources(mapperLocations)); } /* // configLocatoin=》mybatis.config-location: classpath:mybatis-config.xml sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); */ SqlSessionFactory result = sessionFactory.getObject(); // 注册自定义拦截器 result.getConfiguration().addInterceptor(new SqlSessionFactoryInterceptor()); return result; } }
*\FirstSBDemo\src\main\java\com\namejr\base\SqlSessionFactoryInterceptor.java
package com.namejr.base; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import java.sql.Statement; import java.util.Properties; /** MyBatis的拦截器 * 笔记参照地址:MyBatis Interceptor - Milton - 博客园 (cnblogs.com) * @Intercepts 描述:标志该类是一个拦截器 * 注解: 这个地方配置需要拦截的对象方法, 每个方法对应一个Signature, 这个Signature由对象类型, 方法名和参数组成, 方法名和参数可以直接参考这个对象的接口. * @Signature 描述:指明该拦截器需要拦截哪一个接口的哪一个方法 * type:四种类型接口中的某一个接口,四种接口类型分别(拦截顺序也按这个)为Executor、StatementHandler、ParameterHandler和ResultSetHandler,如Executor.class; * method:对应接口中的某一个方法名,比如Executor的query方法; * args:对应接口中的某一个方法的参数,比如Executor中query方法因为重载原因,有多个,args就是指明参数类型,从而确定是具体哪一个方法; * Object plugin(Object target)接口: 用于封装目标对象, 可以返回目标对象本身也可以返回一个它的代理, 这将决定是否会进行拦截 * void setProperties(Properties properties)接口: 用于配置本插件的相关属性, 值可以通过Mybatis配置文件传入 * Object intercept(Invocation invocation) throws Throwable接口: 执行拦截的方法, 其中 invocation.getTarget() 可以看到实际被代理的对象, 根据对象类型不同, 可以读取这个对象方法的参数并进行需要的操作. * */ @Intercepts({ @Signature(type = StatementHandler.class, method = "batch", args = { Statement.class}), @Signature(type = StatementHandler.class, method = "update", args = { Statement.class}), @Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class}), @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), @Signature(type = Executor.class, method = "update", args = {MappedStatement.class,Object.class})}) public class SqlSessionFactoryInterceptor implements Interceptor { /** * 用于封装目标对象, 可以返回目标对象本身也可以返回一个它的代理, 这将决定是否会进行拦截 * 注:MyBatis拦截器用到责任链模式+动态代理+反射机制;所有可能被拦截的处理类都会生成一个代理类,如果有N个拦截器,就会有N个代理,层层生成动态代理是比较耗性能的。而且虽然能指定插件拦截的位置,但这个是在执行方法时利用反射动态判断的,初始化的时候就是简单的把拦截器插入到了所有可以拦截的地方。所以尽量不要编写不必要的拦截器。另外我们可以在调用插件的地方添加判断,只要是当前拦截器拦截的对象才进行调用,否则直接返回目标对象本身,这样可以减少反射判断的次数,提高性能。 */ @Override public Object plugin(Object target) { if (target instanceof Executor) { // 仅当对象为Executor时, 才使用本插件 return Plugin.wrap(target, this); } else { return target; } } /** * 用于配置本插件的相关属性 */ @Override public void setProperties(Properties properties) { // Do nothing } /** 执行拦截处理 **/ @Override public Object intercept(Invocation invocation) throws Throwable { long start = System.currentTimeMillis(); Object target = invocation.getTarget(); //被代理对象 // Object method = invocation.getMethod(); // 被代理方法 // Object ags = invocation.getArgs(); // 方法参数 if (target instanceof Executor) { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; Object parameter = invocation.getArgs()[1]; /** 几个核心部件:(建议跳转Mybatis——拦截器Interceptor_mybatis 拦截器-CSDN博客查看详情,注释仅作笔记处理) * Configuration:初始化基础配置,比如MyBatis的别名等,一些重要的类型对象,如插件,映射器,ObjectFactory和typeHandler对象,MyBatis所有的配置信息都维持在Configuration对象之中。 * SqlSessionFactory:SqlSession工厂。 * SqlSession:作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要的数据库增删改查功能。 * Executor:MyBatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过ResultSetHandler进行自动映射,另外,它还处理二级缓存的操作。 * StatementHandler:MyBatis直接在数据库执行SQL脚本的对象。另外它也实现了MyBatis的一级缓存。 * ParameterHandler:负责将用户传递的参数转换成JDBC Statement所需要的参数。是MyBatis实现SQL入参设置的对象。 * ResultSetHandler:负责将JDBC返回的ResultSet结果集对象转换成List类型的集合。是MyBatis把ResultSet集合映射成POJO的接口对象。 * TypeHandler:负责Java数据类型和JDBC数据类型之间的映射和转换。 * MappedStatement:MappedStatement维护了一条<select|update|delete|insert>节点的封装。 * SqlSource :负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。 * BoundSql:表示动态生成的SQL语句以及相应的参数信息。 * **/ BoundSql boundSql = mappedStatement.getBoundSql(parameter); String sql = boundSql.getSql(); System.out.println("SQL: "+sql); } Object result = invocation.proceed(); // 真正调用被代理方法 long duration = System.currentTimeMillis() - start; System.out.println("Time elapsed: "+duration+"ms"); return result; } }
*\FirstSBDemo\src\main\java\com\namejr\controller\PublicController.java
package com.namejr.controller; import com.namejr.dao.PublicDao; import com.namejr.serviceImpl.PublicServiceImpl; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @RestController @RequestMapping(value = "/api/public") @Validated public class PublicController { @Autowired private PublicServiceImpl pServiceImpl; @Autowired private PublicDao pDao; @RequestMapping(value = "/getServerTime", method = RequestMethod.GET,produces = "application/json;charset=UTF-8") public String getServerTime() { return DateTime.now().toString("yyyy-MM-dd HH:mm:ss"); } @RequestMapping(value = "/getDBInfos", method = RequestMethod.GET,produces = "application/json;charset=UTF-8") public String getDBInfos() { List<HashMap<String,String>> tempOBSInfos= pDao.getResGuids(); if(tempOBSInfos!=null&&!tempOBSInfos.isEmpty()){ tempOBSInfos.forEach((Map<String,String> tempOBSInfo)->{ System.out.println(tempOBSInfo.get("res_guid")); }); return "successful"; } return "failed"; } }
*\FirstSBDemo\src\main\resources\application.properties
server.port=8080 logging.config=classpath:logback-spring.xml # mysql信息配置(需要根据实际配置) spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testDB?characterEncoding=UTF-8&allowMultiQueries=true&&useAffectedRows=true&allowPublicKeyRetrieval=true&useSSL=false spring.datasource.username=namejr spring.datasource.password=000000 mybatis.type-aliases-package=ccom.namejr.bean mybatis.mapper-locations=classpath:/dao/*.xml
*\FirstSBDemo\src\main\resources\dao\PublicDao.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.namejr.dao.PublicDao"> <select id="getResGuids" resultType="java.util.HashMap"> select distinct res_guid from ques_resource limit 1; </select> </mapper>
访问输出:http://127.0.0.1:8080/api/public/getDBInfos
SQL: select distinct res_guid from ques_resource limit 1; Time elapsed: 183ms dt-c304326b1eb54e8594c5cc35f76a04ae