在电影信息管理中,由于一个电影对应多个电影类型,然后一个电影类型对应多个电影,这样就造成了多对多级联,这个emmmmm。
首先说的是关于查询,并进行显示。
先看实体类
public class Film
{
private Integer id; // 编号
private String name; // 电影名称
private String englishName; // 英文名称
private String cover; // 封面图片
private Integer duration; // 电影时长(单位:分钟)
private Integer box; // 票房
private Float score; // 豆瓣得分
private String resume; // 电影描述
private int isHot; // 是否热门
private int clickHit; // 点击次数
private Date publishDate; // 上映日期
private Employee employee; // 导演
private List<FilmType> filmTypes; // 电影类型
private List<Employee> employees; // 雇员(演员)
private List<Picture> pictures; // 图集
// 项目开发中,不需要对应数据库的字段
private List<Perform> performs;
...//省略getset方法
}
public class FilmType
{
private Integer id; // 编号
private String typeName; // 类型名称
private List<Film> films; // 对应电影
}
其所对应的数据表t_film 和t_filmtype结构如下、
t_film
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | YES | | NULL | |
| englishName | varchar(50) | YES | | NULL | |
| cover | varchar(100) | YES | | NULL | |
| duration | int(11) | YES | | NULL | |
| box | int(11) | YES | | NULL | |
| score | float(11,1) | YES | | NULL | |
| resume | text | YES | | NULL | |
| isHot | int(11) | YES | | NULL | |
| clickHit | int(11) | YES | | NULL | |
| employeeId | int(11) | YES | | NULL | |
| publishDate | datetime | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| typeName | varchar(255) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
为了方便操作,在数据库中建立了中间表t_film_filmtype,其结构如下。
+------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| filmId | int(11) | NO | | NULL | |
| filmTypeId | int(11) | NO | | NULL | |
+------------+---------+------+-----+---------+----------------+
在controller层中进行查找
@RequestMapping("/list")
public String list(@RequestParam(value="page",required=false)String page,@RequestParam(value="rows",required=false)String rows,HttpServletResponse response) throws Exception
{
PageBean pageBean = new PageBean(Integer.parseInt(page),Integer.parseInt(rows));
Map<String,Object> map = new HashMap<String,Object>();
map.put("start", pageBean.getStart());
map.put("size", pageBean.getPageSize());
Long total = filmService.count(map);
List<Film> filmList = filmService.find(map);
for(Film temp:filmList)
{
// 过滤掉电影类型中的电影属性
List<FilmType> filmTypes = temp.getFilmTypes();
for(FilmType type:filmTypes)
{
type.setFilms(null);
}
temp.setFilmTypes(filmTypes);
// 过滤掉导演类型中的电影属性
Employee employee = temp.getEmployee();
employee.setFilms(null);
temp.setEmployee(employee);
}
JSONObject result = new JSONObject();
JsonConfig jsonConfig=new JsonConfig();
jsonConfig.setExcludes(new String[] {"employees","pictures"});
jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd"));
JSONArray jsonArray = JSONArray.fromObject(filmList,jsonConfig);
result.put("rows", jsonArray);
result.put("total", total);
ResponseUtil.write(response, result);
return null;
}
要将Film中的属性进行过滤的原因是,虽然mybatis中多对多不会产生死循环,但是所传递的json数组会产生死循环。
要将film中的filmtype集合所对应的film集合都置为null。并且要过滤掉所有含有film集合的集合(例如emloyee)。
现在来看一下在mapper中如何进行SQL语句的书写
<select id="find" parameterType="Map" resultMap="FilmResult">
select * from t_film
<where>
<if test="typeId != null and typeId != 0">
and id in (select filmId from t_film_filmtype where filmTypeId = #{typeId})
</if>
</where>
</select>
前端用的是easyUI框架进行,显示film信息的方式如下
<thead data-options="frozen:true">
<tr>
<th field="cb" width="30" checkbox="true" align="center"></th>
<th field="id" width="50" align="center">编号</th>
<th field="name" width="200" align="center">电影名称</th>
<th field="englishName" width="200" align="center">英文名称</th>
<th field="cover" width="150" align="center" formatter="formatCover">封面图片</th>
<th field="resume" width="250" align="center">描述</th>
<th field="filmType" width="100" align="center" formatter="fromatFilmType">电影类型</th>
</tr>
</thead>
在显示电影类型时所用的js方法如下,将后台所传入的数据进行拼接,以逗号分开,进行显示。
function fromatFilmType(val,row)
{
var types = row.filmTypes;
var result = "";
for(var i=0;i<types.length;i++)
{
if(i == 0)
{
result = result + types[i].typeName;
}
else
{
result = result + "," + types[i].typeName;
}
}
return result;
}
这样就完成了mybatis多对多的查询