向xml低头,没错,我向xml低头了。
前文:
用户,角色,资源,联合查询(使用注解SQL)
注解sql的那种provider的文件格式,可能真的不是mybatis主推的模式,场景欠缺的很多,而当你硬把改场景用这种方式实现时,反倒不优雅了。还是回归传统吧,或许这就是xml这么多年屹立不倒的秘诀。
开始开始。
一段时间不见,gemini的表结构被我改了改,结合各种方面优化考虑,现在的他们是这样的。
用户表:
CREATE TABLE `g_user` (
`id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`user_id` bigint(32) NOT NULL COMMENT '用户编号(业务id)',
`identity_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '账号',
`nick_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '昵称',
`phone` varchar(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系方式',
`email` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '邮箱',
`password` varchar(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '密码',
`lock` tinyint(1) DEFAULT '0' COMMENT '是否锁定',
`create_user_id` bigint(32) DEFAULT NULL COMMENT '创建人id',
`update_user_id` bigint(32) DEFAULT NULL COMMENT '更新人id',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`rev` tinyint(8) DEFAULT '1' COMMENT '版本号',
`delete_flag` tinyint(1) DEFAULT '0' COMMENT '删除标记',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
角色表:
CREATE TABLE `g_role` (
`id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`role_id` bigint(32) NOT NULL COMMENT '角色id',
`role_code` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色编码',
`role_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色名称',
`create_user_id` bigint(32) DEFAULT NULL COMMENT '创建人id',
`update_user_id` bigint(32) DEFAULT NULL COMMENT '更新人id',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`rev` tinyint(8) DEFAULT '1' COMMENT '版本号',
`delete_flag` tinyint(1) DEFAULT '0' COMMENT '删除标记',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
用户角色表:
CREATE TABLE `g_user_role` (
`id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`role_id` bigint(32) NOT NULL COMMENT '角色编码',
`user_id` bigint(32) NOT NULL COMMENT '用户编码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
资源表:
CREATE TABLE `g_resource` (
`id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`resource_id` bigint(32) NOT NULL COMMENT '资源id',
`resource_code` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '资源编码',
`resource_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '资源名称',
`create_user_id` int(32) DEFAULT NULL COMMENT '创建人id',
`update_user_id` int(32) DEFAULT NULL COMMENT '更新人id',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`rev` tinyint(8) DEFAULT '1' COMMENT '版本号',
`delete_flag` tinyint(1) DEFAULT '0' COMMENT '删除标记',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
角色资源表:
CREATE TABLE `g_res_role` (
`id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`role_id` bigint(32) NOT NULL COMMENT '角色id',
`resource_id` bigint(32) NOT NULL COMMENT '资源id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
总体模式同过去没有区别,只是加了一些字段,改了一些名字,变化了一些规则。
首先,过去我的表主键都是自增id,但我在映射关系中,也是使用的自增id,其实是不科学的。过去也不是没想到给它一个主键自增id,一个业务id,一个编码,一个名字。所有的业务表都这么设计的模式。只是觉得有必要吗?但是实际的项目探索之后,其实还是很有必要的。粒度越细,其实可变化性就越多,分工也越明确。只是略有复杂需要处理,具体还是看个人和项目吧。总之我改成了现在的这样。
开始切入正题。
我们现在需求的返回格式同过去一般无二。
1、用户信息中带角色列表,角色列表中再带资源列表。
2、用户信息中直接带角色列表与资源列表。
对于vo文件我也没有怎么改动。除了字段更名和添加字段以外,格式,模式,基本同过去一致。
主要看xml。
其实本质是类似的。还是使用resultMap进行调控。
只是在注解sql中,用的是many=@Many()
这样的格式,在这里使用的就是collection
标签。需要注意的是,所有的关联字段(column
)都必须显式地被写出来,也就是不能依赖通配符(*
)的查询结果。
直接贴图吧。
资源持久化类
ResourceMapper.java:
public interface ResourceMapper {
/**
* 根据roleId获取资源信息
*/
List selectByRoleId(Long roleId);
}
ResourceMapper.xml
很简单,只是普通的根据角色资源映射表查询资源信息。
接下来看角色
角色持久化类
RoleMapper.java
public interface RoleMapper {
/**根据userId获取所有角色信息*/
List selectByUserId(Long userId);
}
RoleMapper.xml
<注意:这里的关联字段是role_id,因此在下面的sql中就显式地把它查了出来。>
用户映射类
userMapper.java:
public interface UserMapper {
/**根据身份编码获取所有信息*/
UserInfoVo selectByIdentityCode(String identityCode);
}
userMapper.xml:
<注意:这里的关联字段是user_id,因此在下面的sql中就显式地把它查了出来。>
关联字段是什么呢?就是两个sql关联在一起的那个共同的字段。所以在写关联查询的时候,一定一定要注意的事,关联字段一定要作为B的条件。
end