Mysql查询指定时间数据+Mybatis中#{}和${}区别及使用场景

一、Mysql查询时间段数据

今天

select * from 表名 where to_days(时间字段名) = to_days(now());

昨天

SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1

近7天

SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)

近30天

SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名)

本月

SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )

注意: %m 对应的月份格式就是: 01,02,03...12.,如果月份是1,2,3...则需要将%m换成%c
上一月

SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( 时间字段名, '%Y%m' ) ) =1

查询本季度数据

select * from `ht_invoice_information` where QUARTER(create_date)=QUARTER(now());

查询上季度数据

select * from `ht_invoice_information` where QUARTER(create_date)=QUARTER(DATE_SUB(now(),interval 1 QUARTER));

查询本年数据

select * from `ht_invoice_information` where YEAR(create_date)=YEAR(NOW());

查询上年数据

select * from `ht_invoice_information` where year(create_date)=year(date_sub(now(),interval 1 year));

查询当前这周的数据

SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) = YEARWEEK(now());

查询上周的数据

SELECT name,submittime FROM enterprise WHERE YEARWEEK(date_format(submittime,'%Y-%m-%d')) = YEARWEEK(now())-1;

查询上个月的数据

select name,submittime from enterprise where date_format(submittime,'%Y-%m')=date_format(DATE_SUB(curdate(), INTERVAL 1 MONTH),'%Y-%m')

select * from user where DATE_FORMAT(pudate,'%Y%m') = DATE_FORMAT(CURDATE(),'%Y%m') ; 

select * from user where WEEKOFYEAR(FROM_UNIXTIME(pudate,'%y-%m-%d')) = WEEKOFYEAR(now()) 

select * from user where MONTH(FROM_UNIXTIME(pudate,'%y-%m-%d')) = MONTH(now()) 

select * from user where YEAR(FROM_UNIXTIME(pudate,'%y-%m-%d')) = YEAR(now()) and MONTH(FROM_UNIXTIME(pudate,'%y-%m-%d')) = MONTH(now()) 

select * from user where pudate between  上月最后一天  and 下月第一天 

查询当前月份或任意某个月的数据

select name,submittime from enterprise where date_format(submittime,'%Y-%m')=date_format(now(),'%Y-%m') 

//=后面可换为具体时间,查询任意月份的数据
查询距离当前时间6个月的数据

select name,submittime from enterprise where submittime between date_sub(now(),interval 6 month) and now();

查询某个月的数据(查询17年10月份数据)

select * from exam   where date_format(starttime,'%Y-%m')='2017-10'
select * from exam   where date_format(starttime,'%Y-%m')=date_format('2017-10-05','%Y-%m')

以上来源于:Mysql中查询某一天,某个月,某一年数据

当然,查询某年的某个月在mybatis中我是这样写的:

@Select("select count(*) from admineventdetails where year(uploadTime)=#{year} and month(uploadTime)=#{month}")

注:uploadTime为数据库时间字段,year和month直接传入String即可。
友情提示:使用between and查询时间段数据时候需要注意数据库中时间字段和传入的时间参数统一问题,比如数据库中是datetime(带时分秒的) ,传入时间参数就必须携带时分秒,否则将会出现边界查询不到的情况。

二、MySQL 日期格式

  • %Y ​代表四位年份 ​%y ​代表两位年份
  • %m ​代表月格式(01,02,03…12) ​%c ​代表月格式(1,2,3…12)
  • %d ​代表日
  • %H ​代表24小时制 ​%h ​代表12小时制
  • %i ​代表分钟(00,-01,02…59)
  • %S或%s ​代表秒(00,01,02…59)

参考链接:sql语句查询指定月份数据

三、Mybatis中#{}和${}区别及常用场景

1、 ${}和#{}详解

动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${} 。

  • #{} : 根据参数的类型进行处理,比如传入String类型,则会为参数加上双引号。#{} 传参在进行SQL预编译时,会把参数部分用一个占位符 ? 代替,这样可以防止 SQL注入。
  • ${} : 将参数取出不做任何处理,直接放入语句中,就是简单的字符串替换,并且该参数会参加SQL的预编译,需要手动过滤参数防止 SQL注入。
    因此 mybatis 中优先使用 #{};当需要动态传入 表名或列名时,再考虑使用 ${} 。

其中 ${} 比较特殊, 他的应用场景是 需要动态传入 表名或列名时使用。下面举例

2、应用场景

首先看下面的SQL语句, 功能是查出年龄使用 IN 运算符,姓名采用模糊查询的一些男生,按照出生时间降序排列。但是下面这代码是达不到需求的,读者可以自己先找找问题。

<!-- 条件查询 -->
    <select id="getList" resultType="com.ccyang.UserDao">
        select 
            u.user_id, u.user_name, u.user_type, u.age, u.sex, u.birthday
        from
            user u
        <where>
            u.user_age in <foreach collection="ages" item="item" index="index" open="(" separator="," close=")">#{item}</foreach>
            and u.sex == "男"
            <if test="u.user_name != null and u.user_name != ''"> AND u.user_name like CONCAT(CONCAT('%', #{userName}), '%')</if>   
            <if test="order_by!= null and order_by != ''">  order by #{order_by} DESC</if>  
        </where>    
    </select>

上面这段代码可以查出数据,但是根据业务来看是有问题的,他不能进行排序,因为 #{birthday} 解析出来后是一个 带着双引号的字符串,mysql找不到这样的列名,因此不能进行排序。

正确的写法应该是使用 ${order_by},这样解析后就是一个列名,然后才能对数据进行排序,已达到业务需求。

<!-- 条件查询 -->
    <select id="getList" resultType="com.ccyang.UserDao">
        select 
            u.user_id, u.user_name, u.user_type, u.age, u.sex, u.birthday
        from
            user u
        <where>
            u.user_age in <foreach collection="ages" item="item" index="index" open="(" separator="," close=")">#{item}</foreach>
            and u.sex == "男"
            <if test="u.user_name != null and u.user_name != ''"> AND u.user_name like CONCAT(CONCAT('%', #{userName}), '%')</if>   
            <if test="order_by!= null and order_by != ''">  order by ${order_by} DESC</if> 
        </where>    
    </select>

参考链接:mybatis 中 #{} 和 ${} 的区别及应用场景

四、小结:

Mybatis本身是基于JDBC封装的。

  • #{para}是预编译处理(PreparedStatement)范畴的。
  • ${para}是字符串替换。这种方式的缺点是: 以这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。
  • Mybatis在处理#时,会调用PreparedStatement的set系列方法来赋值;处理时,就是把{para}替换成变量的值。使用#{para}可以有效的防止SQL注入,提高系统安全性。

扩展一点项目中经常用的路径小知识:

  • "./":代表目前所在的目录。
  • " . ./"代表上一层目录。
  • "/":代表根目录。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章