1. 程式人生 > >mybaties呼叫mysql儲存過程。儲存過程返回多個select結果集。

mybaties呼叫mysql儲存過程。儲存過程返回多個select結果集。

先看需求,直接上圖

從圖中看出,需要12條普通的SELECT語句,所以就放到儲存過程中
儲存過程如下:

DROP PROCEDURE IF EXISTS proc_report;
DELIMITER $
CREATE PROCEDURE proc_report(
OUT d_normal INT,
OUT d_warn INT,
OUT d_error INT,
OUT d_fatal INT,
OUT m_normal INT,
OUT m_warn INT,
OUT m_error INT,
OUT m_fatal INT,
OUT w_normal INT,
OUT w_warn INT,
OUT w_error INT,
OUT w_fatal INT
)
BEGIN
-- 過去一天的正常日誌數量
    SELECT COUNT(1) INTO d_normal FROM device_log a 
	   WHERE a.type = '0' 
	     AND TO_DAYS(NOW()) - TO_DAYS(a.create_time) < 1;    

-- 過去一天的警告日誌數量
    SELECT COUNT(1) INTO d_warn FROM device_log a 
	   WHERE a.type = '1' 
	     AND TO_DAYS(NOW()) - TO_DAYS(a.create_time) < 1;    

-- 過去一天的錯誤日誌數量
    SELECT COUNT(1) INTO d_error FROM device_log a 
	   WHERE a.type = '2' 
	     AND TO_DAYS(NOW()) - TO_DAYS(a.create_time) < 1;

-- 過去一天的嚴重錯誤日誌數量
    SELECT COUNT(1) INTO d_fatal FROM device_log a 
	   WHERE a.type = '3' 
	     AND TO_DAYS(NOW()) - TO_DAYS(a.create_time) < 1;

-- 過去一個月的正常日誌數量
    SELECT COUNT(1) INTO m_normal FROM device_log a
     WHERE a.type = '0'
       AND PERIOD_DIFF(DATE_FORMAT(NOW(),'%Y%m'),DATE_FORMAT(a.create_time,'%Y%m')) < 1;
-- 過去一個月的警告日誌數量 
    SELECT COUNT(1) INTO m_warn FROM device_log a
     WHERE a.type = '1'
       AND PERIOD_DIFF(DATE_FORMAT(NOW(),'%Y%m'),DATE_FORMAT(a.create_time,'%Y%m')) < 1;
-- 過去一個月的錯誤日誌數量
    SELECT COUNT(1) INTO m_error FROM device_log a
     WHERE a.type = '2'
       AND PERIOD_DIFF(DATE_FORMAT(NOW(),'%Y%m'),DATE_FORMAT(a.create_time,'%Y%m')) < 1;
-- 過去一個月的嚴重錯誤日誌數量 
    SELECT COUNT(1) INTO m_fatal FROM device_log a
     WHERE a.type = '3'
       AND PERIOD_DIFF(DATE_FORMAT(NOW(),'%Y%m'),DATE_FORMAT(a.create_time,'%Y%m')) < 1;
-- 過去7天的正常日誌
    SELECT COUNT(1) INTO w_normal FROM device_log a 
     WHERE a.type = '0'
       AND DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(a.create_time);
-- 過去7天的警告日誌
    SELECT COUNT(1) INTO w_warn FROM device_log a 
     WHERE a.type = '1'
       AND DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(a.create_time);
-- 過去7天的錯誤日誌
    SELECT COUNT(1) INTO w_error FROM device_log a 
     WHERE a.type = '2'
       AND DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(a.create_time);
-- 過去7天的嚴重錯誤日誌
    SELECT COUNT(1) INTO w_fatal FROM device_log a 
     WHERE a.type = '3'
       AND DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(a.create_time);
 
END $


mysql中的呼叫先看一下

