MyBatis 之识别器
作者:andy
- 2022-10-27 北京
本文字数:2913 字
阅读完需:约 10 分钟
一、多表重复字段的问题
在数据库设计中,会出现多个不同的事物之间有相同的信息。书礼物表中存在有名称、描述、作者,而纪念品礼物表中存在有名称、描述、产地。其中,名称和描述都是两个表共有的属性信息,而只不过书礼物表有作者,纪念品礼物表有产地。那么,对于这样的情况,该如何合理设计数据库表呢?这个问题暂时留着,本文章主要阐述的不是这一个问题。
书礼物表:
create table giftbook( gid int auto_increment, name varchar(30) not null, description varchar(255), author varchar(30), constraint pk_gid primary key(gid))engine InnoDB;复制代码
纪念品礼物表:
create table giftsouvenir( gid int auto_increment, name varchar(30) not null, description varchar(255), origin varchar(255), constraint pk_gid primary key(gid))engine InnoDB;复制代码
二、MyBatis 识别器的引入
实际上,一旦类似的事物不断增加。那么,就要不断建立新表。因此,可以建立一张表,通过标志位判断各自存储的内容即可。
礼物表:
create table gift( gid int auto_increment, name varchar(30) not null, description varchar(255), cost double, flag varchar(30) not null, author varchar(30), origin varchar(255), constraint pk_gid primary key(gid))engine InnoDB;复制代码
在项目开发中,需要将数据库数据转化为 VO 对象。那么,我们仍然不可能去建立多个 VO,让后编写重复字段。因此,可以建立 Gift 父类,把共同属性和标志位的属性添加上,剩下的 GiftBook 和 GiftSouvenir 子类继承父类,再各自增加属于自己的属性。
Gift 父类:
package org.fuys.owndb.vo;import java.io.Serializable;@SuppressWarnings("serial")public class Gift implements Serializable { private Integer gid; private String name; private String description; private Double cost; private String flag;}复制代码
package org.fuys.owndb.vo;import java.io.Serializable;@SuppressWarnings("serial")public class GiftBook extends Gift implements Serializable { private String author;}复制代码
GiftSouvenir 子类:
package org.fuys.owndb.vo;import java.io.Serializable;@SuppressWarnings("serial")public class GiftBook extends Gift implements Serializable { private String author;}复制代码
那么,建立好基础类之后,需要在核心内容配置文件中添加类的别人,以便引用。
<typeAliases> <typeAlias type="org.fuys.owndb.vo.Gift" alias="Gift"/> <typeAlias type="org.fuys.owndb.vo.GiftBook" alias="GiftBook"/> <typeAlias type="org.fuys.owndb.vo.GiftSouvenir" alias="GiftSouvenir"/> </typeAliases>复制代码
随后添加映射文件。
<mappers> <mapper resource="org/fuys/owndb/vo/mapping/Gift.xml"/> </mappers>复制代码
在映射文件中,配置信息,但是需要注意的是:resultMap 的编写,添加识别器 discriminator。
Gift.xml 文件:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="org.fuys.owndb.vo.mapping.Gift"> <resultMap type="Gift" id="GiftResultMap"> <id column="gid" property="gid" /> <result column="name" property="name" /> <result column="description" property="description" /> <result column="cost" property="cost" /> <discriminator javaType="java.lang.String" column="flag"> <case value="book" resultType="GiftBook"> <result column="author" property="author" /> </case> <case value="souvenir" resultType="GiftSouvenir"> <result column="origin" property="origin" /> </case> </discriminator> </resultMap> <insert id="insertGiftBook" parameterType="GiftBook" keyProperty="gid" useGeneratedKeys="true"> INSERT INTO gift(name,description,cost,flag,author) VALUES(#{name},#{description},#{cost},"book",#{author}) </insert> <select id="selectGiftBookList" parameterType="GiftBook" resultMap="GiftResultMap"> SELECT gid,name,description,cost,flag,author,origin FROM gift <where> <if test="gid !=null"> and gid = #{gid} </if> <if test="name !=null"> and name LIKE CONCAT(CONCAT("%",#{name}),"%") </if> <if test="description !=null"> and description LIKE CONCAT(CONCAT("%",#{description}),"%") </if> <if test="cost !=null"> and cost = #{cost} </if> <if test="flag !=null"> and flag = #{flag} </if> </where> </select></mapper>复制代码
测试程序:
package org.fuys.owndb.test;import java.util.List;import java.util.Random;import org.fuys.owndb.model.MyBatisSqlSessionFactory;import org.fuys.owndb.vo.Gift;import org.fuys.owndb.vo.GiftBook;import org.fuys.owndb.vo.GiftSouvenir;import org.junit.Test;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import junit.framework.TestCase;public class TestDiscriminator { private Logger logger = LoggerFactory.getLogger(TestDiscriminator.class); @Test public void testInsert() { GiftBook book = new GiftBook(); book.setName("zero to one " + new Random().nextInt(99)); book.setDescription("It's about company."); book.setCost(79.4); book.setFlag("book"); book.setAuthor("Peter Thiel"); int lenA = MyBatisSqlSessionFactory.getSqlSession().insert("org.fuys.owndb.vo.mapping.Gift.insertGiftBook", book); MyBatisSqlSessionFactory.getSqlSession().commit(); TestCase.assertEquals(lenA, 1); logger.info(String.valueOf(lenA)); logger.info(book.toString()); } @Test public void testSelectList() { GiftBook book = new GiftBook(); book.setAuthor("Peter Thiel"); List<GiftBook> bookList = MyBatisSqlSessionFactory.getSqlSession().selectList("org.fuys.owndb.vo.mapping.Gift.selectGiftBookList", book); TestCase.assertNotNull(bookList); for(int x=0;x<bookList.size();x++){ Gift gift = bookList.get(x); if(gift instanceof Gift){ logger.info("gift --> " + x); } if(gift instanceof GiftBook){ logger.info("giftBook --> " + x); } if(gift instanceof GiftSouvenir){ logger.info("giftSouvenir --> " + x); } } logger.info(bookList.toString()); }}复制代码
发现:
程序验证之后,发现一个问题,对于查询 GiftBook 数据,我将所有的 Gift 数据全部查询出来,在 GiftBook 集合中,竟然包含 GiftSouvenir 对象的数据,这一点非常厉害,但是也引起疑问,不同类型的同级类,竟然能够互相存储。
划线
评论
复制
发布于: 刚刚阅读数: 3
andy
关注
还未添加个人签名 2019-11-21 加入
还未添加个人简介









评论