数据库表的关系无非就四种:1、一对多(多对一),2、一对一,3、多对多,4、没有关系。其实面对数据表的多对多关系并没有那么复杂,那要看你怎么实现,传统的方法无非就是查询sql语句,而我要的是不通过自己写sql语句来达到查询出数据。这个我貌似不会,在网上找了太多资料,结果太让我失望了,不是要xml文件就是注解写sql,多对多的关系处理不清。想了好久,也碰到好多壁障,不过还是做出来了。
功能:通过中间表查询出与之关联的表的个别字段数据
传统方法(注解编写sql语句的方式)
- 表关系(歌单表、歌曲表、歌曲集合表(中间表))
一个歌单可以有多首歌曲,一首歌曲可以有多个歌单。
这是歌曲表:
这是歌单表:
这是中间表:
代码(注解sql语句方式)
- 创建一个实体类接收数据:
/**
* 歌单歌曲id
*/
private Integer id;
/**
* 歌曲id
*/
private Integer songId;
/**
* 歌单id
*/
private Integer songListId;
/*歌曲表*/
private Song song;
/*曲名*/
private String name;
/*歌单*/
private SongList songList;
/*歌单标题*/
private String title;
- dao层
@Select("select song.name,song_list.title from list_song inner join song on list_song.song_id=song.id\n" +
"join song_list on list_song.song_list_id=song_list.id where list_song.song_list_id=#{id} ")
List<ListSongUtils> selectsong(@Param("id")Integer id);
//sql语句我一般都是在数据库写好了再复制过来,这样可以降低sql语句出错的概率
//参数id是通过前端传过来的,是歌单id(根据歌单id查询歌单里的歌曲集合)
- service层
List<ListSongUtils> selectsong(@Param("id")Integer id);
- serviceImpl实现层
//引用dao层
@Autowired
ListSongMapper listSongMapper;
@Override
public List<ListSongUtils> selectsong(Integer id) {
//返回数据
return listSongMapper.selectsong(id);
}
- 测试-测试类
//引入service
@Autowired
ListSongService listSongService;
//这里直接调用方法
@Test
void test01() {
List<ListSongUtils> gg = listSongService.selectsong(1);
System.out.println(gg);
}
- 测试-controller
@RequestMapping("/jjjop")
public void ggkk(){
List<ListSongUtils>llmm =listSongService.selectsong(1);
System.out.println(llmm);
}
无sql语句查询
无sql语句查询就比较简单(我是说操作步骤)。要完成接下来的操作要导入mybatis-plus的依赖(因为我本来用的就是mybatis-plus)要导入依赖请跳往mybatis-plus官网
然后利用mybatis-plus service层继承IService
public interface ListSongService extends IService<ListSong> {
}
- 直接测试-测试类
@Autowired
ListSongService listSongService;
@Autowired
SongService songService;
@Test
void test02() {
//创建一个map容器
Map<String, Object> columnMap=new HashMap<>();
//给map容器中放值
columnMap.put("song_list_id",1);
//调用IService类中的方法listByMap(解析在下面)
//查询出中间表的数据
List<ListSong> gg = listSongService.listByMap(columnMap);
//创建一个list集合,集合的类型是:Integer
List<Integer>songids=new ArrayList<>();
for (int i=0; i<gg.size();i++){
//for循环个list集合中放值
//取值的对象查询中间表数据中的歌曲的id集合
songids.add(gg.get(i).getSongId());
}
//调用IService类中的方法listByIds(解析在下面)
List<Song> nn = songService.listByIds(songids);
//创建一个集合,集合里面装的是一个map容器
List<Map<Object,Object>> hh=new ArrayList<>();
//for循环往map里赋值在给到集合里,这里值的注意的是创建map的对象要在循环体里:
//因为如果在循环体外那么就相当只创建了一个map它的地址值不变,最后只会得到循环最后一位的值(即:得到多个一样的值)
for (int i=0; i<gg.size();i++){
Map<Object,Object> kk=new HashMap<>();
//给map放值
kk.put("id",gg.get(i).getId());
kk.put("name",nn.get(i).getName());
//给集合放值
hh.add(kk);
}
//输出
System.out.println(hh);
}
//IService类listByMap方法解析:
//在创建一个map容器后给容器赋值:columnMap.put("song_list_id",1),前面song_list_id是数据库字段名,后面的1是字段名的值。具体使用方法可去mybatis-plus官网查询
//IService类listByIds方法解析:是根据主键id的集合批量查询数据
//
- 测试-controller
@GetMapping("/selectListsong")
public List<Map<Object,Object>> selectListsong(@RequestParam("id") Integer id){
//根据表字段查询数据
Map<String, Object> columnMap=new HashMap<>();
columnMap.put("song_list_id",id);
List<ListSong> gg = listSongService.listByMap(columnMap);
//创建一个集合,通过for循环取出ListSong表中歌曲的id
List<Integer>songids=new ArrayList<>();
for (int i=0; i<gg.size();i++){
songids.add(gg.get(i).getSongId());
}
//通过id的集合查询数据数据
List<Song> nn = songService.listByIds(songids);
List<Map<Object,Object>> hh=new ArrayList<>();
for (int i=0; i<gg.size();i++){
Map<Object,Object> kk=new HashMap<>();
kk.put("id",gg.get(i).getId());
kk.put("name",nn.get(i).getName());
hh.add(kk);
}
return hh;
}
//注解我就不写了,跟测试类的一样