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 от входа до мастерства"