【MyBatis】 MyBatis修煉之三 MyBatis XML方式的基本用法

我們通過一個簡單的權限控制需求(RABC,Role-Based Access Control,基于角色的訪問控制),來講解通過XML方式配置MyBatis的基本用法(即select、update、insert、delete等操作的XML配置方式)。

工具

JDK 1.6及以上版本
MyBatis 3.30版本
MySQL 6.3版本
Eclipse4 及以上版本
Apache Maven 構建工具


項目源碼下載地址:https://github.com/JFAlex/MyBatis/tree/master/MyBatis_No.3/alex


權限控制需求

一個用戶擁有若干個角色,一個角色擁有若干權限,權限就是對某個資源的(模塊)的某種操作(增、刪、改、查),這樣就構成了“用戶--角色--權限”的授權模型。在這種模型中,用戶與角色之間、角色與權限之間,一般是多對多的關系。

創(chuàng)建數(shù)據(jù)庫表

首先我們需要創(chuàng)建五個表:用戶表、角色表、權限表、用戶角色關系表、角色權限關系表。在已經創(chuàng)建好的mybatis數(shù)據(jù)庫中執(zhí)行如下SQL腳本:

#創(chuàng)建數(shù)據(jù)庫,并制定編碼格式為UTF-8
CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

#切換數(shù)據(jù)庫到mybatis
use mybatis;

#創(chuàng)建用戶表
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 '創(chuàng)建時間',
    primary key (id)
    
);
alter table sys_user comment '用戶表';

#創(chuàng)建角色表
create table sys_role(
    id bigint not null auto_increment comment '角色ID',
    role_name varchar(50) comment '角色名',
    enabled int comment '有效標志',
    create_by bigint comment '創(chuàng)建人',
    create_time datetime comment '創(chuàng)建時間',
    primary key (id)
);
alter table sys_role comment '角色表';

#創(chuàng)建權限表
create table sys_privilege(
    id bigint not null auto_increment comment '權限ID',
    privilege_name varchar(50) comment '權限名稱',
    privilege_uri varchar(200) comment '權限URL',
    primary key (id)
);
alter table sys_privilege comment '權限表';

#創(chuàng)建用戶角色關系表
create table sys_user_role(
    user_id bigint comment '用戶ID',
    role_id bigint comment '角色ID'
);
alter table sys_user_role comment '用戶角色關聯(lián)表';

#創(chuàng)建角色權限關系表
create table sys_role_privilege(
    role_id bigint comment '角色ID',
    privilege bigint comment '權限ID'
);
alter table sys_role_privilege comment '角色權限關聯(lián)表';

##測試數(shù)據(jù)
insert into sys_user(id,user_name, user_password, user_email, user_info, head_img, create_time) 
values(1,'admin','123456','admin@mybais.alex','管理員',null,'2017-8-09 15:26:52'),
(2,'test','123456','test@mybais.alex','測試用戶',null,'2017-8-09 15:27:30');

insert into sys_role(id,role_name, enabled, create_by, create_time) 
values(1,'管理員','1','1','2017-8-09 15:26:52'),(2,'普通用戶','1','1','2017-8-09 15:26:52');

insert into sys_privilege(id,privilege_name, privilege_uri)
values(1,'用戶管理','/users'),(2,'角色管理','/roles'),(3,'系統(tǒng)日志','/logs'),(4,'人員維護','/persons'),(5,'部門維護','/companies');

insert into sys_user_role values(1,1),(1,2),(2,2);
insert into sys_role_privilege values(1,1),(1,2),(1,3),(2,4),(2,5);

此處沒有創(chuàng)建表之間的外鍵關系。對于表之間的關系,我們可以通過業(yè)務邏輯來進行限制。

創(chuàng)建實體類

MyBatis默認遵循“下劃線轉駝峰”命名方式,所以在創(chuàng)建實體類時一般都按照這種方式進行創(chuàng)建。而具體采用什么命名方式并不重要,在我們使用對象的時候,可以通過resultMap對數(shù)據(jù)庫的列和類的字段配置隱射關系。

用戶類SysUser

package mybatis.simple.model;

import java.util.Arrays;
import java.util.Date;

public class SysUser {

    private Long id;
    private String userName;
    private String userPassword;
    private String userEmail;
    private String userInfo;
    private byte[] headImg;
    private Date createTime;

    public SysUser() {
        super();
    }

    public SysUser(Long id, String userName, String userPassword, String userEmail, String userInfo, byte[] headImg,
            Date createTime) {
        super();
        this.id = id;
        this.userName = userName;
        this.userPassword = userPassword;
        this.userEmail = userEmail;
        this.userInfo = userInfo;
        this.headImg = headImg;
        this.createTime = createTime;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getUserEmail() {
        return userEmail;
    }

    public void setUserEmail(String userEmail) {
        this.userEmail = userEmail;
    }

    public String getUserInfo() {
        return userInfo;
    }

    public void setUserInfo(String userInfo) {
        this.userInfo = userInfo;
    }

    public byte[] getHeadImg() {
        return headImg;
    }

    public void setHeadImg(byte[] headImg) {
        this.headImg = headImg;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "SysUser [id=" + id + ", userName=" + userName + ", userPassword=" + userPassword + ", userEmail="
                + userEmail + ", userInfo=" + userInfo + ", headImg=" + Arrays.toString(headImg) + ", createTime="
                + createTime + "]";
    }

}

角色類SysRole

package mybatis.simple.model;

import java.sql.Date;

public class SysRole {
    private Long id;
    private String role_name;
    private Integer enabled;
    private Long create_by;
    private Date create_time;

