这是课设制作总结的第四篇,目前仍旧奋战在持久层。前面三节分析了项目需求、编写了持久层mapper接口、实现了部分mapper接口的配置文件及测试。
这一节就来继续将剩下的mapper文件配置并测试完。
有关项目背景和model类设计可以查看第一节:【从零开始JavaEE课设】《影院系统》(一) 需求分析 数据库设计 后端model类
model层类涉及到的不多,仅有七个类且类间关系比较简单明确:
resultMap真的是一大神器,可以在其中清晰的表达类之间的对应包含关系,非常的方便。
对于这个项目来说,目前主要用到它来解决一对一和一对多关系。
在resultMap中使用association标签可以映射一对一的包含关系
例如,在放映计划中,一个放映计划关联了一个电影和一个房间,是两个一对一关系。
放映计划对应的resultMap:
<resultMap type="screeningPlan" id="planMap">
<id column="spId" property="id"/>
<result column="price" property="price"/>
<result column="planTime" property="time"/>
<result column="planDate" property="date"/>
<association property="room" javaType="room">
<id column="rId" property="id"/>
<result column="seat" property="seat"/>
<result column="roomName" property="name"/>
<result column="type" property="type"/>
association>
<association property="film" javaType="film" resultMap="com.none.mapper.FilmMapper.filmMap">association>
resultMap>
这个例子同时展示了如何使用已经映射好的map。对于关联关系一层一层传递的关系编写非常的友好。
映射在FilmMapper中的film:
<resultMap type="film" id="filmMap">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="director" property="director"/>
<result column="country" property="country"/>
<result column="length" property="length"/>
<result column="release_time" property="releaseTime"/>
<result column="offline_time" property="offlineTime"/>
<result column="language" property="language"/>
<result column="introduction" property="introduction"/>
<collection property="post" javaType="list" ofType="filmPost">
<id column="pid" property="id"/>
<result column="film_Id" property="filmId"/>
<result column="dir" property="dir"/>
collection>
resultMap>
这里面又提到了如何进行一对多映射,电影和电影海报的关系就是一对多。这需要用到集合(collection)这个标签进行配置。
其中有三个常用属性:
另外,查询一对多关系时映射记得使用外联结,左右联结皆可,使用内联结可能会丢失一部分数据,mybatis会帮助我们自动将同一个主表内容映射成为一个同对象。
例如,查询所有的电影及其对应的海报对象,联结时的语句:
film LEFT OUTER JOIN film_post ON film.id = film_post.film_id
当WHERE
条件需要使用到IN
判断时,往往需要传递一个集合作为参数。
这时需要使用到foreach
标签进行处理
例如,查询一些电影对应的记录
mapper方法:
/*查询影片记录*/
public List<Record> selectByFilms(@Param("films") List<Film> films);
mapper文件:
<select id="selectByFilms" resultMap="recordMap">
<include refid="select">include>
WHERE film.id IN
<foreach collection="films" index="index" item="film" open="(" separator="," close=")">
#{film.id}
foreach>
;
select>
这里需要这几个参数:
@Param
注解则这里应该写注解中的映射名可以使用sql
标签封装常用的sql片段,并在sql语句中使用include
标签引用这些片段;
例如,需要查出的字段及其别名可以使用sql
封装,并可以在具有嵌套结构时调用已经封装好的sql片段
例如,将相互联结的表的联结封装在一个sql片段中,编写select语句时就不需要表述千篇一律地表述表间的联结关系
如一个上映计划需要聚合一个电影和一个影厅,所以查询时需要将计划表联结电影表及影厅表:
<sql id="allContent">
plan.id spId,plan.price price,plan.time planTime,plan.date planDate,
room.id rId,room.seat seat,room.name roomName,room.type type,
film.id fId,film.name filmName,film.director director,film.country country,film.length length,film.release_time release_time,film.offline_time offline_time,film.language language,film.introduction introduction,
film_post.id pid,film_post.dir dir,film_post.film_id film_id
sql>
<sql id="join">
screening_plan plan JOIN film ON plan.film_id = film.id
JOIN room ON room.id = plan.room_id
LEFT JOIN film_post ON film_post.film_id = film.id
sql>
又如,一个购票记录需要组合一个放映计划:
<sql id="allContent">
record.id reId,record.money reMoney,record.time reTime,record.code code,record.phone phone,record.seat_id seatId,
<include refid="com.none.mapper.ScreeningPlanMapper.allContent">include>
sql>
<sql id="join">
record JOIN
<include refid="com.none.mapper.ScreeningPlanMapper.join">include>
ON record.plan_id = plan.id
sql>
<mapper namespace="com.none.mapper.RecordMapper">
<sql id="allContent">
record.id reId,record.money reMoney,record.time reTime,record.code code,record.phone phone,record.seat_id seatId,
<include refid="com.none.mapper.ScreeningPlanMapper.allContent">include>
sql>
<sql id="noId">
money,time,code,phone,plan_id,seat_id
sql>
<sql id="join">
record JOIN
<include refid="com.none.mapper.ScreeningPlanMapper.join">include>
ON record.plan_id = plan.id
sql>
<sql id="select">
SELECT
<include refid="allContent">include>
FROM
<include refid="join">include>
sql>
<resultMap type="record" id="recordMap">
<id column="reId" property="id"/>
<result column="reMoney" property="money"/>
<result column="reTime" property="time"/>
<result column="code" property="code"/>
<result column="phone" property="phone"/>
<result column="seatId" property="seatId"/>
<association property="plan" resultMap="com.none.mapper.ScreeningPlanMapper.planMap">association>
resultMap>
<insert id="insertRecord" parameterType="record">
INSERT INTO record
(<include refid="noId">include>)
VALUE
(#{money},#{time},#{code},#{phone},#{plan.id},#{seatId});
insert>
<delete id="deleteById" parameterType="int">
DELETE FROM record WHERE id = #{value};
delete>
<update id="updateRecord" parameterType="record">
UPDATE record
<set>
<if test="#{plan.id} != null">
plan_id = #{plan.id},
if>
<if test="#{money} != null">
money = #{money},
if>
<if test="#{time} != null">
time = #{time},
if>
<if test="#{phone} != null">
phone = #{phone},
if>
<if test="#{seatId} != null">
seat_id = #{seatId},
if>
<if test="#{code} != null">
code = #{code},
if>
set>
WHERE id = #{id};
update>
<select id="selectAll" resultMap="recordMap">
<include refid="select">include>
;
select>
<select id="selectByPhone" resultMap="recordMap" parameterType="string">
<include refid="select">include>
WHERE record.phone = #{value};
select>
<select id="selectByTime" resultMap="recordMap">
<include refid="select">include>
WHERE record.time BETWEEN #{begin} AND #{end};
select>
<select id="selectByFilms" resultMap="recordMap">
<include refid="select">include>
WHERE film.id IN
<foreach collection="films" index="index" item="film" open="(" separator="," close=")">
#{film.id}
foreach>
;
select>
<select id="selectByRooms" resultMap="recordMap">
<include refid="select">include>
WHERE room.id IN
<foreach collection="rooms" index="index" item="room" open="(" separator="," close=")">
#{room.id}
foreach>
;
select>
<select id="selectByRoomsAndFilms" resultMap="recordMap">
<include refid="select">include>
WHERE room.id IN
<foreach collection="rooms" index="index" item="room" open="(" separator="," close=")">
#{room.id}
foreach>
AND film.id IN
<foreach collection="films" index="index" item="film" open="(" separator="," close=")">
#{film.id}
foreach>
select>
mapper>
<mapper namespace="com.none.mapper.ScreeningPlanMapper">
<resultMap type="screeningPlan" id="planMap">
<id column="spId" property="id"/>
<result column="price" property="price"/>
<result column="planTime" property="time"/>
<result column="planDate" property="date"/>
<association property="room" javaType="room">
<id column="rId" property="id"/>
<result column="seat" property="seat"/>
<result column="roomName" property="name"/>
<result column="type" property="type"/>
association>
<association property="film" javaType="film" resultMap="com.none.mapper.FilmMapper.filmMap">association>
resultMap>
<sql id="allContent">
plan.id spId,plan.price price,plan.time planTime,plan.date planDate,
room.id rId,room.seat seat,room.name roomName,room.type type,
film.id fId,film.name filmName,film.director director,film.country country,film.length length,film.release_time release_time,film.offline_time offline_time,film.language language,film.introduction introduction,
film_post.id pid,film_post.dir dir,film_post.film_id film_id
sql>
<sql id="join">
screening_plan plan JOIN film ON plan.film_id = film.id
JOIN room ON room.id = plan.room_id
LEFT JOIN film_post ON film_post.film_id = film.id
sql>
<sql id="noId">
price,time,date,room_id,film_id
sql>
<insert id="insertPlan">
INSERT INTO screening_plan
(<include refid="noId">include>)
VALUE
(#{price},#{time},#{date},#{room.id},#{film.id});
insert>
<update id="updatePlan">
UPDATE screening_plan
<set>
<if test="#{price} != null">
price = #{price},
if>
<if test="#{time} != null">
time = #{time},
if>
<if test="#{date} != null">
date = #{date},
if>
<if test="#{room.id} != null">
room_id = #{room.id},
if>
<if test="#{film.id} != null">
film_id = #{film.id},
if>
set>
WHERE id = #{id};
update>
<delete id="deleteById">
DELETE FROM screening_plan WHERE id = #{value};
delete>
<select id="selectNearby" resultMap="planMap">
SELECT
<include refid="allContent">include>
FROM
<include refid="join">include>
WHERE
plan.date BETWEEN #{nowDate} AND #{endDate}
AND
plan.time BETWEEN #{nowTime} AND #{endTime};
select>
<select id="selectPlans" resultMap="planMap">
SELECT
<include refid="allContent">include>
FROM
<include refid="join">include>
WHERE
plan.film_id = #{film.id}
AND
plan.date = #{date}
AND
plan.time >= #{time};
select>
<select id="selectById" resultMap="planMap">
SELECT
<include refid="allContent">include>
FROM
<include refid="join">include>
WHERE plan.id = #{value};
select>
mapper>
<mapper namespace="com.none.mapper.StaffMapper">
<sql id="content">
id,name,id_card idCard,password
sql>
<select id="selectByIdCard" parameterType="String" resultType="staff">
SELECT
<include refid="content">include>
FROM staff
WHERE id_card = #{value};
select>
mapper>
<mapper namespace="com.none.mapper.VipMapper">
<sql id="noId">
code,discount,money,password,phone,name,birthday,due_time
sql>
<sql id="content">
id,
<include refid="noId">include>
sql>
<sql id="value">
#{code},#{discount},#{money},#{password},#{phone},#{name},#{birthday},#{dueTime}
sql>
<insert id="insertVip" parameterType="vip">
INSERT INTO vip
(<include refid="noId">include>)
VALUE
(<include refid="value">include>);
insert>
<delete id="deleteById" parameterType="int">
DELETE FROM vip WHERE id = #{value};
delete>
<update id="updateVip" parameterType="vip">
UPDATE vip
<set>
<if test="#{name} != null">
name = #{name},
if>
<if test="#{birthday} != null">
birthday = #{birthday},
if>
<if test="#{dueTime} != null">
due_time = #{dueTime},
if>
<if test="#{password} != null">
password = #{password},
if>
<if test="#{phone} != null">
phone = #{phone},
if>
<if test="#{code} != null">
code = #{code},
if>
<if test="#{discount} != null">
discount = #{discount},
if>
<if test="#{money} != null">
money = #{money},
if>
set>
WHERE id = #{id};
update>
<select id="selectVip" resultType="vip" parameterType="string">
SELECT
<include refid="content">include>
FROM vip WHERE
code = #{value}
OR
phone = #{value};
select>
mapper>
其他的mapper和对应测试代码在上一篇:
【从零开始JavaEE课设】《影院系统》(三)配置mybatis框架,编写mapper文件并测试(附mybatis知识点)
package com.none.tests;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.none.mapper.FilmMapper;
import com.none.mapper.RecordMapper;
import com.none.mapper.RoomMapper;
import com.none.mapper.ScreeningPlanMapper;
import com.none.model.Film;
import com.none.model.Record;
import com.none.model.ScreeningPlan;
import com.none.util.DateUtil;
import com.none.util.MapperUtil;
public class RecordTest {
RecordMapper mapper = (RecordMapper) MapperUtil.getMapper(RecordMapper.class);
ScreeningPlanMapper sm = (ScreeningPlanMapper) MapperUtil.getMapper(ScreeningPlanMapper.class);
FilmMapper fm = (FilmMapper) MapperUtil.getMapper(FilmMapper.class);
RoomMapper rm = (RoomMapper) MapperUtil.getMapper(RoomMapper.class);
@Test
public void insert()
{
ScreeningPlan plan = sm.selectById(2);
Record record = new Record();
record.setPlan(plan);
record.setCode("67987");
record.setMoney(35);
record.setSeatId(33);
record.setPhone("10086");
record.setTime(DateUtil.getCurrentDateTime());
mapper.insertRecord(record);
MapperUtil.commit();
}
@Test
public void delete()
{
mapper.deleteById(5);
MapperUtil.commit();
}
@Test
public void update()
{
ScreeningPlan plan = sm.selectById(2);
Record record = new Record();
record.setPlan(plan);
record.setCode("67987");
record.setMoney(35);
record.setSeatId(33);
record.setPhone("10010");
record.setTime(DateUtil.getCurrentDateTime());
record.setId(6);
mapper.updateRecord(record);
MapperUtil.commit();
}
@Test
public void selectAll()
{
List<Record> list = mapper.selectAll();
for(Record r: list)
{
System.out.println(r);
}
}
@Test
public void selectByNumber()
{
System.out.println(mapper.selectByPhone("10010"));
}
@Test
public void selectByTime()
{
System.out.println(mapper.selectByTime("2020-01-01 00:00:00", DateUtil.getCurrentDateTime()));
}
@Test
public void selectList()
{
//System.out.println(fm.selectOnLine(DateUtil.getCurrentDate()));
//List list = mapper.selectByFilms(fm.selectByName("穿越"));
List<Record> list = mapper.selectByRoomsAndFilms(rm.selectByName("测试厅1"),fm.selectByName("星际穿越"));
for(Record r : list)
{
System.out.println(r);
}
}
}
package com.none.tests;
import java.util.List;
import org.junit.Test;
import com.none.mapper.FilmMapper;
import com.none.mapper.RoomMapper;
import com.none.mapper.ScreeningPlanMapper;
import com.none.model.Film;
import com.none.model.Room;
import com.none.model.ScreeningPlan;
import com.none.util.DateUtil;
import com.none.util.MapperUtil;
public class ScreeningPlanTest {
ScreeningPlanMapper mapper = (ScreeningPlanMapper) MapperUtil.getMapper(ScreeningPlanMapper.class);
RoomMapper rm = (RoomMapper) MapperUtil.getMapper(RoomMapper.class);
FilmMapper fm = (FilmMapper) MapperUtil.getMapper(FilmMapper.class);
@Test
public void insert()
{
Room room = rm.selectByName("测试").get(0);
Film film = fm.selectByName("哪吒").get(0);
ScreeningPlan plan = new ScreeningPlan();
plan.setTime("15:30:00");
plan.setDate("2020-06-25");
plan.setPrice(50);
plan.setFilm(film);
plan.setRoom(room);
mapper.insertPlan(plan);
MapperUtil.commit();
}
@Test
public void update()
{
Room room = rm.selectByName("测试").get(0);
Film film = fm.selectByName("哪吒").get(0);
ScreeningPlan plan = new ScreeningPlan();
plan.setTime("15:30:00");
plan.setDate("2020-06-25");
plan.setPrice(25);
plan.setFilm(film);
plan.setRoom(room);
plan.setId(4);
mapper.updatePlan(plan);
MapperUtil.commit();
}
@Test
public void delete()
{
mapper.deleteById(4);
MapperUtil.commit();
}
@Test
public void selectNear()
{
List<ScreeningPlan> list = mapper.selectNearby(DateUtil.getCurrentTime(), "23:59:59", DateUtil.getCurrentDate(), "2020-07-20");
for(ScreeningPlan p : list)
{
System.out.println(p);
}
}
@Test
public void selectPlan() {
Film film = fm.selectByName("穿越").get(0);
List<ScreeningPlan> list = mapper.selectPlans(film, "2020-06-25", "00:00:00");
for(ScreeningPlan p : list)
{
System.out.println(p);
}
}
@Test
public void selectOne()
{
ScreeningPlan plan = mapper.selectById(2);
System.out.println(plan);
}
}
package com.none.tests;
import org.junit.Test;
import com.none.mapper.StaffMapper;
import com.none.util.MapperUtil;
public class StaffTest {
StaffMapper mapper = (StaffMapper) MapperUtil.getMapper(StaffMapper.class);
@Test
public void select() {
System.out.println(mapper.selectByIdCard("123456789"));
}
}
package com.none.tests;
import org.junit.Test;
import com.none.mapper.VipMapper;
import com.none.model.Vip;
import com.none.util.MapperUtil;
public class VipTest {
VipMapper mapper = (VipMapper) MapperUtil.getMapper(VipMapper.class);
@Test
public void insert()
{
Vip vip = new Vip();
vip.setBirthday("2001-06-02");
vip.setCode("987654321");
vip.setDiscount(0.5);
vip.setDueTime("9999-12-31");
vip.setMoney(99999);
vip.setPassword("123456");
vip.setPhone("1333333333333");
vip.setName("张三");
mapper.insertVip(vip);
MapperUtil.commit();
}
@Test
public void update()
{
Vip vip = new Vip();
vip.setBirthday("2001-06-02");
vip.setCode("123456789");
vip.setDiscount(0.5);
vip.setDueTime("9999-12-31");
vip.setMoney(99999);
vip.setPassword("123456");
vip.setPhone("15555555555");
vip.setName("李四");
vip.setId(1);
mapper.updateVip(vip);
MapperUtil.commit();
}
@Test
public void delete()
{
mapper.deleteById(3);
MapperUtil.commit();
}
@Test
public void select()
{
System.out.println(mapper.selectVip("123456789"));
}
}
前面几节