项目技巧三
目录
我们现在要实现一个接口功能
1.我们先书写sql语句
2.编写接口
3.书写业务逻辑
4.书写mapper
结果:
缺点:没有根据涨跌幅区间的大小来排序
1.yml文件
2.在value object包下映射这个yml文件
3.开启这个配置类进行映射,并把它交给spring管理
4.修改后的业务逻辑
5.新的结果
6.第二种业务逻辑,使用lambda表达式
我们现在要实现一个接口功能
查询当前时间下股票的涨跌幅度区间统计功能
如果当前日期不在有效时间内,则以最近的一个股票交易时间作为查询点
股票涨跌幅区间定义: "<-7%" 、 "-7~-5%"、 "-5~-3%" 、 "-3~0%" 、"0~3%" 、 "3~5%" 、 "5~7%" 、 ">7%"
要返回的数据
{ "code": 1, "data": { "time": "2021-12-31 14:58:00", "infos": [ { "count": 17, "title": "-3~0%" }, { "count": 2, "title": "-5~-3%" }, //省略...... ] } }
1.我们先书写sql语句
#统计当前时间下(精确到分钟),A股在各个涨跌区间股票的数量; #股票涨跌幅区间定义: "<-7%" 、 "-7~-5%"、 "-5~-3%" 、 "-3~0%" 、"0~3%" 、 "3~5%" 、 "5~7%" 、 ">7%" #1.使用的表stock_market_index_info #2.业务分析:1.时间:当前最新交易时间点 #2.要统计出每个个股的涨幅流水表 #3.把每个个股的涨幅转换成涨跌幅区间 使用 case when then end #4.最后根据涨跌幅区间来分组统计每个组的记录数量 count #3.返回的数据 count title(涨跌幅区间)
#1.统计每个个股的涨幅
select (cur_price-pre_close_price)/pre_close_price as ud from stock_rt_info where cur_time='2022-01-06 09:55:00';
#2.把涨幅字段的值转换成涨跌幅区间
select
case
when tmp.ud>0.07 then '>7%' #根据条件来该字段的值
when tmp.ud<=0.07 and tmp.ud>0.05 then '5~7%'
when tmp.ud<=0.05 and tmp.ud>0.03 then '3~5%'
when tmp.ud<=0.03 and tmp.ud>0 then '0~3%'
when tmp.ud<=0 and tmp.ud>-0.03 then '-3~0%'
when tmp.ud<=-0.03 and tmp.ud>-0.05 then '-5~-3%'
when tmp.ud<=-0.05 and tmp.ud>=-0.07 then '-7~-5%'
else '<-7%'
end 'title' #给这个字段重命名
from (select (cur_price-pre_close_price)/pre_close_price as ud from stock_rt_info where cur_time='2022-01-06 09:55:00')
as tmp;
#3.根据涨跌幅区间进行分组
select count(*) as count, tmp2.title from (select
case
when tmp.ud>0.07 then '>7%' #根据条件来该字段的值
when tmp.ud<=0.07 and tmp.ud>0.05 then '5~7%'
when tmp.ud<=0.05 and tmp.ud>0.03 then '3~5%'
when tmp.ud<=0.03 and tmp.ud>0 then '0~3%'
when tmp.ud<=0 and tmp.ud>-0.03 then '-3~0%'
when tmp.ud<=-0.03 and tmp.ud>-0.05 then '-5~-3%'
when tmp.ud<=-0.05 and tmp.ud>=-0.07 then '-7~-5%'
else '<-7%'
end 'title' #给这个字段重命名
from (select (cur_price-pre_close_price)/pre_close_price as ud from stock_rt_info where cur_time='2022-01-06 09:55:00')
as tmp) as tmp2 group by tmp2.title;
2.编写接口
/**
* 查询当前时间下股票的涨跌幅度区间统计功能
* 如果当前日期不在有效时间内,则以最近的一个股票交易时间作为查询点
* @return
*/
@ApiOperation("查询最新交易时间下股票的涨跌幅度区间中各个股票的数量")
@GetMapping("/stock/updown")
public R<Map<String,Object>> getStockUpDown(){//这里使用的是Object,因为每个键对应的类型不一样,一个是String,一个是List集合
return stockService.stockUpDownScopeCount();
}
3.书写业务逻辑
/**
* 查询当前时间下股票的涨跌幅度区间统计功能
* 如果当前日期不在有效时间内,则以最近的一个股票交易时间作为查询点
* @return
*/
@Override
public R<Map<String, Object>> stockUpDownScopeCount() {
//1.获取当前时间的最新交易点
DateTime datetime = DateTimeUtil.getLastDate4Stock(DateTime.now());
Date time=datetime.toDate();
//设置mock data
DateTime curDateTime=DateTime.parse("2022-01-06 09:55:00",DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
Date curDate = curDateTime.toDate();
//2.根据mapper接口获取数据
List<Map> infos=stockRtInfoMapper.getStockUpDownScopeCount(curDate);
//3.封装数据
Map<String,Object>data=new HashMap<>();
data.put("time",curDateTime.toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")));
data.put("infos",infos);
//4.返回数据
return R.ok(data);
}
4.书写mapper
/**
* 查询当前时间下股票的涨跌幅度区间统计功能
* 如果当前日期不在有效时间内,则以最近的一个股票交易时间作为查询点
* @return
*/
List<Map> getStockUpDownScopeCount(@Param("curDate") Date curDate);
5.书写mapperXml文件
<!-- 如果在XML中SQL语句遇到大量特殊字符需要转义,比如:< 等,建议使用** sql 语句 **标记,这样特殊字符就不会被解析器解析
所以使用<![CDATA[]]> -->
<select id="getStockUpDownScopeCount" resultType="map">
<![CDATA[
select count(*) as count, tmp2.title from (select
case
when tmp.ud>0.07 then '>7%'
when tmp.ud<=0.07 and tmp.ud>0.05 then '5~7%'
when tmp.ud<=0.05 and tmp.ud>0.03 then '3~5%'
when tmp.ud<=0.03 and tmp.ud>0 then '0~3%'
when tmp.ud<=0 and tmp.ud>-0.03 then '-3~0%'
when tmp.ud<=-0.03 and tmp.ud>-0.05 then '-5~-3%'
when tmp.ud<=-0.05 and tmp.ud>=-0.07 then '-7~-5%'
else '<-7%'
end 'title'
from (select (cur_price-pre_close_price)/pre_close_price as ud from stock_rt_info where cur_time=#{curDate})
as tmp) as tmp2 group by tmp2.title
]]>
</select>
结果:
缺点:没有根据涨跌幅区间的大小来排序
我们可以在application-stock.yml文件中自己书写按照大小排序的涨跌幅区间,因为涨跌幅区间不能直接进行大小比较进行排序
1.yml文件
# 配置股票相关的参数
stock:
upDownRange:
- "<-7%"
- "-7~-5%"
- "-5~-3%"
- "-3~0%"
- "0~3%"
- "3~5%"
- "5~7%"
- ">7%"
2.在value object包下映射这个yml文件
@Data
@ConfigurationProperties(prefix = "stock")//映射yml文件中stock属性的值
//@Component//直接让其交给spring管理,TODO:我们不使用(不让它自己开启),我们让其他要使用该类的子模块来开启
public class StockInfoConfig {
public List<String>upDownRange;//涨跌幅区间
}
3.开启这个配置类进行映射,并把它交给spring管理
@Configuration
@EnableConfigurationProperties(StockInfoConfig.class)//TODO:在这个子模块开启加载此配置类,并让它映射yml文件中的stock属性的值,再交给spring管理
public class CommonConfig {
}
4.修改后的业务逻辑
/**
* 查询当前时间下股票的涨跌幅度区间统计功能
* 如果当前日期不在有效时间内,则以最近的一个股票交易时间作为查询点
* @return
*/
@Override
public R<Map<String, Object>> stockUpDownScopeCount() {
//1.获取当前时间的最新交易点
DateTime datetime = DateTimeUtil.getLastDate4Stock(DateTime.now());
Date time=datetime.toDate();
//设置mock data
DateTime curDateTime=DateTime.parse("2022-01-06 09:55:00",DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
Date curDate = curDateTime.toDate();
//2.根据mapper接口获取数据
List<Map> infos=stockRtInfoMapper.getStockUpDownScopeCount(curDate);
//获取涨跌幅区间(按照大小排序)
List<String> upDownRange = stockInfoConfig.getUpDownRange();
List<Map>orderInfos=new ArrayList<>();//创建一个新的集合,来接收新的数据
for (String range : upDownRange) {//按照涨跌幅区间排序(升序)
Map tmpMap =null;//创建一个临时map
for (Map map : infos) {
if(map.containsValue(range)){//如果包含这个涨跌幅区间,就进行赋值
tmpMap=map;
break;
}
}
if(tmpMap==null) {//如果tmpMap还为null,则说明没有该涨跌幅区间
tmpMap=new HashMap();//自己进行赋值
tmpMap.put("count",0);
tmpMap.put("title",range);
}
orderInfos.add(tmpMap);//添加
}
//3.封装数据
Map<String,Object>data=new HashMap<>();
data.put("time",curDateTime.toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")));
data.put("infos",orderInfos);
//4.返回数据
return R.ok(data);
}
5.新的结果
6.第二种业务逻辑,使用lambda表达式
/**
* 查询当前时间下股票的涨跌幅度区间统计功能
* 如果当前日期不在有效时间内,则以最近的一个股票交易时间作为查询点
* @return
*/
@Override
public R<Map<String, Object>> stockUpDownScopeCount() {
//1.获取当前时间的最新交易点
DateTime datetime = DateTimeUtil.getLastDate4Stock(DateTime.now());
Date time=datetime.toDate();
//设置mock data
DateTime curDateTime=DateTime.parse("2022-01-06 09:55:00",DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
Date curDate = curDateTime.toDate();
//2.根据mapper接口获取数据
List<Map> infos=stockRtInfoMapper.getStockUpDownScopeCount(curDate);
//获取涨跌幅区间(按照大小排序)
List<String> upDownRange = stockInfoConfig.getUpDownRange();
/*
List<Map>orderInfos=new ArrayList<>();//创建一个新的集合,来接收新的数据
for (String range : upDownRange) {//按照涨跌幅区间排序(升序)
Map tmpMap =null;//创建一个临时map
for (Map map : infos) {
if(map.containsValue(range)){//如果包含这个涨跌幅区间,就进行赋值
tmpMap=map;
break;
}
}
if(tmpMap==null) {//如果tmpMap还为null,则说明没有该涨跌幅区间
tmpMap=new HashMap();//自己进行赋值
tmpMap.put("count",0);
tmpMap.put("title",range);
}
orderInfos.add(tmpMap);//添加
}
*/
List<Map>orderInfos=upDownRange.stream().map(range->{//使用map方法将String数据类型转换成map类型,range是upDownRange集合的每个值
Map tmpMap=null;//创建一个临时map
//使用之前查询出来的List<Map>集合来过滤出含有涨跌幅区间的map,并使用findFirst()进行赋值
//这里使用 Optional来接收,是防止为null
Optional<Map>op =infos.stream().filter(map->map.containsValue(range)).findFirst();
if(op.isPresent()){
tmpMap=op.get();//存在就直接进行赋值
}else{
tmpMap=new HashMap();//自己进行赋值
tmpMap.put("count",0);
tmpMap.put("title",range);
}
return tmpMap;
}).collect(Collectors.toList());
//3.封装数据
Map<String,Object>data=new HashMap<>();
data.put("time",curDateTime.toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")));
data.put("infos",orderInfos);
//4.返回数据
return R.ok(data);
}