logback是boot默认的日志首选,个人觉得是最好的日志实现(比log4j好)

下边,在之前的代码基础上增加一个功能,该功能要实现mybatis的and or联查功能,并通过logback日志在控制台去查看输出的sql情况。

即实现如下sql的功能:

SELECT * FROM tb_user WHERE id = ? AND (username=? OR `password`= ?);

该语句需要用到xml格式。

注意:由本节开始,springboot采用了1.3.0.

1、com.xxx.firstboot.web.UserController

     @ApiOperation("测试mybatis and or联查")
@ApiImplicitParams({
@ApiImplicitParam(paramType="query",name="id",dataType="int",required=false, value="用户的id",defaultValue="1"),
@ApiImplicitParam(paramType="query",name="username",dataType="String",required=false,value="用户的姓名",defaultValue="zhaojigang"),
@ApiImplicitParam(paramType="query",name="password",dataType="String",required=false,value="用户的密码",defaultValue="wangna")
})
@ApiResponses({
@ApiResponse(code=400,message="请求参数没填好"),
@ApiResponse(code=404,message="请求路径没有或页面跳转路径不对")
})
@RequestMapping(value="/testMybatisAndOrUnion",method=RequestMethod.GET)
public User getUserByIdAndUsernameOrPassword(@RequestParam(name="id",required=false) Integer id,
@RequestParam(name="username",required=false) String username,
@RequestParam(name="password",required=false) String password) {
return userService.getUserByIdAndUsernameOrPassword(id, username, password);
}

注意

  • 这里我三个参数都是"required=false",是为了测试。
  • id使用Integer是为了让其可以为null来测试,如果改成int的话如果前端不传参数就会出问题。
    • 这也是Integer的一个用途

2、com.xxx.firstboot.service.UserService

 @Service
public class UserService { private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class); @Autowired
private UserDao userDao; public User getUserByIdAndUsernameOrPassword(Integer id, String username, String password){
User user = userDao.getUserByIdAndUsernameOrPassword(id, username, password);
LOGGER.info("getUserByIdAndUsernameOrPassword success! user:'{}'", user);
return user;
}

说明

  • 在该service中引入了slf4j,这是日志接口,其实现可以是各种实现,包括logback,log4j等

3、com.xxx.firstboot.dao.UserDao

     /**
* 测试 mybatis and or联查
*/
public User getUserByIdAndUsernameOrPassword(Integer id, String username, String password){
return userMapper.getUserByIdAndUsernameOrPassword(id, username, password);
}

4、com.xxx.firstboot.mapper.UserMapper

 public User getUserByIdAndUsernameOrPassword(@Param("id") Integer id, @Param("username") String username, @Param("password") String password);

说明

  • 这里参数的传递必须使用@Param来传递,否则xml里接收不到

    • 目前为止,只发现传递模型类(eg.User)不需要@Param注解

5、src/main/resources/mapper/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"> <!-- 指定工作空间,要与接口名相同,源代码没有去看,猜测应该是通过"这里的namespace.下边方法的id"来定位方法的 -->
<mapper namespace="com.xxx.firstboot.mapper.UserMapper">
<resultMap type="User" id="userResultMap">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="password" column="password" />
</resultMap> <!-- SELECT * FROM tb_user WHERE id = 1 AND (username='' OR `password`='wangna'); -->
<select id="getUserByIdAndUsernameOrPassword" resultMap="userResultMap">
<![CDATA[ SELECT * FROM tb_user WHERE id = #{id}]]>
<trim prefix=" AND (" suffix=")" prefixOverrides="OR">
<if test="username != null"><![CDATA[ username = #{username}]]></if>
<if test="password != null"><![CDATA[ OR password = #{password}]]></if>
</trim>
</select> </mapper>

注意:trim的作用

  • prefix=" AND (":在"被trim括起来的满足条件的语句的最前方"添加,例如添加" AND ("
  • suffix=")":在"被trim括起来的满足条件的语句的最后方"添加,例如添加")"
  • prefixOverrides="OR":被trim括起来的满足条件的语句的最前方如果是"OR"(语句中的OR前可以有多个空格,但是prefixOverrides="OR"中的OR前边不能有空格)。eg.如果上述语句中id和password传了,如果不加这个属性,就会形成如下的sql:SELECT * FROM tb_user WHERE id = 1 AND ( OR 'password'='wangna'),该语句就错了;如果加了的话,就会使用prefix=" AND ("来覆盖" OR",就会如下sql:SELECT * FROM tb_user WHERE id = 1 AND ( 'password'='wangna')
  • 如果username和password都isBlank(即为null或者为""),该trim标签会判断trim内没有语句,则不会加上prefix和suffix,eg.SELECT * FROM tb_user WHERE id = 1 AND ( )(这样的情况不会出现)。

6、src/main/resources/logback.xml

 <?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<!-- 1、logger
属性:
1)name:用来指定受此logger约束的某一个包或者具体的某一个类
2)level:用来设置打印级别,大小写无关(最常用的几种):DEBUG, INFO, WARN, ERROR
2、
-->
<!-- <logger name="org.springframework.web" level="DEBUG" /> --> <!-- mybatis日志打印 -->
<!-- <logger name="com.ibatis" level="DEBUG" /> -->
<!-- <logger name="com.ibatis.common.jdbc.SimpleDataSource" level="DEBUG" /> -->
<!-- <logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG" /> -->
<!-- <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" level="DEBUG" /> --> <!-- <logger name="java.sql.Connection" level="DEBUG" /> -->
<!-- <logger name="java.sql.Statement" level="DEBUG" /> -->
<!-- <logger name="java.sql.PreparedStatement" level="DEBUG" /> -->
<!-- 这一句至关重要如果没有,就无法输出sql语句 -->
<logger name="com.xxx.firstboot.mapper" level="DEBUG"></logger>
</configuration>

注意:在boot中,想在控制台打印mybatis的sql语句,只需要配置下边这一句就好了。

<logger name="com.xxx.firstboot.mapper" level="DEBUG"></logger>

即将mapper接口打入logger就行。

但是在ssm中,可能就需要该行上边的7行了。(这个没有测过不清楚)

测试:

启动应用,打开swagger。

打印出的sql语句:SELECT * FROM tb_user WHERE id = ?

打印出的sql语句:SELECT * FROM tb_user WHERE id = ? AND ( username = ? )

打印出的sql语句:SELECT * FROM tb_user WHERE id = ? AND ( password = ? )

打印出的sql语句:SELECT * FROM tb_user WHERE id = ? AND ( username = ? OR password = ? )

根据测试可以发现,id是必须的,这也是我的项目的需求(而这里不传id,只是为了测试而已),如果id也不是必须,就要考虑trim的位置以及prefixOverrides的值(可以使用AND|OR这样的表示或)

参考自:

http://stackoverflow.com/questions/21718097/how-to-configure-logback-for-mybatis-to-print-my-sql

http://aub.iteye.com/blog/1896611 关于logback可以参考的博客

第十章 springboot + logback的更多相关文章

  1. ELK+SpringBoot+Logback离线安装及配置

    ELK+SpringBoot+Logback 离线安装及配置 版本 v1.0 编写时间 2018/6/11 编写人 xxx     目录 一. ELK介绍2 二. 安装环境2 三. Elasticse ...

  2. springboot logback 集成

    在 application.yml 中敲 logging.pattern.consle ,IDEA 会联想到对应的值.单击属性就可以跳到 LoggingApplicationListener.java ...

  3. SpringBoot Logback配置,SpringBoot日志配置

    SpringBoot Logback配置,SpringBoot日志配置  SpringBoot springProfile属性配置 ================================ © ...

  4. 利用SpringBoot+Logback手写一个简单的链路追踪

    目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...

  5. springboot+logback日志输出企业实践(下)

    目录 1.引言 2. 输出 logback 状态数据 3. logback 异步输出日志 3.1 异步输出配置 3.2 异步输出原理 4. springboot 多环境下 logback 配置 5. ...

  6. springboot+logback日志输出企业实践(上)

    目录 1.引言 2.logback简介 3. springboot默认日志框架-logback 3.1 springboot示例工程搭建 3.2 日志输出与基本配置 3.2.1 日志默认输出 3.2. ...

  7. SpringBoot Logback无法获取配置中心属性

    SpringBoot Logback无法获取配置中心属性 前言 最近在做项目中,需要把项目中的日志信息通过RabbitMQ将规定格式的消息发送到消息队列中,然后ELK系统通过消息队列拿日志并且保存起来 ...

  8. 【第十章】 springboot + logback

    logback是boot默认的日志首选,个人觉得是最好的日志实现(比log4j好) 下边,在之前的代码基础上增加一个功能,该功能要实现mybatis的and or联查功能,并通过logback日志在控 ...

  9. springboot logback 相关使用

    参考: https://www.cnblogs.com/EasonJim/p/9159195.html https://blog.csdn.net/tianyaleixiaowu/article/de ...

随机推荐

  1. 在分享到微信里的网页中,打开qq对话框。

    废话不多说,就是要去这个网址把qq申请一下服务. 网址: http://shang.qq.com/v3/widget.html 大概长这样: 2.截取这一段代码: 3.重新分享到微信,因为微信好像有缓 ...

  2. 【LOJ】 #2009. 「SCOI2015」小凸玩密室

    题解 神仙dp啊QAQ 我们发现我们需要枚举一个起点,遍历完它所有的儿子然后向上爬 设\(f[i][j]\)表示第i个点的子树全部处理完之后到达i深度为j的祖先的兄弟处 我们只需要对叶子节点和只有一个 ...

  3. SCU 4445 Right turn

    模拟. 每次找一下即将要遇到的那个点,这个数据范围可以暴力找,自己的写的时候二分了一下.如果步数大于$4*n$一定是$-1$. #include<bits/stdc++.h> using ...

  4. Spring Boot 整合MyBatis(1)

    这篇文章介绍如何在Spring boot中整合Mybatis,其中sql语句采用注解的方式插入.后续文章将会介绍,如何使用xml方式. SSM SSH框架已经满足轻量级这个需求了,但是对于开发人员而言 ...

  5. Bzoj[Usaco2018 Feb]5194 Snow Boots(线段树)

    Description 到冬天了,这意味着下雪了!从农舍到牛棚的路上有N块地砖,方便起见编号为1…N,第i块地砖上积了fi英尺的雪 .在Farmer John的农舍的地窖中,总共有B双靴子,编号为1… ...

  6. zstuoj 4245 KI的斐波那契

    KI的斐波那契 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 550  Solved: 208 Description KI十分喜欢美丽而优雅的斐波那 ...

  7. Redis学习篇(四)之List类型及其操作

    Redis的List是一个双向链表 LPUSH 作用:向列表左端添加元素 语法:LPUSH key value value... 从左到右逐个添加到左端,前面的先添加, 可以一次添加多个元素 RPUS ...

  8. android remoteView

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha remoteView  可以在 appWidget 和 notification 中 使 ...

  9. JZYZOJ1998 [bzoj3223] 文艺平衡树 splay 平衡树

    http://172.20.6.3/Problem_Show.asp?id=1998 平衡树区间翻转的板子,重新写一遍,给自己码一个板子. #include<iostream> #incl ...

  10. CodeForces - 1009D Relatively Prime Graph

    题面在这里! 直接暴力找点对就行了,可以证明gcd=1是比较密集的,所以复杂度略大于 O(N log N) #include<bits/stdc++.h> #define ll long ...