总结:
打包部署:
基本的CRUD
因为项目使用了mybatis-generator,所以其实大部分的数据库的sql语句就不用自己写了
分页
借助PageHelper
public List<Member> list(MemberQueryParam memberQueryParam, Integer pageSize, Integer pageNum) {
// 分页
PageHelper.startPage(pageNum, pageSize);
MemberExample memberExample = new MemberExample();
MemberExample.Criteria criteria = memberExample.createCriteria();
// 这里是做条件查询的判断
if (!StringUtils.isEmpty(memberQueryParam.getName())) {
criteria.andNameLike("%" + memberQueryParam.getName() + "%");
}
if (memberQueryParam.getDayPrice() != null) {
criteria.andDayPriceEqualTo(memberQueryParam.getDayPrice());
}
if (memberQueryParam.getDepartId() != null) {
criteria.andDepartIdEqualTo(memberQueryParam.getDepartId());
}
return memberMapper.selectByExample(memberExample);
}
返回结果的封装
主要代码在package com.azhu.mana.api下,可以仔细看看
不仅有各种常见返回结果的封装,还有分页返回结果的封装
ps:
List是一bai个接口,而ListArray是一个类。
ListArray继承并实现了List。
所以List不能被构造,但可以向上面那样为List创建一个引用,而ListArray就可以被构造。
问题
- 数据库中日期最好用什么类型(String还是Date)
- 如何检验String类型是否符合Date类型
- 捕获异常后是否可以返回给前端信息,说字符串格式不对,该如何返回,应该是直接在catch里面return 错误信息
Java String转Date
ArrayList的add()添加元素时重复的问题
-
如果自己更新mapper,添加新的xml,会不会被别人generator的时候覆盖
-
报表统计——java实现查询某年12个月数据,没数据补0
这个数据库里面的年月日是在三个属性里面
日期
比较是否为同一天:
Java判断两个Date是不是同一天
DateUtils.isSameDay(date1,date2)
比较日期前后:
date1.after(date2)
Lombok
帮助
遍历Map的几种方式
JAVA8 List<List<Integer>> list中再装一个list转成一个list
mybatis example group by count 分组求和 - java分组求和
返回echarts所需数据,饼图
返回数据格式:
按日返回各部门盈利
{
"code": 200,
"message": "操作成功",
"data": {
"departIds": [
1,
2,
3,
4
],
"departNames": [
"a部门",
"b部门",
"c部门",
"d部门"
],
"departProfitDataList": [
{
"profits": 250,
"departName": "a部门"
},
{
"profits": 160,
"departName": "b部门"
},
{
"profits": 80,
"departName": "c部门"
},
{
"profits": 70,
"departName": "d部门"
}
]
}
}
主要代码:
/**
* 按日返回各部门数据,饼图
* 思路:
* 1. 将string类型的传参day转换成Date,因为数据库里面是Date
* 2. 获取当前数据库当天的所有部门信息(数据库里面一个部门一天只有一条数据)
* 3.1. 若返回数据为null,直接return null
* 3.2. 若返回数据有值,进行下一步处理
* 4. 遍历返回数据,主要是进行按组封装返回数据
*/
@Override
public DepartDataDayResult resultByDay(String day) {
// 日饼图
// day的形式是2020-12-17
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//设置包容性,为true时,比如"1992-12-32"则会变成"1993-1-1",这里为了检验,设为false
simpleDateFormat.setLenient(false);
Date date = simpleDateFormat.parse(day);
System.out.println(date);
// 获取DepartData表的数据
DepartDataExample departDataExample = new DepartDataExample();
DepartDataExample.Criteria criteria = departDataExample.createCriteria();
criteria.andTimeEqualTo(date);
List<DepartData> departDataList = departDataMapper.selectByExample(departDataExample);
if (departDataList == null) {
return null;
}
// 处理数据
System.out.println("departDataList:" + departDataList);
List<Integer> departIds = new ArrayList<>();
List<String> departNames = new ArrayList<>();
DepartDataDayResult departDataResult = new DepartDataDayResult(departIds, departNames);
List<DepartProfitData> departProfitDataList = new ArrayList<>();
for (DepartData departData : departDataList) {
// 将所有id组合成组 [1,2,3,4]
departIds.add(departData.getDepartId());
String name = departService.getName(departData.getDepartId());
// 这个要放里面,否则会出现数据重复的问题
DepartProfitData departProfitData = new DepartProfitData();
// [{profit:220, departName: 'a部门'},{profit:220, departName: 'a部门'}]
departProfitData.setDepartName(name);
departProfitData.setProfits(departData.getProfit());
// System.out.println(departProfitData);
departProfitDataList.add(departProfitData);
// System.out.println(departProfitDataList);
// ['a部门','b部门']
departNames.add(name);
}
System.out.println(departProfitDataList);
departDataResult.setDepartProfitDataList(departProfitDataList);
return departDataResult;
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
返回echarts所需数据,折线图
返回数据格式:
按月返回各部门盈利
{
"code": 200,
"message": "操作成功",
"data": {
"departIds": [
1,
2,
3,
4
],
"departNames": [
"a部门",
"b部门",
"c部门",
"d部门"
],
"departProfitDataMap": {
"1": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
250,
120
],
"2": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
160
],
"3": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
80
],
"4": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
70
]
},
"duration": [
"2020-11-18",
"2020-11-19",
"2020-11-20",
"2020-11-21",
"2020-11-22",
"2020-11-23",
"2020-11-24",
"2020-11-25",
"2020-11-26",
"2020-11-27",
"2020-11-28",
"2020-11-29",
"2020-11-30",
"2020-12-01",
"2020-12-02",
"2020-12-03",
"2020-12-04",
"2020-12-05",
"2020-12-06",
"2020-12-07",
"2020-12-08",
"2020-12-09",
"2020-12-10",
"2020-12-11",
"2020-12-12",
"2020-12-13",
"2020-12-14",
"2020-12-15",
"2020-12-16",
"2020-12-17",
"2020-12-18"
]
}
}
/**
* 按月返回各部门数据,折线图
* 思路:
* 1. 处理传参day,有2020-12-18或者2020-12两种形式,获取到开始日期和截止日期
* 2.1. 2020-12-18
* a. day转化成Date数据类型,作为截止日期
* b. 借助DateUtil(自己封装的函数)获取到这天的前一个月日期值(作为开始日期)
* 2.2. 2020-12
* a. 获取这个月的第一天,作为开始日期
* b. 获取这个月的最后一天,作为截止日期
* 3. 获取部门信息
* 4. 遍历部门信息,按部门id查询这段期间的depart_date数据库的信息
* 5.1. 如果查询结果为null,将这一个月数据全补0
* 5.2. 否则进行数据处理,有则补充,无则补0
*/
@Override
public DepartDataMonthAndSeasonResult resultByMonth(String day) {
// 月折线图
// ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 时间一个月
// ['expected', 'actual'], 部门列表
// [100, 120, 161, 134, 105, 160, 165], 比如是第一个部门在这一个月内的每天盈利,这个每个部门对于一个数组
// month的形式是2020-12-17 或者是 2020-12
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//设置包容性,为true时,比如"1992-12-32"则会变成"1993-1-1",这里为了检验,设为false
simpleDateFormat.setLenient(false);
// 处理数据,获取开始和截止时间
int str_len = day.trim().length();
System.out.println("month:" + day);
Date startDate = null;
Date endDate = null;
Calendar c = Calendar.getInstance();
if (str_len > 7) {
// 传的是截止日期2020-12-17
endDate = simpleDateFormat.parse(day);
System.out.println(endDate);
//过去一月
c.setTime(endDate);
c.add(Calendar.MONTH, -1);
startDate = c.getTime();
} else {
// 传的是2020-12,就是要获取2020-12月的所有数据
String[] split = day.split("-");
int year = Integer.parseInt(split[0]);
int mon = Integer.parseInt(split[1]);
startDate = DateUtil.getFirstDay(year, mon);
endDate = DateUtil.getLastDay(year, mon);
}
// 获取DepartData表的数据
// DepartDataExample departDataExample = new DepartDataExample();
// DepartDataExample.Criteria criteria = departDataExample.createCriteria();
// criteria.andTimeBetween(startDate, endDate);
// List<DepartData> departDataList = departDataMapper.selectByExample(departDataExample);
// System.out.println(departDataList);
//
//
// if (departDataList == null) {
// return null;
// }
// // 将数据按照部门id分组
// Map<Integer, List<DepartData>> departDataGroupByDidList = departDataList.stream().collect(Collectors.groupingBy(DepartData::getDepartId));
// System.out.println(departDataGroupByDidList);
// HashMap<Integer, List<Long>> resMap = new HashMap<>(128);
// // 这里已经分好组了,Integer是组id,List<DepartData>是数据
// for (Map.Entry<Integer, List<DepartData>> departDataEntry : departDataGroupByDidList.entrySet()) {
// List<Long> departIdData = new ArrayList<>();
// for (DepartData departD : departDataEntry.getValue()) {
// departIdData.add(departD.getProfit());
// }
// System.out.println(departIdData);
// resMap.put(departDataEntry.getKey(), departIdData);
// }
// System.out.println(resMap);
/*
* 思路:
* 1. 首先查看depart_id,查看有几个部门
* 2. 根据部门限制+起止时间,查询这段时间的数据
* 3. 遍历,查看时间日期,相应填数据
* */
List<Date> duration = DateUtil.getDatesBetweenTwoDate(startDate,endDate);
List<String> sDuration = DateUtil.dateToStringList("yyyy-MM-dd",duration);
// 1
List<Depart> departList = departService.list();
List<Integer> departIds = new ArrayList<>();
List<String> departNames = new ArrayList<>();
HashMap<Integer, List<Long>> resMap = new HashMap<>(128);
for (Depart depart:departList) {
departIds.add(depart.getId());
departNames.add(departService.getName(depart.getId()));
// 2
DepartDataExample departDataExample = new DepartDataExample();
departDataExample.setOrderByClause("time ASC");
DepartDataExample.Criteria criteria = departDataExample.createCriteria();
criteria.andTimeBetween(startDate,endDate);
criteria.andDepartIdEqualTo(depart.getId());
List<DepartData> departDataList = departDataMapper.selectByExample(departDataExample);
// 3
List<Long> sqlData = new ArrayList<>();
if (departDataList==null) {
for (Date d : duration) {
sqlData.add(0L);
}
}
else {
for (Date d : duration) {
for (DepartData departData : departDataList) {
if (departData.getTime().after(d)) {
// 如果在之后,补0
sqlData.add(0L);
break;
}
else {
if(DateUtils.isSameDay(departData.getTime(),d)) {
sqlData.add(departData.getProfit());
break;
}
else {
continue;
}
}
}
}
resMap.put(depart.getId(),sqlData);
}
}
DepartDataMonthAndSeasonResult departDataMonthAndSeasonResult = new DepartDataMonthAndSeasonResult(departIds, departNames, resMap, sDuration);
return departDataMonthAndSeasonResult;
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
返回echarts所需数据,柱状图
返回数据格式:
按季节返回各部门盈利
{
"code": 200,
"message": "操作成功",
"data": {
"departIds": [
1,
2,
3,
4
],
"departNames": [
"a部门",
"b部门",
"c部门",
"d部门"
],
"departProfitDataMap": {
"1": [
0,
0,
0,
370
],
"2": [
0,
0,
0,
160
],
"3": [
0,
0,
0,
80
],
"4": [
0,
0,
0,
70
]
},
"duration": [
"Spring",
"Summer",
"Autumn",
"Winter"
]
}
}
/**
* 按季节返回各部门数据,柱状图
* 思路:
* 1. 处理传参year(2020),比较当前年和传值年
* 2.1. 传值年<=当前年
* 2.2. 传值年>当前年
* return null
* 3. 获取部门信息
* 4. 遍历部门信息,按部门id查询传值年(整年)的depart_date数据库的信息
* 5.1. 如果查询结果为null,将该部门四季的返回盈利总额全补0,即[0,0,0,0]
* 5.2. 否则进行下一步,按季节开始和截止时间,总共进行四次按部门按时间查询盈利总额(这里查询用的是自己写的mapper方法),无则补0,将四次结果添加到数组
*/
@Override
public DepartDataMonthAndSeasonResult resultBySeason(String year) {
// 纵坐标['Spring', 'Summer', 'Autumn', 'Winter']
// [79, 52, 200, 334]每个部门对应一个数组
// 季度一年四季, 第一季度:1月-3月, 第二季度:4月-6月, 第三季度:7月-9月, 第四季度:10月-12月
/*
* 1. 输入年份2020
* 2. 自动生成到今天为止的四季
* */
// Calendar today = Calendar.getInstance();
// // 获取当前月
// int month = today.get(Calendar.MONTH)+1;
// 获取当前日期
System.out.println(year);
Date startDate = null;
Date endDate = null;
Date today = DateUtil.getDate(new Date());
Calendar calendar = Calendar.getInstance();
// 当前年
int year1 = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH)+1;
// 传值年
int year2 = Integer.parseInt(year);
List<Depart> departList = departService.list();
System.out.println(departList);
List<Integer> departIds = new ArrayList<>();
List<String> departNames = new ArrayList<>();
HashMap<Integer, List<Long>> resMap = new HashMap<>(128);
List<String> seasonList = new ArrayList<>();
seasonList.add("Spring");
seasonList.add("Summer");
seasonList.add("Autumn");
seasonList.add("Winter");
if(year1<=year2) {
// 按部门来看四季
for (Depart depart:departList) {
// 首先查查这一年有没有数据,没有就直接返回全0
departIds.add(depart.getId());
departNames.add(depart.getName());
startDate = DateUtil.getFirstDay(year2, 1);
endDate = DateUtil.getLastDay(year2, 12);
DepartDataExample departDataExample = new DepartDataExample();
DepartDataExample.Criteria criteria = departDataExample.createCriteria();
criteria.andTimeBetween(startDate,endDate);
criteria.andDepartIdEqualTo(depart.getId());
List<DepartData> departDataList = departDataMapper.selectByExample(departDataExample);
List<Long> sqlData = new ArrayList<>();
if(departDataList==null) {
for(int i=1;i<=4;i++) {
sqlData.add(0L);
}
resMap.put(depart.getId(),sqlData);
}
else {
// 四季
for(int i=1;i<=4;i++) {
startDate = DateUtil.getFirstDay(year2, (i-1)*3+1);
endDate = DateUtil.getLastDay(year2, i*3);
Long seasonProfit = departDataMapper.getSeasonProfitByTime(startDate,endDate,depart.getId());
System.out.println(seasonProfit);
if(seasonProfit==null) {
sqlData.add(0L);
}
else {
sqlData.add(seasonProfit);
}
}
resMap.put(depart.getId(),sqlData);
}
}
} else {
return null;
}
DepartDataMonthAndSeasonResult departDataMonthAndSeasonResult = new DepartDataMonthAndSeasonResult(departIds, departNames, resMap, seasonList);
return departDataMonthAndSeasonResult;
}
注意点:
写mapper方法如下:
Long getSeasonProfitByTime(@Param("startDate") Date startDate, @Param("endDate") Date endDate, @Param("departId") Integer departId);
<select id="getSeasonProfitByTime" parameterType="map" resultType="java.lang.Long">
select sum(profit)
from depart_data
where depart_id = #{departId,jdbcType=INTEGER}
and time BETWEEN #{startDate,jdbcType=DATE}
and #{endDate,jdbcType=DATE}
</select>
因为是多个传参,所以用parameterType=“map”
传一个Integer参数,用这种方法parameterType=“java.lang.Integer”
因为返回值是Long类型,所以用resultType=“java.lang.Long”
返回对象,用resultMap=“BaseResultMap”
ps:这里的Map和Type千万别弄错