温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring Boot整合MyBatis学习总结

发布时间:2020-07-05 00:22:55 来源:网络 阅读:7156 作者:zhuwensheng 栏目:开发技术

      公司的很多项目都陆陆续续引入了Spring Boot,通过对Spring Boot的接触了解发现其真的是大大地简化了开发、简化了依赖配置,很多功能注解一下就可以实现,真的是太方便了。下面记录了一个Spring Boot的入门程序实现,包括过滤器、servlet、定时器、全局异常处理、日志、Druid数据源的SQL监控配置。

1,pom.xml文件:

<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.zws</groupId>   <artifactId>spring-boot</artifactId>   <version>0.0.1-SNAPSHOT</version>   <packaging>jar</packaging>   <name>spring-boot</name>   <url>http://maven.apache.org</url>   <properties>     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>   </properties>      <parent>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-parent</artifactId>     <version>1.5.10.RELEASE</version>   </parent>   <dependencies>	<dependency>	    <groupId>org.springframework.boot</groupId>	    <artifactId>spring-boot-starter-web</artifactId>	    <exclusions>	        <exclusion>	           <groupId>org.springframework.boot</groupId>	           <artifactId>spring-boot-starter-logging</artifactId>	        </exclusion>	</exclusions>	</dependency>	<dependency>	    <groupId>org.springframework.boot</groupId>	    <artifactId>spring-boot-starter-aop</artifactId>	</dependency>	<dependency>	    <groupId>org.springframework.boot</groupId>	    <artifactId>spring-boot-starter-jdbc</artifactId>	</dependency>	<dependency>	    <groupId>org.mybatis.spring.boot</groupId>	    <artifactId>mybatis-spring-boot-starter</artifactId>	    <version>1.3.1</version>	</dependency>	<dependency>	    <groupId>com.alibaba</groupId>	    <artifactId>druid-spring-boot-starter</artifactId>	    <version>1.1.0</version>	</dependency>	<dependency>  	    <groupId>mysql</groupId>  	    <artifactId>mysql-connector-java</artifactId>  	</dependency>	<dependency>	    <groupId>commons-logging</groupId>	    <artifactId>commons-logging</artifactId>	    <version>1.2</version>	</dependency>	<dependency>	    <groupId>org.slf4j</groupId>	    <artifactId>slf4j-api</artifactId>	</dependency>	<dependency>	    <groupId>log4j</groupId>	    <artifactId>log4j</artifactId>	    <version>1.2.17</version>	</dependency>	<dependency>	    <groupId>com.alibaba</groupId>	    <artifactId>fastjson</artifactId>	    <version>1.2.46</version>	</dependency>	<dependency>	    <groupId>junit</groupId>	    <artifactId>junit</artifactId>	    <scope>test</scope>	</dependency>   </dependencies>      <build>       <plugins>       	  <plugin>	      <groupId>org.apache.maven.plugins</groupId>	  <artifactId>maven-compiler-plugin</artifactId>	  <configuration>	      <source>1.8</source>	      <target>1.8</target>	  </configuration>	  </plugin>           <plugin>               <groupId>org.springframework.boot</groupId>               <artifactId>spring-boot-maven-plugin</artifactId>           </plugin>       </plugins>   </build> </project>

可以看到这个文件内容并不多,但是却引入了很多需要的依赖。这里引入的Spring Boot版本为1.5.10.RELEASE,其中spring-boot-maven-plugin插件是Spring Boot提供的打包用的插件。mybatis-spring-boot-starter为MyBatis集成Spring Boot的依赖。druid-spring-boot-starter为阿里开源数据源Druid集成Spring Boot的依赖,它会下载对应的druid jar包,注意这里并没有直接引入Druid依赖,如果直接引入Druid依赖jar包,则druid的监控页面无法显示sql。

2,Spring Boot配置文件resources/application.properties:

server.port=8080 server.context-path=/app spring.mvc.throw-exception-if-no-handler-found=true spring.resources.add-mappings=false #tomcat访问日志 server.tomcat.basedir=logs server.tomcat.accesslog.enabled=true server.tomcat.accesslog.directory=access server.tomcat.accesslog.pattern=%t %a "%r" %s %b (%D ms) datasource.druid.url=jdbc:mysql://localhost/db_boot?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false datasource.druid.username=root datasource.druid.password=root datasource.druid.driver-class-name=com.mysql.jdbc.Driver datasource.druid.initialSize=5 datasource.druid.minIdle=5 datasource.druid.maxActive=20 datasource.druid.maxWait=60000 datasource.druid.minEvictableIdleTimeMillis=300000 datasource.druid.validationQuery=select 'x' datasource.druid.testOnBorrow=false datasource.druid.testOnReturn=false datasource.druid.testWhileIdle=true datasource.druid.poolPreparedStatements=false datasource.druid.maxPoolPreparedStatementPerConnectionSize=100 datasource.druid.filters=stat,wall,log4j mybatis.config-location=classpath:mybatis/mybatis-config.xml mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

