MyBatis系列(二):MyBatisXML方式的基本用法之Select
MyBatis系列(⼆):MyBatisXML⽅式的基本⽤法之Select 1. 明确需求
书中提到的需求是⼀个基于⾓⾊的权限控制需求(RBAC,即Role-Based Access Control),提到权限管理,相信⼤家都不陌⽣,因为⼤部分的系统都是需要权限管理的,我在上家公司负责的系统之⼀就是权限系统,设计思路和书中提到的差不多,⼤致描述如下:
1)权限点⽤来管理要控制权限的资源,⽐如某个页⾯,某个按钮。
2)创建⼀个⾓⾊,给这个⾓⾊分配某些权限点,⽐如商品模块的所有页⾯的权限。
3)新建⼀个⽤户,给这个⽤户分配某些⾓⾊。
数据关系图如下所⽰:
2. 数据准备
⾸先执⾏如下脚本创建上图中的5张表:⽤户表,⾓⾊表,权限表,⽤户⾓⾊关联表,⾓⾊权限关联表。
CREATE TABLE sys_user
(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '⽤户ID',
user_name VARCHAR(50) COMMENT '⽤户名',
user_password VARCHAR(50) COMMENT '密码',
user_email VARCHAR(50) COMMENT '邮箱',
user_info TEXT COMMENT '简介',
head_img BLOB COMMENT '头像',
create_time DATETIME COMMENT '创建时间',
PRIMARY KEY (id)
);
ALTER TABLE sys_user COMMENT '⽤户表';
CREATE TABLE sys_role
(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '⾓⾊ID',
role_name VARCHAR(50) COMMENT '⾓⾊名',
enabled INT COMMENT '有效标志',
create_by BIGINT COMMENT '创建⼈',
create_time DATETIME COMMENT '创建时间',
PRIMARY KEY (id)
);
ALTER TABLE sys_role COMMENT '⾓⾊表';
CREATE TABLE sys_privilege
(
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '权限ID',
privilege_name VARCHAR(50) COMMENT '权限名称',
privilege_url VARCHAR(200) COMMENT '权限URL',
PRIMARY KEY (id)
);
ALTER TABLE sys_privilege COMMENT '权限表';
CREATE TABLE sys_user_role
(
user_id BIGINT COMMENT '⽤户ID',
role_id BIGINT COMMENT '⾓⾊ID'
);
ALTER TABLE sys_user_role COMMENT '⽤户⾓⾊关联表';
CREATE TABLE sys_role_privilege
(
role_id BIGINT COMMENT '⾓⾊ID',
privilege_id BIGINT COMMENT '权限ID'
);
ALTER TABLE sys_role_privilege COMMENT '⾓⾊权限关联表';
然后执⾏如下脚本添加测试数据:
INSERT INTO sys_user VALUES (1,'admin','123456','admin@mybatis.tk','管理员',NULL,current_timestamp);
INSERT INTO sys_user VALUES (1001,'test','123456','test@mybatis.tk','测试⽤户',NULL,current_timestamp);
INSERT INTO sys_role VALUES (1,'管理员',1,1,current_timestamp);
INSERT INTO sys_role VALUES (2,'普通⽤户',1,1,current_timestamp);
INSERT INTO sys_user_role VALUES (1,1);
INSERT INTO sys_user_role VALUES (1,2);
INSERT INTO sys_privilege VALUES (1,'⽤户管理','/users');
INSERT INTO sys_privilege VALUES (2,'⾓⾊管理','/roles');
INSERT INTO sys_privilege VALUES (3,'系统⽇志','/logs');
INSERT INTO sys_privilege VALUES (4,'⼈员维护','/persons');
INSERT INTO sys_privilege VALUES (5,'单位维护','/companies');
INSERT INTO sys_role_privilege VALUES (1,1);
INSERT INTO sys_role_privilege VALUES (1,2);
INSERT INTO sys_role_privilege VALUES (1,3);
INSERT INTO sys_role_privilege VALUES (2,4);
INSERT INTO sys_role_privilege VALUES (2,5);
3. 创建实体类
在包del下依次创建这5张表对应的实体类:package del;
import java.util.Date;
/**
* ⽤户表
*/
public class SysUser {
/**
* ⽤户ID
*/
private Long id;
/**
* ⽤户名
*/
private String userName;
/**
* 密码
*/
private String userPassword;
/
**
关于高中生活的作文* 邮箱
*/
private String userEmail;
/**
* 简介
*/
private String userInfo;
/**
* 头像
*/
private byte[] headImg;
/**
* 创建时间
*/
private Date createTime;
// 按Alt+Insert快捷键⽣成get和set⽅法
国内音乐学院排名}
package del;
import java.util.Date;
/**
* ⾓⾊表
*/
public class SysRole {
/**
* ⾓⾊ID
*/
private Long id;
/**
* ⾓⾊名
*/
private String roleName;
/**
*/
private Integer enabled;
/**
* 创建⼈
*/
private Long createBy;
/**
* 创建时间
*/
private Date createTime;
// 按Alt+Insert快捷键⽣成get和set⽅法
}
可以参考类似的命名⽅式创建SysPrivilege.java,SysUserRole.java,SysRolePrivilege.java。
也可以按照⽂末提供的源码地址下载下源代码。
注意事项:
1)MyBatis默认遵循“下划线转驼峰”命名⽅式。
如sys_user表对应的实体类名是Sys_User,数据库字段user_name对应的实体类字段是userName。
2)在实体类中不要使⽤Java的基本类型,基本类型包括byte、int、short、long、float、doubule、char、boolean。
因为Java中的基本类型会有默认值,例如当某个类中存在private int age;字段时,age的默认值为0,所以⽆法满⾜age为null的情况,如果使⽤age !=null,结果总为ture,会导致⼀些隐藏的bug。
4. 创建l⽂件
在src/main/resources下的com/zwwhnly/mybatisaction/mapper⽬录下依次创建5张表对应的Mapper.x
ml⽂件。
护士节文案为了后续更快速的创建l⽂件,我们可以按照如下步骤添加模版:
上图中的内容框中输⼊以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd">
<mapper>
</mapper>
然后选中⽬录,右键新增⽂件,如下图所⽰:
刚⽣成的l内容如下:
太想念
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd">
<mapper>
</mapper>
我们只需要给mapper标签添加个namespace属性即可:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd">
<mapper namespace="batisaction.mapper.SysUserMapper">
</mapper>
按照同样的⽅式依次创建l,l,l和l。
创建完成后,打开我们在上篇博客中创建的l⽂件,修改节点的内容为:
<mappers>
<mapper resource="com/zwwhnly/mybatisaction/l"/>
<mapper resource="com/zwwhnly/mybatisaction/l"/>
<mapper resource="com/zwwhnly/mybatisaction/l"/>
<mapper resource="com/zwwhnly/mybatisaction/l"/>
<mapper resource="com/zwwhnly/mybatisaction/l"/>
<mapper resource="com/zwwhnly/mybatisaction/l"/>
</mappers>
使⽤这种⽅式,最明显的缺点就是,我们后续如果新增了l⽂件,仍然需要来修改⽂件,⾮常不好维护,因此我们修改成如下配置⽅式,配置⼀个包名:
<package name="batisaction.mapper"/>
</mappers>
修改完成后,运⾏上篇博客中的单元测试CountryMapperTest,发现执⾏报如下错误:
报错的原因是上篇博客中,我们并没有为l⽂件创建对应的接⼝,使⽤包名配置⽅式后,就需要创建,所以解决⽅案就是在src/main/java下新建包batisaction.mapper下,然后在该包下新建接⼝CountryMapper,然后在接⼝中添加⽅法selectAll()。
package batisaction.mapper;
import del.Country;
import java.util.List;
public interface CountryMapper {
/**
* 查询全部国家
*
* @return
*/
List<Country> selectAll();
}
5. 创建Mapper接⼝
到src/main/java⽬录下的包batisaction.mapper,在该包下创建XML⽂件对应的接⼝类,分别为
SysUserMapper.java,SysRoleMapper.java,SysPrivilegeMapper.java,SysUserRoleMapper.java,SysRolePrivilegeMapper.java。
这⾥只展⽰下SysUserMapper.java的代码:
package batisaction.mapper;
public interface SysUserMapper {
}
注意事项:当Mapper接⼝和XML⽂件关联的时候,命名空间namespace的值需要配置成接⼝的全限定名称,MyBatis内部就是通过这个值将接⼝和XML关联起来的。
例如l中配置的namespace就batisaction.mapper.SysUserMapper
6. select⽤法
6.1 查询单条数据
假设我们需要通过id查询⽤户的信息,⾸先,我们需要打开SysUserMapper.java接⼝定义⽅法:
/**
社保 转移* 通过id查询⽤户
*
* @param id
* @return
*/
SysUser selectById(Long id);
然后打开对应的l⽂件添加如下内容:
<resultMap id="sysUserMap" type="del.SysUser">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userPassword" column="user_password"/>
<result property="userEmail" column="user_email"/>
<result property="userInfo" column="user_info"/>
相组词<result property="headImg" column="head_img" jdbcType="BLOB"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>
<select id="selectById" resultMap="sysUserMap">
SELECT * FROM sys_user WHERE id = #{id}
</select>
说明:
1)MyBatis通过select标签的id属性值和接⼝的名称进⾏关联。
3)标签的id属性值在同⼀个命名空间下不能重复。
4)因为接⼝⽅法是可以重载的,所以接⼝中可以出现多个同名但参数不同的⽅法,但是XML中id的值不能重复,因此接⼝中的所有同名⽅法会对应着XML中的同⼀个id的⽅法。
为了验证第2点,我们将selectById修改成select.ById:
<select id="select.ById" resultMap="sysUserMap">
SELECT * FROM sys_user WHERE id = #{id}
</select>
此时如果调⽤该⽅法,会报如下错误:
为了验证第3点,我们将XML内容修改为如下:
<select id="selectById" resultMap="sysUserMap">
SELECT * FROM sys_user WHERE id = #{id}
</select>
<select id="selectById" resultMap="sysUserMap">
SELECT * FROM sys_user WHERE id = #{id}
</select>
此时如果调⽤该⽅法,会报如下错误:
XML 代码讲解:
select:映射查询语句使⽤的标签。
id:查询语句的唯⼀标识符,可⽤来代表这条语句。
resultMap:⽤于设置数据库返回列和Java对象的映射关系。
SELECT * FROM sys_user WHERE id = #{id}是查询语句。
{id}:MyBatis SQL中使⽤预编译参数的⼀种⽅式,⼤括号中的id代表传⼊的参数名。
resultMap标签⽤于配置Java对象的属性和查询结果列的对应关系,通过resultMap中配置的column和property可以将查询列的值映射到type 对象的属性上。
上⾯查询语句⽤到的resultMap标签讲解:
id:必填且唯⼀。select标签resultMap属性的值为此处id设置的值。
type:必填。⽤于配置查询列所映射到的Java对象模型。
column:从数据库中得到的列名或者列的别名。
property:要映射到的列结果的属性,即Java对象模型的属性。
jdbcType:列对应的数据库类型。
6.2 查询多条数据
假设我们需要查询所有⽤户的信息,⾸先,我们需要打开SysUserMapper.java接⼝定义⽅法:
/**
* 查询全部⽤户
*
* @return
*/
List<SysUser> selectAll();
然后打开对应的l⽂件添加如下内容:
<select id="selectAll" resultType="del.SysUser">
SELECT id,
user_name    userName,
user_password userPassword,
user_email    userEmail,
user_info    userInfo,
head_img      headImg,
create_time  createTime
FROM sys_user
</select>
注意事项:这⾥我们并没有使⽤resultMap属性来设置要返回结果的类型,⽽是通过resultType属性直接指定
要返回结果的类型,使⽤此种⽅式需要设置查询列的别名,别名要和resultType指定对象的属性名保持⼀致,
进⽽实现⾃动映射。
MyBatis提供了⼀个全局属性mapUnderscoreToCamelCase,将这个属性的值设置为ture可以⾃动将以下划线命名的数据库列映射到Java对象的驼峰式命名属性中。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。