Vue+axios+Element UI+SpringBoot+Spring Data JPA实现分组查看

今天从中午弄到晚上九点多就一直在纠结,到底是经验不够,哎

一 后端

要实现的是找出所有分组及每个分组下的所有车辆

(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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章