Этот блог в основном объясняет, как использовать обработчики шрифтов в MyBatis.
1. Определите потребности
В начале проектирования поле enable таблицы sys_role имеет 2 необязательных значения, где 0 означает отключено, 1 означает включено, и мы используем тип Interger в классе сущностей:
/**
* 有效标志
*/
private Integer enabled;
public Integer getEnabled() {
return enabled;
}
public void setEnabled(Integer enabled) {
this.enabled = enabled;
}
Если мы хотим добавить или обновить информацию о роли, мы должны убедиться, что значение поля enable равно 0 или 1, поэтому начальная часть кода может выглядеть так:
if (sysRole.getEnabled() == 0 || sysRole.getEnabled() == 1) {
sysRoleMapper.updateById(sysRole);
sysRole = sysRoleMapper.selectById(2L);
Assert.assertEquals(0, sysRole.getEnabled());
} else {
throw new Exception("无效的enabled值");
}
Этот метод жесткого кодирования не только выглядит недружелюбно, но и не способствует пост-сопровождению: если у программиста сопровождения плохой характер, он вас отругает, ха-ха.
Таким образом, наше требование состоит в том, чтобы отказаться от жесткого кодирования и использовать дружественный метод кодирования, чтобы проверить, действительно ли значение включенного поля.
2. Используйте процессор типа перечисления, предоставляемый MyBatis.
Мы обычно используем перечисления для решения такого сценария.
Сначала создайте новый пакет com.zwwhnly.mybatisaction.type, а затем создайте новое перечисление Enabled под пакетом:
package com.zwwhnly.mybatisaction.type;
public enum Enabled {
/**
* 禁用
*/
disabled,
/**
* 启用
*/
enabled;
}
Среди них индекс, соответствующий отключенному, равен 0, а индекс, соответствующий включенному, равен 1.
Затем измените поле enable типа Integer в классе SysRole на:
/**
* 有效标志
*/
private Enabled enabled;
public Enabled getEnabled() {
return enabled;
}
public void setEnabled(Enabled enabled) {
this.enabled = enabled;
}
На этом этапе исходный жестко закодированный код может быть изменен на:
if (sysRole.getEnabled() == Enabled.disabled || sysRole.getEnabled() == Enabled.enabled) {
sysRoleMapper.updateById(sysRole);
sysRole = sysRoleMapper.selectById(2L);
Assert.assertEquals(Enabled.disabled, sysRole.getEnabled());
} else {
throw new Exception("无效的enabled值");
}
Хотя приведенный выше код прекрасно решает проблему жесткого кодирования, в настоящее время он вызывает новую проблему:
База данных не распознает тип перечисления Enabled.При добавлении, обновлении или в качестве условия запроса значение перечисления необходимо преобразовать в тип int в базе данных.При запросе данных необходимо преобразовать значение типа int в базу данных. на Включен.тип подъема.
Имея в виду этот вопрос, мы добавляем следующий тестовый метод в тестовый класс SysRoleMapperTest:
@Test
public void testUpdateById() {
SqlSession sqlSession = getSqlSession();
try {
SysRoleMapper sysRoleMapper = sqlSession.getMapper(SysRoleMapper.class);
// 先查询出id=2的角色,然后修改角色的enabled值为disabled
SysRole sysRole = sysRoleMapper.selectById(2L);
Assert.assertEquals(Enabled.enabled, sysRole.getEnabled());
// 修改角色的enabled为disabled
sysRole.setEnabled(Enabled.disabled);
if (sysRole.getEnabled() == Enabled.disabled || sysRole.getEnabled() == Enabled.enabled) {
sysRoleMapper.updateById(sysRole);
sysRole = sysRoleMapper.selectById(2L);
Assert.assertEquals(Enabled.disabled, sysRole.getEnabled());
} else {
throw new Exception("无效的enabled值");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
Запустите тестовый код и обнаружите, что возникает следующее исключение:
Error querying database. Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'enabled' from result set. Cause: java.lang.IllegalArgumentException: No enum constant com.zwwhnly.mybatisaction.type.Enabled.1
Это связано с тем, что MyBatis использует TypeHandler (обработчик типов) для преобразования между типами Java и типами базы данных.
MyBatis предоставляет реализации интерфейса TypeHandler для типов Java и общих типов в базе данных JDBC.
MyBatis загрузит все обработчики типов, соответствующие JDBC, при запуске и будет использовать обработчик org.apache.ibatis.type.EnumTypeHandler по умолчанию при обработке типов перечисления.Этот обработчик преобразует тип перечисления в слово строкового типа. для перечисления Enabled — строки «disabled» и «enabled».
Тип включенного поля в базе данных — int, поэтому при запросе информации о роли значение 1 типа int преобразуется в тип Enabled и сообщается об ошибке.
Итак, как решить эту проблему?
MyBatis также предоставляет другой обработчик перечисления: org.apache.ibatis.type.EnumOrdinalTypeHandler, который использует для обработки перечисляемый индекс, что может решить здесь проблему ошибок преобразования.
Чтобы использовать этот процессор, вам нужно добавить следующую конфигурацию в предыдущий файл resources/mybatis-config.xml:
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
javaType="com.zwwhnly.mybatisaction.type.Enabled"/>
</typeHandlers>
Запустите тестовый код еще раз, тест пройден, и журнал вывода выглядит следующим образом:
DEBUG [main] - ==> Preparing: SELECT id,role_name,enabled,create_by,create_time FROM sys_role WHERE id = ?
DEBUG [main] - ==> Parameters: 2(Long)
TRACE [main] - <== Columns: id, role_name, enabled, create_by, create_time
TRACE [main] -
DEBUG [main] - <== Total: 1
DEBUG [main] - ==> Preparing: UPDATE sys_role SET role_name = ?,enabled = ?,create_by=?, create_time=? WHERE id=?
DEBUG [main] - ==> Параметры: обычный пользователь (String), 0 (Integer), 1 (Long), 2019-06-27 18:21:12.0 (Timestamp), 2 (Long)
DEBUG [main] - <== Updates: 1
Как видно из журнала, при запросе информации о роли MyBatis преобразует 1 в Enabled.enabled, а при обновлении информации о роли MyBatis преобразует Enabled.disabled в 0.
3. Используйте обработчик пользовательского типа
Предполагая, что значение включенного поля не является ни буквальным значением перечисления, ни значением индекса перечисления, тогдаorg.apache.ibatis.type.EnumTypeHandler
а такжеorg.apache.ibatis.type.EnumOrdinalTypeHandler
Ни один из них не может удовлетворить наши потребности, в этом случае нам нужно реализовать процессор типов самостоятельно.
Сначала измените код Enabled класса перечисления:
package com.zwwhnly.mybatisaction.type;
public enum Enabled {
/**
* 启用
*/
enabled(1),
/**
* 禁用
*/
disabled(0);
private final int value;
private Enabled(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Затем создайте новый обработчик типа EnabledTypeHandler в пакете com.zwwhnly.mybatisaction.type:
package com.zwwhnly.mybatisaction.type;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
/**
* Enabled类型处理器
*/
public class EnabledTypeHandler implements TypeHandler<Enabled> {
private final Map<Integer, Enabled> enabledMap = new HashMap<Integer, Enabled>();
public EnabledTypeHandler() {
for (Enabled enabled : Enabled.values()) {
enabledMap.put(enabled.getValue(), enabled);
}
}
@Override
public void setParameter(PreparedStatement preparedStatement, int i, Enabled enabled, JdbcType jdbcType) throws SQLException {
preparedStatement.setInt(i, enabled.getValue());
}
@Override
public Enabled getResult(ResultSet resultSet, String s) throws SQLException {
Integer value = resultSet.getInt(s);
return enabledMap.get(value);
}
@Override
public Enabled getResult(ResultSet resultSet, int i) throws SQLException {
Integer value = resultSet.getInt(i);
return enabledMap.get(value);
}
@Override
public Enabled getResult(CallableStatement callableStatement, int i) throws SQLException {
Integer value = callableStatement.getInt(i);
return enabledMap.get(value);
}
}
Обработчик настраиваемого типа реализует интерфейс TypeHandler, переписывает четыре метода в интерфейсе, выполняет обход типа перечисления Enabled в конструкторе без параметров и присваивает поле enabledMap.
Чтобы использовать процессор пользовательского типа, вам также необходимо добавить следующую конфигурацию в resources/mybatis-config.xml:
<typeHandlers>
<!--其他配置-->
<typeHandler handler="com.zwwhnly.mybatisaction.type.EnabledTypeHandler"
javaType="com.zwwhnly.mybatisaction.type.Enabled"/>
</typeHandlers>
Запустите тестовый код, и журнал вывода будет таким же, как и журнал вывода выше, который здесь повторяться не будет.
4. Исходный код и ссылка
Адрес источника:GitHub.com/Как Ухань, где/каждый шаг…, добро пожаловать на скачивание.
Лю Цзэнхуэй "MyBatis от входа до мастерства"