    public SysRole() {
        super();
    }

    public SysRole(Long id, String role_name, Integer enabled, Long create_by, Date create_time) {
        super();
        this.id = id;
        this.role_name = role_name;
        this.enabled = enabled;
        this.create_by = create_by;
        this.create_time = create_time;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRole_name() {
        return role_name;
    }

    public void setRole_name(String role_name) {
        this.role_name = role_name;
    }

    public Integer getEnabled() {
        return enabled;
    }

    public void setEnabled(Integer enabled) {
        this.enabled = enabled;
    }

    public Long getCreate_by() {
        return create_by;
    }

    public void setCreate_by(Long create_by) {
        this.create_by = create_by;
    }

    public Date getCreate_time() {
        return create_time;
    }

    public void setCreate_time(Date create_time) {
        this.create_time = create_time;
    }

    @Override
    public String toString() {
        return "SysRole [id=" + id + ", role_name=" + role_name + ", enabled=" + enabled + ", create_by=" + create_by
                + ", create_time=" + create_time + "]";
    }

}

權限類SysPrivilege

package mybatis.simple.model;

public class SysPrivilege {

    private Long id;
    private String privilege_name;
    private String privilege_uri;

    public SysPrivilege() {
        super();
    }

    public SysPrivilege(Long id, String privilege_name, String privilege_uri) {
        super();
        this.id = id;
        this.privilege_name = privilege_name;
        this.privilege_uri = privilege_uri;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getPrivilege_name() {
        return privilege_name;
    }

    public void setPrivilege_name(String privilege_name) {
        this.privilege_name = privilege_name;
    }

    public String getPrivilege_uri() {
        return privilege_uri;
    }

    public void setPrivilege_uri(String privilege_uri) {
        this.privilege_uri = privilege_uri;
    }

    @Override
    public String toString() {
        return "SysPrivilege [id=" + id + ", privilege_name=" + privilege_name + ", privilege_uri=" + privilege_uri
                + "]";
    }

}

用戶角色關系類SysUserRole

package mybatis.simple.model;

public class SysUserRole {
    private Long user_id;
    private Long role_id;

    public SysUserRole() {
        super();
    }

    public SysUserRole(Long user_id, Long role_id) {
        super();
        this.user_id = user_id;
        this.role_id = role_id;
    }

    public Long getUser_id() {
        return user_id;
    }

    public void setUser_id(Long user_id) {
        this.user_id = user_id;
    }


    public Long getRole_id() {
        return role_id;
    }

    public void setRole_id(Long role_id) {
        this.role_id = role_id;
    }

    @Override
    public String toString() {
        return "SysUserRole [user_id=" + user_id + ", role_id=" + role_id + "]";
    }
}

角色權限關系類

package mybatis.simple.model;

public class SysRolePrivilege {
    private Long role_id;
    private Long privilege;

    public SysRolePrivilege() {
        super();
    }

    public SysRolePrivilege(Long role_id, Long privilege) {
        super();
        this.role_id = role_id;
        this.privilege = privilege;
    }

    public Long getRole_id() {
        return role_id;
    }

    public void setRole_id(Long role_id) {
        this.role_id = role_id;
    }

    public Long getPrivilege() {
        return privilege;
    }

    public void setPrivilege(Long privilege) {
        this.privilege = privilege;
    }

