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