application.properties文件为Spring Boot的总配置文件,Spring Boot默认会加载resources目录下的application.properties文件。Spring Boot默认内嵌Tomcat作为web容器,server.port为端口,server.context-path为上下文路径。datasource开头的为druid数据源的配置。

3,MyBatis的配置文件resources/mybatis/mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration>	<settings>	<setting name="cacheEnabled" value="true" />	<setting name="lazyLoadingEnabled" value="true" />	<setting name="multipleResultSetsEnabled" value="true" />	<setting name="useColumnLabel" value="true" />	<setting name="useGeneratedKeys" value="false" />	<setting name="autoMappingBehavior" value="PARTIAL" />	<setting name="autoMappingUnknownColumnBehavior" value="WARNING" />	<setting name="defaultExecutorType" value="SIMPLE" />	<setting name="defaultStatementTimeout" value="25" />	<setting name="defaultFetchSize" value="100" />	<setting name="safeRowBoundsEnabled" value="false" />	<setting name="mapUnderscoreToCamelCase" value="false" />	<setting name="localCacheScope" value="SESSION" />	<setting name="jdbcTypeForNull" value="OTHER" />	<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />	</settings>	<typeAliases>	<package name="com.zws.be.user.bean" />	</typeAliases> </configuration>

此配置文件的路径已经配置在了resources/application.properties文件内。

4,resources/mybatis/UserMapper.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.zws.be.user.mapper.UserMapper" >     <resultMap id="UserMap" type="User">         <id column="id" property="id" jdbcType="BIGINT" />         <result column="name" property="name" jdbcType="VARCHAR" />         <result column="pass" property="pass" jdbcType="VARCHAR" />         <result column="create_date" property="createDate" />     </resultMap>     <select id="getAll" resultMap="UserMap">        select id, name, pass, create_date from user     </select>          <select id="getUserById" resultMap="UserMap" parameterType="long">     	select id, name, pass, create_date from user where id = #{value}     </select> </mapper>

5,Sping Boot启动类Application.java:

package com.zws.be; import javax.sql.DataSource; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.Bean; import org.springframework.scheduling.annotation.EnableScheduling; import com.alibaba.druid.pool.DruidDataSource; @SpringBootApplication @MapperScan(basePackages = {"com.zws.be.*.mapper"}) @ServletComponentScan @EnableScheduling public class Application {	public static void main(String[] args) {	SpringApplication.run(Application.class, args);	}	@Bean("dataSource")	@ConfigurationProperties("datasource.druid")	public DataSource getDruidDataSource() {	return DataSourceBuilder.create().type(DruidDataSource.class).build();	} }

这个是程序启动的入口,里面有mian函数,运行此类即可启动Spring Boot。注解@MapperScan(basePackages = {"com.zws.be.*.mapper"})指定了映射mapper文件的接口所在的包。@EnableScheduling注解用于开启Spring的定时组件,下面会有例子。@ServletComponentScan注解搭配@WebServlet和@WebFilter注解使得定义servlet和filter时非常方便。

6,下面是定义一个简单的restful接口所需的各类:

com.zws.be.user.bean.User:

package com.zws.be.user.bean; import java.util.Date; import org.apache.ibatis.type.Alias; @Alias("User") public class User {	private Long id;	private String name;	private String pass;	private Date createDate;	public Long getId() {	return id;	}	public void setId(Long id) {	this.id = id;	}	public String getName() {	return name;	}	public void setName(String name) {	this.name = name;	}	public String getPass() {	return pass;	}	public void setPass(String pass) {	this.pass = pass;	}	public Date getCreateDate() {	return createDate;	}	public void setCreateDate(Date createDate) {	this.createDate = createDate;	}	@Override	public String toString() {	return "User [id=" + id + ", name=" + name + ", pass=" + pass + ", createDate=" + createDate + "]";	} }

com.zws.be.user.mapper.UserMapper:

package com.zws.be.user.mapper; import java.util.List; import com.zws.be.user.bean.User; public interface UserMapper {	List<User> getAll();	User getUserById(Long id); }