    @Override
    public String toString() {
        return "SysRolePrivilege [role_id=" + role_id + ", privilege=" + privilege + "]";
    }

}

在完成上面5個實體類的創(chuàng)建之后,下面我們開始MyBatis XML方式的基本用法。

使用XML方式

MyBatis的真正強大之處在于它的映射語句,由于他的映射語句異常強大,映射器的XML文件就顯得相對簡單。而MyBatis3.0相比2.0版本的一個最大變化,就是支持使用接口的來調用方法。

在【MyBatis修煉之二】中我們使用的是SqlSession通過命名空間調用MyBatis方法,我們需要用到命名空間和方法id組成的字符串來調用相應的方法。而當參數(shù)多于1個的時候,需要將參數(shù)放到一個Map對象中。通過Map傳遞多個參數(shù),使用起來很不方便。

使用接口調用的方式就會方便很多,MyBatis使用Java的動態(tài)代理可以直接通過接口來調用相應的方法,不需要提供接口的實現(xiàn)類,并且也不需要使用SqlSession以通過命名空間間接調用。同時,當有多個參數(shù)時,可以通過在參數(shù)之前添加@Param("fieldName")設置參數(shù)的名字,這樣我們就可以不用手動構造Map參數(shù)了,尤其是在Spring中使用的時候,可以配置為自動掃描所有的接口類,直接將接口注入需要用到的地方。

接下來我們便開始使用MyBatis的XML方式。
首先,在src/main/resource的mybatis.simple.mapper目錄下創(chuàng)建和我們創(chuàng)建的5個表對應的XML文件,分別為UserMapper.xml、RoleMapper.xml、PrivilegeMapper.xml、UserRoleMapper.xml、RolePrivilegeMapper.xml,然后在src/main/java下面創(chuàng)建包mybatis.simple.mapper,接著在該包下創(chuàng)建XML文件對應的接口類,分別為UserMapper.java、RoleMapper.java、PrivilegeMapper.java、UserRoleMapper.java、RolePrivilegeMapper.java。
下面以用戶表對應的Mapper接口UserMapper.java為例進行說明。

package mybatis.simple.mapper;

public interface UserMapper {
    

}

現(xiàn)在這些文件都是空的,后續(xù)使用的時候我們將陸續(xù)向其中添加接口方法。創(chuàng)建了所有的接口文件之后,打開UserMapper.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="mybatis.simple.mapper.UserMapper">

</mapper>

我們特別需要注意的地方是<mapper>根標簽namespace屬性。當Mapper接口和XML文件關聯(lián)的時候,命名空間namespace的值就需要配置成接口的權限定名稱(包名+接口類名),MyBatis內部將通過這個值將接口和XML關聯(lián)在一起。按照相同的方法創(chuàng)建另外4個Mapper.xml文件。準備好這些XML映射文件后,我們需要在mybatis-config.xml配置文件中的mappers元素中配置所有的mapper,部分配置代碼如下。

  <mappers>
      <mapper resource="mybatis/simple/mapper/CountryMapper.xml"/>
      <mapper resource="mybatis/simple/mapper/UserMapper.xml"/>
      <mapper resource="mybatis/simple/mapper/RoleMapper.xml"/>
      <mapper resource="mybatis/simple/mapper/PrivilegeMapper.xml"/>
      <mapper resource="mybatis/simple/mapper/UserRoleMapper.xml"/>
      <mapper resource="mybatis/simple/mapper/RolePrivilegeMapper.xml"/>
  </mappers>

這種配置方式需要將所有的映射文件一一列舉出來,如果增加了新的映射文件,還需要在此處進行配置,操作起來比較麻煩,因為此處所有的XML映射文件都多有對應的Mapper接口,所有還有一種更簡單的配置方式:

    <mappers>
        <package name="mybatis.simple.mapper"/>
    </mappers>

這種配置會先查找mybatis.simple.mapper包下的所有接口,然后循環(huán)對接口進行如下操作:
① 判斷接口對應的命名空間是否已經存在,如果存在就拋出異常,不存在就繼續(xù)進行接下來的操作。
② 加載接口對應的XML映射文件,將接口權限定名轉換為路徑,例如,將接口mybatis.simple.mapper.UserMapper轉換為mybatis/simple/mapper/UserMapper.xml,以.xml為后綴搜索XML資源,如果找打就解析XML。
③ 處理接口中的注解方法。
注意: 使用Mapper接口包名批量加載的方式時,需要將Mapper接口類名和Mapper.xml映射文件名稱保持一致并且包名一致(Mapper.xml可以放在src/main/resource目錄下,但是需要和接口類的包名保持一致,Mapper.xml也可以和接口類在同一個包下),因此直接配置接口包名,就可以自動掃描包下的接口和XML映射文件

完整mybatis-config.xml文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
<configuration>
    
    <!-- 配置指定使用LOG4J輸出日志 -->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    
    <!-- 配置包的別名,這樣我們在mapper中定義時,就不需要使用類的全限定名稱,只需要使用類名即可 -->
    <typeAliases>
        <package name="mybatis.simple.model"/>
    </typeAliases>
    
    <!-- 數(shù)據(jù)庫配置 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!-- mybatis的SQL語句和映射配置文件 -->
    <mappers>
        <package name="mybatis.simple.mapper"/>
    </mappers>

</configuration>

select用法

我們執(zhí)行查詢操作,使用MyBatis,我們只需要在XML中添加select元素,然后寫上SQL語句,然后再做一些簡單的配置,就可以將查詢的結果直接映射到對象中。

詳細說明:XML方式的基本用法(SELECT)

insert用法

和select相比,insert要簡單的多。只有讓他返回主鍵時,由于不同數(shù)據(jù)庫的主鍵生成方式不同,這種情況下會有一些復雜。

詳細說明:XML方式的基本用法(INSERT)

update、delete用法

詳細說明:XML方式的基本用法(UPDATE、DELETE)

特別注意:
不論是SELECT、INSERT、UPDATE還是DELETE,XML配置中的SQL語句結尾都不能添加分號。
不能添加分號……不能添加分號……不能添加分號……


項目源碼下載地址:https://github.com/JFAlex/MyBatis/tree/master/MyBatis_No.3/alex


上一篇: 【MyBatis】MyBatis修煉之二 Maven項目配置MyBatis連接mySQL

下一篇: 【MyBatis】 MyBatis修煉之四 MyBatis XML方式的基本用法(SELECT)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容