一、解决数据库字段和属性字段不一致问题
- 开启驼峰命名,这只能解决特定字段不一致问题,如aa_bb映射成aaBb属性;
- 起别名,别名的名称毫无疑问就是pojo类中属性名,使用了别名就解决了pojo属性和数据库字段的不一致问题,此时推荐使用resultType;
- 通过自定义resultMap,通过自己配置的形式解决了字段和属性字段不一致问题,参考案例如下;
二、处理复杂查询语句
前言:vo、po、do、dto的区别
- VO,View Object用途是接收前端提交的数据封装成VO类型,然后将后端程序封装成VO对象发送给了浏览器,由于VO需要经网络渲染到前端,所以需要序列化也就是实现serialable接口;
- PO,Persistant Object用途是将数据封装为PO存入数据库,再次数据库取出的数据封装为PO类型,所以PO和数据库表是一一对应的,典型的ORM思想;
- DO,Data Object从第三方或中间件中取出的数据,如redis,zookeeper
- DTO,Data Transform Object数据传输对象,用于Consumer和Provider的数据交互
这个问题就要追溯的Model数据模型层问题上,因为Model中尤其是VO(ViewObject)部分,这是开发中非常常用的一类Model,一个WEB页面,用一个VO对象对应整个界面的值,所以通过一个VO可能包含了多个PO,比如一个ProjectVO对象在一个WEB页面展现它全部的数据,但一个ProjectVO可能对应多项PO,如下,一个ProjectVO对应projectPo,typePO,tagPO,而每个po则是对应一张完整的数据表,这是我们要想办法"凑"出这三部分数据集。如下,我用了整整三个sql查询语句才"凑"齐这个VO数据,此类情况不是一个简单的resultType就能处理的。
案例
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ProjectVO {
private Integer id;
private String projectName;
private String projectDescription
private Integer money;
private Integer day;
private Integer leftDay;
private Integer status;
private String deploydate;
private MemberPO memberPO;
private List<TypePO> typePO;
private List<TagPO> tagPO;
}
<mapper namespace="com.wzh.atcrowdfunding.mapper.ProjectPOMapper">
<resultMap id="loadBasicProjectMap" type="com.wzh.atcrowdfunding.entity.project.ProjectVO">
<id column="id" property="id"/>
<result column="project_name" property="projectName"/>
<result column="project_description" property="projectDescription"/>
<result column="money" property="money"/>
<result column="day" property="day"/>
<result column="status" property="status"/>
<result column="deploydate" property="deploydate"/>
<association property="memberPO" column="memberid"
select="com.wzh.atcrowdfunding.mapper.ProjectPOMapper.selectMemberbyId"></association>
<collection property="tagPO" column="id" ofType="com.wzh.atcrowdfunding.entity.project.TagPO"
select="com.wzh.atcrowdfunding.mapper.ProjectPOMapper.selectTagsbyPid"></collection>
<collection property="typePO" column="id" ofType="com.wzh.atcrowdfunding.entity.project.TypePO"
select="com.wzh.atcrowdfunding.mapper.ProjectPOMapper.selectTypesbyPid"></collection>
</resultMap>
<select id="selectProjectByKeyword" resultMap="loadBasicProjectMap">
select * FROM t_project p join t_member m on p.memberid = m.id
WHERE
project_name like concat("%",#{keyword},"%") or
username like concat("%",#{keyword},"%")
</select>
三、总结
resultType:指定输出结果的类型(通过是现有的POJO类),将sql查询结果映射为对象,需要注意:sql查询的类名和resultType指定的pojo的属性名相同,指定相同的属性方可映射成功,如果sql查询的类名要和resultType指定的pojo属性名不全相同则会报错,通常需要使用起别名的方式来解决不一致问题,该结构不适合处理涉及到一对一,一对多的复杂场景
resultMap:将sql查询结果映射为Java对象,实际开发中往往都会写一个baseResultMap,这种需求常见于sql查询列名和最终要映射的pojo属性名不一致的情景,这时需要使用resultMap将列名和pojo的属性名做一个对应关系(列名和属性名映射配置)。面对复杂查询首先就要考虑resultMap,因为resultMap内有专门的标签association和collection来处理这种一对一,一对多的情况