Серия MyBatis (2): выбор основного использования режима XML MyBatis.

MyBatis

1. Определите потребности

Упомянутое в книге требование — это требование управления доступом на основе ролей (RBAC, то есть управление доступом на основе ролей).Что касается управления доступом, я думаю, что все знакомы с ним, потому что большинство систем требуют управления доступом. одной из систем, за которую отвечала предыдущая компания, является система разрешений.Идеи дизайна аналогичны упомянутым в книге.Общее описание выглядит следующим образом:

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_user_role VALUES (1001,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. Создайте класс сущностей

Создайте классы сущностей, соответствующие этим пяти таблицам, по очереди в пакете com.zwwhnly.mybatisaction.model:

package com.zwwhnly.mybatisaction.model;

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 com.zwwhnly.mybatisaction.model;

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 имеют значения по умолчанию, например, когда в классе есть частное целое поле age;, значение age по умолчанию равно 0, поэтому оно не может удовлетворять ситуации, когда age равен null.Если вы используете age ! =null, результат всегда будет For ture, это вызовет некоторые скрытые ошибки.

4. Создайте файл Mapper.xml

Создайте файлы Mapper.xml, соответствующие пяти таблицам, в каталоге com/zwwhnly/mybatisaction/mapper в папке src/main/resources.

Чтобы создать файл Mapper.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>
</mapper>

Затем выберите каталог и щелкните правой кнопкой мыши, чтобы добавить новый файл, как показано на следующем рисунке:

Содержимое только что сгенерированного SysUserMapper.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>
</mapper>

Нам просто нужно добавить атрибут пространства имен в тег mapper:

<?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="com.zwwhnly.mybatisaction.mapper.SysUserMapper">
</mapper>

Таким же образом создайте файлы SysRoleMapper.xml, SysPrivilegeMapper.xml, SysUserRoleMapper.xml и SysRolePrivilegeMapper.xml.

После завершения создания откройте файл mybatis-config.xml, который мы создали в предыдущем блоге, и измените содержимое узла следующим образом:

<mappers>
    <mapper resource="com/zwwhnly/mybatisaction/mapper/CountryMapper.xml"/>
    <mapper resource="com/zwwhnly/mybatisaction/mapper/SysUserMapper.xml"/>
    <mapper resource="com/zwwhnly/mybatisaction/mapper/SysRoleMapper.xml"/>
    <mapper resource="com/zwwhnly/mybatisaction/mapper/SysPrivilegeMapper.xml"/>
    <mapper resource="com/zwwhnly/mybatisaction/mapper/SysUserRoleMapper.xml"/>
    <mapper resource="com/zwwhnly/mybatisaction/mapper/SysRolePrivilegeMapper.xml"/>
</mappers>

Наиболее очевидным недостатком использования этого метода является то, что если в будущем мы добавим новый файл Mapper.xml, нам все равно потребуется изменить файл, который очень сложно поддерживать, поэтому мы изменяем его на следующий метод конфигурации и настраиваем имя пакета:

<mappers>
    <package name="com.zwwhnly.mybatisaction.mapper"/>
</mappers>

После завершения модификации запустите модульный тест CountryMapperTest в предыдущем блоге и обнаружите, что выполнение сообщает о следующей ошибке:

Причина ошибки в том, что в предыдущем блоге мы не создали соответствующий интерфейс для файла CountryMapper.xml, после использования метода конфигурации имени пакета нам нужно его создать, поэтому решение - создать новый пакет com .zwwhnly в src/main/java, в mybatisaction.mapper, затем создайте новый интерфейс CountryMapper в пакете, а затем добавьте в интерфейс метод selectAll().

package com.zwwhnly.mybatisaction.mapper;

import com.zwwhnly.mybatisaction.model.Country;

import java.util.List;

public interface CountryMapper {
    /**
     * 查询全部国家
     *
     * @return
     */
    List<Country> selectAll();
}

5. Создайте интерфейс картографа

Найдите пакет com.zwwhnly.mybatisaction.mapper в каталоге src/main/java и создайте классы интерфейса, соответствующие файлам XML в этом пакете, а именно SysUserMapper.java, SysRoleMapper.java, SysPrivilegeMapper.java, SysUserRoleMapper.java, SysRolePrivilegeMapper.java.

Здесь показан только код SysUserMapper.java:

package com.zwwhnly.mybatisaction.mapper;

public interface SysUserMapper {
    
}

Примечание. Когда интерфейс Mapper связан с файлом XML, значение пространства имен Пространство имен необходимо настроить для интерфейса с полным именем интерфейса, и интерфейс связан с XML через это значение.

Например, пространство имен, настроенное в SysUserMapper.xml, — это com.zwwhnly.mybatisaction.mapper.SysUserMapper.

6. выберите использование

6.1 Запрос одного фрагмента данных

Предположим, нам нужно запросить информацию о пользователе по id, для начала нам нужно открыть метод определения интерфейса SysUserMapper.java:

/**
 * 通过id查询用户
 *
 * @param id
 * @return
 */
SysUser selectById(Long id);

Затем откройте соответствующий файл SysUserMapper.xml и добавьте следующее:

<resultMap id="sysUserMap" type="com.zwwhnly.mybatisaction.model.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 связывает значение атрибута id тега select с именем интерфейса.

2) Значение атрибута id тега не может стоять с английской точкой ".".

3) Значение атрибута id тега не может повторяться в одном и том же пространстве имен.

4) Поскольку методы интерфейса могут быть перегружены, в интерфейсе может быть несколько методов с одинаковым именем, но разными параметрами, но значение id в XML не может повторяться, поэтому все методы с одинаковым именем в интерфейсе будут соответствовать тот же идентификатор в XML-методах.

Чтобы проверить пункт 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, идентификатор в фигурных скобках представляет имя входящего параметра.

Тег resultMap используется для настройки соответствующей связи между свойствами объекта Java и столбцами результатов запроса.Значения столбцов запроса могут быть сопоставлены со свойствами объекта типа через столбец и свойство, настроенные в resultMap .

Объяснение тега resultMap, используемого в приведенном выше запросе:

  • id: обязательный и уникальный. Значением атрибута resultMap тега select является значение, установленное здесь идентификатором.
  • Тип: обязательный. Используется для настройки объектной модели Java, на которую сопоставляются столбцы запроса.
  • столбец: имя столбца или псевдоним столбца, полученный из базы данных.
  • свойство: свойство результата столбца для сопоставления, то есть свойство объектной модели Java.
  • jdbcType: тип базы данных, соответствующий столбцу.

6.2 Запрос нескольких частей данных

Предположим, нам нужно запросить информацию обо всех пользователях, для начала нам нужно открыть метод определения интерфейса SysUserMapper.java:

/**
 * 查询全部用户
 *
 * @return
 */
List<SysUser> selectAll();

Затем откройте соответствующий файл SysUserMapper.xml и добавьте следующее:

<select id="selectAll" resultType="com.zwwhnly.mybatisaction.model.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, установка значения этого свойства в true может автоматически сопоставлять столбцы базы данных, названные с подчеркиванием, именованным свойствам объектов Java в стиле camelCase.

Так как его открыть?

Метод заключается в том, чтобы открыть файл mybatis-config, который мы создали в предыдущем блоге, и добавить следующую конфигурацию в узел настроек:

<settings>
    <!--其他配置-->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

На этом этапе предыдущий оператор selectAll можно упростить следующим образом.

<select id="selectAll" resultType="com.zwwhnly.mybatisaction.model.SysUser">
    SELECT id,
           user_name,
           user_password,
           user_email,
           user_info,
           head_img,
           create_time
    FROM sys_user
</select>

7. Модульное тестирование

Создайте новый базовый тестовый класс BaseMapperTest, код выглядит следующим образом.

package com.zwwhnly.mybatisaction.mapper;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;

import java.io.IOException;
import java.io.Reader;

/**
 * 基础测试类
 */
public class BaseMapperTest {
    private static SqlSessionFactory sqlSessionFactory;

    @BeforeClass
    public static void init() {
        try {
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

Измените код класса CountryMapperTest в предыдущем блоге на следующий.

package com.zwwhnly.mybatisaction.mapper;

import com.zwwhnly.mybatisaction.model.Country;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CountryMapperTest extends BaseMapperTest {

    @Test
    public void testSelectAll() {
        SqlSession sqlSession = getSqlSession();

        try {
            List<Country> countryList = sqlSession.selectList("com.zwwhnly.mybatisaction.mapper.CountryMapper.selectAll");
            printCountryList(countryList);
        } finally {
            sqlSession.close();
        }
    }

    private void printCountryList(List<Country> countryList) {
        for (Country country : countryList) {
            System.out.printf("%-4d%4s%4s\n", country.getId(), country.getCountryname(), country.getCountrycode());
        }
    }
}

Пункт модификации:

1) Наследовать базовый тестовый класс BaseMappertest, вызвать метод базового класса getSqlSession() для получения объекта SQLSession, реализовать повторное использование кода.

2) Значение параметра метода selectList() изменено с selectAll на com.zwwhnly.mybatisaction.mapper.CountryMapper.selectAll,

Поскольку метод selectAll() также добавлен в SysUserMapper, selectAll больше не уникален, поэтому при вызове необходимо использовать пространство имен.

Обратитесь к тестовому классу CountryMapperTest, чтобы создать новый тестовый класс SysUserMapperTest.Код выглядит следующим образом.

package com.zwwhnly.mybatisaction.mapper;

import com.zwwhnly.mybatisaction.model.SysUser;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;

import java.util.List;

public class SysUserMapperTest extends BaseMapperTest {
    @Test
    public void testSelectById() {
        SqlSession sqlSession = getSqlSession();

        try {
            SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);

            SysUser sysUser = sysUserMapper.selectById(1L);
            Assert.assertNotNull(sysUser);

            Assert.assertEquals("admin", sysUser.getUserName());
        } finally {
            sqlSession.close();
        }
    }

    @Test
    public void testSelectAll() {
        SqlSession sqlSession = getSqlSession();

        try {
            SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);

            List<SysUser> sysUserList = sysUserMapper.selectAll();

            Assert.assertNotNull(sysUserList);
            Assert.assertTrue(sysUserList.size() > 0);
        } finally {
            sqlSession.close();
        }
    }
}

Запустите код тестового класса, тест пройден, и выходной журнал выглядит следующим образом.

DEBUG [main] - ==> Preparing: SELECT id, user_name, user_password, user_email, user_info, head_img, create_time FROM sys_user

DEBUG [main] - ==> Parameters:

TRACE [main] - <== Columns: id, user_name, user_password, user_email, user_info, head_img, create_time

TRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, <>, <>, 2019-06-27 18:21:07.0

TRACE [main] - <== Row: 1001, test, 123456, test@mybatis.tk, <>, <>, 2019-06-27 18:21:07.0

DEBUG [main] - <== Total: 2

DEBUG [main] - ==> Preparing: SELECT * FROM sys_user WHERE id = ?

DEBUG [main] - ==> Parameters: 1(Long)

TRACE [main] - <== Columns: id, user_name, user_password, user_email, user_info, head_img, create_time

TRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, <>, <>, 2019-06-27 18:21:07.0

DEBUG [main] - <== Total: 1

8. Исходный код и ссылка

Адрес источника:GitHub.com/Как Ухань, где/каждый шаг…, добро пожаловать на скачивание.

Лю Цзэнхуэй "MyBatis от входа до мастерства"

Создайте xml-файл в IntelliJ IDEA