com.zws.be.user.service.UserService:

package com.zws.be.user.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zws.be.user.bean.User; import com.zws.be.user.mapper.UserMapper; @Service public class UserService {	@Autowired	private UserMapper userMapper;	public List<User> getUsers() {	return userMapper.getAll();	}	public User getUser(Long id) {	return userMapper.getUserById(id);	} }

com.zws.be.user.controller.UserController:

package com.zws.be.user.controller; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import com.zws.be.user.bean.User; import com.zws.be.user.service.UserService; @RestController @RequestMapping("/user") public class UserController {	public Logger logger = Logger.getLogger(UserController.class);	@Autowired	private UserService userService;	@RequestMapping(value="/{id}", method=RequestMethod.GET, produces = "application/json")	public String hello(@PathVariable Long id) {	User user = userService.getUser(id);	return JSON.toJSONString(user, SerializerFeature.WriteDateUseDateFormat);	} }

7,配置Druid的sql监控servlet:

package com.zws.be.filter; import javax.servlet.annotation.WebServlet; import com.alibaba.druid.support.http.StatViewServlet; /**  * DRUID的sql监控  * @author wensh.zhu  * @2018-03-11  */ @WebServlet(name="monitorSrvlet", urlPatterns= {"/druid/*"}) public class MonitorServlet extends StatViewServlet {	private static final long serialVersionUID = -2211104135110049275L; }

启动后访问http://localhost:8080/app/druid即可进入Druid的sql监控的监控页面。

8,过滤器例子:

package com.zws.be.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import org.apache.log4j.Logger; @WebFilter(filterName="filterDemo", urlPatterns = {"/*"}) public class FilterDemo implements Filter{	private Logger logger = Logger.getLogger(FilterDemo.class);	@Override	public void destroy() {}	@Override	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)	throws IOException, ServletException {	logger.info("FilterDemo is working...");	chain.doFilter(arg0, arg1);	}	@Override	public void init(FilterConfig arg0) throws ServletException {	} }

9,定时器例子:

package com.zws.be.timer; import org.apache.log4j.Logger; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class TimerDemo {	private Logger logger = Logger.getLogger(getClass());	@Scheduled(cron = "0/30 * * * * *")  	public void timer() {	logger.info("定时器例子");	} }

10,全局异常处理:

package com.zws.be.exception; import org.apache.log4j.Logger; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; /**  * 全局异常处理  * @author wensh.zhu  * @2018-03-11  */ @RestControllerAdvice public class ExceptionAdvice {	private Logger logger = Logger.getLogger(getClass());	private String pattern = "抱歉,异常了:{0}";	@ExceptionHandler(value = {Exception.class})	@ResponseBody	public String handleAllException(Exception e, HttpServletRequest req, HttpServletResponse resp) {	logger.error("接口调用异常", e);	if (e instanceof NoHandlerFoundException) {	String reqURI = req.getRequestURI().toString();	return MessageFormat.format(pattern, "资源" + reqURI + "不存在!!!");	}	return MessageFormat.format(pattern, e.getMessage());	} }

11,log4j配置文件resources/log4j.properties:

log4j.rootLogger=INFO, stdout, infoLog, errorLog log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.conversionPattern = %d{yyyy-MM-dd HH\:mm\:ss}|%p|%C|%M|%L|%m%n log4j.appender.infoLog=com.zws.be.log.MyRollingFileAppender log4j.appender.infoLog.File=logs/info/info.log log4j.appender.infoLog.Threshold = info log4j.appender.infoLog.layout=org.apache.log4j.PatternLayout log4j.appender.infoLog.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss}|%p|%C|%M|%L|%m%n log4j.appender.errorLog=com.zws.be.log.MyRollingFileAppender log4j.appender.errorLog.File=logs/error/error.log log4j.appender.errorLog.Threshold = error log4j.appender.errorLog.layout=org.apache.log4j.PatternLayout log4j.appender.errorLog.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss}|%p|%C|%M|%L|%m%n

自定义日志生成文件名称:

package com.zws.be.log; import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; import org.apache.log4j.Priority; import org.apache.log4j.RollingFileAppender; import org.apache.log4j.helpers.CountingQuietWriter; import org.apache.log4j.spi.LoggingEvent; public class MyRollingFileAppender extends RollingFileAppender{	private long nextRollover = 0L;	public void rollOver() {	File target, file;	if (qw != null) {	long size = ((CountingQuietWriter) qw).getCount();	nextRollover = size + maxFileSize;	}	boolean renameSuccessed = true;	if (maxBackupIndex > 0) {	file = new File(getRollingFileName(fileName, maxBackupIndex));	if (file.exists()) {	renameSuccessed = file.delete();	}	for (int i = maxBackupIndex - 1; i >= 1 && renameSuccessed; i --) {	file = new File(getRollingFileName(fileName, i));	if (file.exists()) {	target = new File(getRollingFileName(fileName, i + 1));	renameSuccessed = file.renameTo(target);	}	}	if (renameSuccessed) {	target = new File(getRollingFileName(fileName, 1));	closeFile();	renameSuccessed = file.renameTo(target);	if (!renameSuccessed) {	try {	setFile(fileName, true, bufferedIO, bufferSize);	} catch (IOException e) {	if (e instanceof InterruptedIOException) {	Thread.currentThread().interrupt();	}	}	}	}	}	}	private String getRollingFileName(String fileName, int index) {	String fName = "";	String newIndex = index < 10 ? ("0" + index) : String.valueOf(index);	if (index > 0) {	fName = fileName.replace(".log", "") + "_" + newIndex + ".log";	} else {	fName = fileName;	}	return fName;	}	@Override	protected void subAppend(LoggingEvent event) {	super.subAppend(event);	if (fileName != null && qw != null) {	long size = ((CountingQuietWriter) qw).getCount();	if (size >= maxFileSize && size >= nextRollover) {	rollOver();	}	}	}	@Override	public boolean isAsSevereAsThreshold(Priority priority) {	String level = priority.toString();	if ("ERROR".equals(level)) {	return getThreshold().equals(priority);	}	return super.isAsSevereAsThreshold(priority);	} }

12,Spring MVC请求参数以及返回信息自动日志的辅助类:

package com.zws.be.log; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.text.MessageFormat; import org.apache.log4j.Logger; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /**  * 用于请求参数、响应信息的自动日志。  * @author wensh.zhu  * @2018-03-11  */ @ControllerAdvice(basePackages = {"com.zws.be"}) public class LogResponseBodyAdvice implements ResponseBodyAdvice<String>{	private String pattern = "\n---BEGIN---\nReqURI:{0}\nParams:{1}\nMethod:{2}\nReturn:{3}\n---END---";	private Logger logger = Logger.getLogger(LogResponseBodyAdvice.class);	@Override	public String beforeBodyWrite(String rtnMsg, MethodParameter param, MediaType arg2,	Class<? extends HttpMessageConverter<?>> arg3, ServerHttpRequest req, ServerHttpResponse resp) {	String clazName = param.getDeclaringClass().getName();	String mtdName = param.getMethod().getName();	String reqURI = req.getURI().toString();	String reqParams = getReqParams(req);	String log = getLog(reqURI, reqParams, clazName + "." + mtdName, rtnMsg);	logger.info(log);	return rtnMsg;	}	@Override	public boolean supports(MethodParameter arg0, Class<? extends HttpMessageConverter<?>> arg1) {	return true;	}	private String getLog(String reqURI, String reqParams, String proMethod, String rtnMsg) {	return MessageFormat.format(pattern, reqURI, reqParams, proMethod, rtnMsg);	}	private String getReqParams(ServerHttpRequest req) {	StringBuilder body = new StringBuilder();	String line = null;	BufferedReader reader = null;	try {	reader = new BufferedReader(new InputStreamReader(req.getBody(), "UTF-8"));	while ((line = reader.readLine()) != null) {	body.append(line);	}	} catch (IOException e) {	logger.error("I/O error ", e);	} finally {	try {	if (reader != null) {	reader.close();	}	} catch (IOException e) {	logger.error("I/O error ", e);	}	}	return body.toString();	} }

此类功能为将Spring MVC接受到请求的参数、处理请求对应的方法、请求返回内容自动打印到日志文件内,在接口出现问题的时候方便排查,日志输出样例:

---BEGIN--- ReqURI:http://localhost:8080/app/user/1 Params: Method:com.zws.be.user.controller.UserController.hello Return:{"createDate":"2018-03-04 15:44:25","id":1,"name":"zhangsan","pass":"zhangsan@123"} ---END---

13,运行Application,访问http://localhost:8080/app/user/1,如下图:

Spring Boot整合MyBatis学习总结

查看druid的监控:

Spring Boot整合MyBatis学习总结

项目目录结构图:

Spring Boot整合MyBatis学习总结

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI