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注入,提高系統安全性。

擴展一點項目中經常用的路徑小知識:

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