CALL proc_report(
	        @d_normal,
			    @d_warn,
			    @d_error,
			    @d_fatal,
			    @m_normal,
			    @m_warn,
			    @m_error,
			    @m_fatal,
          @w_normal,
			    @w_warn,
			    @w_error,
			    @w_fatal
	           );
	    
	   SELECT @d_normal AS d_normal,@d_warn AS d_warn,@d_error AS d_error,@d_fatal AS d_fatal,
              @m_normal AS m_normal,@m_warn AS m_warn,@m_error AS m_error,@m_fatal AS m_fatal,
              @w_normal AS w_normal,@w_warn AS w_warn,@w_error AS w_error,@w_fatal AS w_fatal 

查詢結果如下圖:
在這裡插入圖片描述

mybaties中的呼叫和在DB中呼叫不一樣,需要注意

mybaties呼叫程式碼:

<!-- report -->
	<select id="getDeviceLog" statementType="CALLABLE" >
	   CALL proc_report(
			    #{d_normal,jdbcType=INTEGER,mode=OUT},
			    #{d_warn,jdbcType=INTEGER,mode=OUT},
			    #{d_error,jdbcType=INTEGER,mode=OUT},
			    #{d_fatal,jdbcType=INTEGER,mode=OUT},
			    #{m_normal,jdbcType=INTEGER,mode=OUT},
			    #{m_warn,jdbcType=INTEGER,mode=OUT},
			    #{m_error,jdbcType=INTEGER,mode=OUT},
			    #{m_fatal,jdbcType=INTEGER,mode=OUT},
			    #{w_normal,jdbcType=INTEGER,mode=OUT},
			    #{w_warn,jdbcType=INTEGER,mode=OUT},
			    #{w_error,jdbcType=INTEGER,mode=OUT},
			    #{w_fatal,jdbcType=INTEGER,mode=OUT}
	           )
	</select>

注意:第一點:從select節點引數看得出來,這個查詢是沒有返回值的。第二點:和在mysql中呼叫又點區別,不再需要【select @引數名】,我使用了實體類傳送和接收引數,查詢結果會直接set到實體類的物件中

DAO層程式碼:

/**
 * DAO介面
 * @author CYH
 * @version 2018-11-23
 */
@MyBatisDao
public interface DeviceLogDao extends CrudDao<DeviceLog> {
    
    public void getDeviceLog(DeviceLog deviceLog);
    
    public List<DeviceLog> getLogList(DeviceLog deviceLog);
}

注意是 void getDeviceLog,如果是帶有返回值的,結果集回事null,這裡的結果都set到DeviceLog 的物件中了

service層程式碼:

@Autowired
	private DeviceLogDao deviceLogDao;
	
	public void getLog(DeviceLog deviceLog){
		deviceLogDao.getDeviceLog(deviceLog);
	}

controller層程式碼:

/**
		 * 過去一天:d_normal 正常,d_warn警告,d_error錯誤,d_fatal嚴重錯誤;
		 * 過去一月:m_normal 正常,m_warn警告,m_error錯誤,m_fatal嚴重錯誤;
		 * 過去一星期:w_normal 正常,w_warn警告,w_error錯誤,w_fatal嚴重錯誤
		*/
		deviceLogService.getLog(deviceLog);
		map.put("d_normal", deviceLog.getD_normal());
		map.put("d_warn", deviceLog.getD_warn());
		map.put("d_error", deviceLog.getD_error());
		map.put("d_fatal", deviceLog.getD_fatal());
		map.put("m_normal", deviceLog.getM_normal());
		map.put("m_warn", deviceLog.getM_warn());
		map.put("m_error", deviceLog.getM_error());
		map.put("m_fatal", deviceLog.getM_fatal());
		map.put("w_normal", deviceLog.getW_normal());
		map.put("w_warn", deviceLog.getW_warn());
		map.put("w_error", deviceLog.getW_error());
		map.put("w_fatal", deviceLog.getW_fatal());
		model.addAttribute("log", map);

後臺程式碼到此結束