今天从中午弄到晚上九点多就一直在纠结,到底是经验不够,哎
一 后端
要实现的是找出所有分组及每个分组下的所有车辆
(1)SQL语句的编写
车辆为一张表,分组为一张表,车辆表里的分组ID对应着分组表里的主键ID。
我们设想了好多条SQL语句,比如:
select t_car.id ,t_car.car_group from t_car group by t_car.id ;
select t_car.id ,t_car.car_group from t_car group by t_car.car_group ;
select t_group.id , t_car.id from t_car left join t_group on t_car.car_group = t_group.id group by t_group.id ;
select t_group.id , t_car.id from t_car join t_group on t_car.car_group = t_group.id group by t_group.id ;
select t_car.id from t_car join t_group on t_car.car_group = t_group.id group by t_group.id ;
它们都会报一个错误:
[42000][1055] Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'cardemo.t_car.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
。。。。。
最后我的设想是:先找出所有分组,再根据分组id找到在这个分组的所有车辆。
Repository层:
//请求全部分组
@Override
List<Group> findAll();
//根据分组查询车辆
// @Query(value = "select t_car.id,t_car.car_type,t_car.car_number from t_car join t_group on t_car.car_group = t_group.id where t_group.id = ?1",nativeQuery = true)
// List<Car> findCarsGroupByGroup(String groupId);
@Query(value = "select t_car.id from t_car join t_group on t_car.car_group = t_group.id where t_group.id = ?1",nativeQuery = true)
List<String> findCarsGroupByGroup(String groupId);
在写第二个方法时我接连踩了几个坑:
(1)t_car is not mapped
解决:在@Query注解里加上nativeQuery = true,我对@Query注解的使用还不够理解。(捂脸)
(2)query did not return a unique result
Encountered a duplicated sql alias [xxxx] during auto-discovery of a native-sql query
分析:我一开始写的SQL语句是“select * from…”,因为我的车辆表和分组表都有一个相同的字段id,也许就是这样导致了报错。因此我把SQL语句改成了现在这样。
(3)cannot convert …String …to 我自己定义的实体类
分析:这个错误是在后面服务层调用这个方法时出现的。我一开始看到这个错误感到一脸懵逼,后来想到这样的SQL语句返回的是String,而我却简单粗暴地把它转换成我定义的实体类,并放到List里。最后我使用了String的List存储查找返回的结果,在服务层里再进行转换。
服务层:
//请求全部数据
List<Group> findAll();
//根据分组查询车辆
// List<Car> getCarsGroupByGroup(String groupId);
List<Car> getCarsGroupByGroup(String groupId);
@Override
public List<Group> findAll() {
return groupRepository.findAll();
}
@Override
public List<Car> getCarsGroupByGroup(String groupId) {
List<String> strings = groupRepository.findCarsGroupByGroup(groupId);
List<Car> cars = new ArrayList<>();
for (int i = 0; i < strings.size(); i++) {
Car car = carService.findById(strings.get(i));
cars.add(car);
}
return cars;
}
控制层:
//请求全部数据
@GetMapping("/groupList")
@CrossOrigin
public List<Group> getAllGroups(){
return groupService.findAll();
}
@GetMapping("/groupCars/{id}")
@CrossOrigin
public List<Car> getCarsGroupByGroup(@PathVariable("id") String groupId){
return groupService.getCarsGroupByGroup(groupId);
}
二 前端
写好了接口,接下来就该思考前端要如何拿到数据并进行页面渲染了。
我使用了Element UI的折叠面板组件,我一开始的代码是这样的:
<el-collapse v-model="activeNames" >
<el-collapse-item
v-for="(item,index) in group"
:title="item.groupName"
@click.native="getCarByGroup(index,item.id)">
<div>
v-for="c in car">
{{c.carNumber}}
</div>
</el-collapse-item>
</el-collapse>
data() {
return {
group:[],
car:[],
activeNames: ['1']
};
},
methods: {
getCarByGroup(id){
let config = {
url:'http://localhost:8080/group/groupCars/'+id,
method: 'get',
}
axios(config)
.then((response) => {
console.log(response)
this.car = response.data
// console.log(tableData)
})
.catch((err) => {
console.log(err)
})
},
handleGroup(){
let config = {
url:'http://localhost:8080/group/groupList',
method: 'get',
}
axios(config)
.then((response) => {
this.group = response.data
// console.log(tableData)
})
},
handleChange(val) {
console.log(val);
}
},
created() {
//this.handle(this.$route.query.id);
this.handleGroup()
},
因为我循环得到三个面板,然后他们都有相同的一个点击事件……然后点击事件得到的值就把三个面板的内容都改变了……都变成相同的了。。。。。而我预想是每个面板有各自对应的内容的……
这就尴尬了。。。。
然后挠破脑袋想半天。。。因为我对前端开发还不怎么熟悉,最后听取了一位前端同学的意见,将折叠面板里的内容封装成一个子组件:
<template>
<div>
<div
v-for="c in car">
{{c.carNumber}}
</div>
</div>
</template>
然后就涉及到父子组件通信的问题了。子组件里:
props:['id'],
data(){
return{
car:[],
}
},
methods:{
handle(id){
let config = {
url:'http://localhost:8080/group/groupCars/'+id,
method: 'get',
}
axios(config)
.then((response) => {
console.log(response)
this.car = response.data
// console.log(tableData)
})
.catch((err) => {
console.log(err)
})
}
},
created() {
this.handle(this.id)
}
created里的id要加上id哦(微笑)
父组件:将从后端获取到的id传给子组件
<template>
<div>
<el-collapse v-model="activeNames" >
<el-collapse-item
v-for="(item,index) in group"
:title="item.groupName">
<my-el-collapse-item
:id="item.id"
></my-el-collapse-item>
</el-collapse-item>
</el-collapse>
</div>
</template>