Эта статья является кратким изложением книги «MyBatis простыми словами: технические принципы и практика».
В предыдущей статье описана конфигурация MyBatis и подробно объяснен каждый элемент конфигурации, а также упоминается картограф, который является наиболее мощным и наиболее часто используемым инструментом MyBatis.
С помощью картографа можно легко выполнять операции добавления, удаления, модификации и запроса.Мы абстрагируем ключевые моменты этих операций: передачу параметров запроса, сборку условий запроса в различных сценариях, связывание запросов и отображение результатов запроса на объекты Java Bean или коллекция и т.д. Кроме того, производительность запроса данных можно повысить за счет ленивой загрузки и кэширования.
Индекс статьи:
- Введение в JDBC и MyBatis
- Все конфигурации MyBatis
- "Маппер" все понимают
- Основы отражения и динамических прокси
Эта статья обобщает эту идею.Во-первых, в ней перечислены основные элементы картографа, элементы конфигурации и функции, предоставляемые каждым элементом, а затем основное внимание уделяется параметрам, отображению результатов, отложенной загрузке, кэшированию, динамическому SQL и другим функциям.
Основные элементы маппера
Преобразователь состоит из интерфейса Java и файла XML (или аннотации). Интерфейс Java в основном определяет интерфейс вызывающей стороны. Файл XML является основным файлом для настройки преобразователя, включая следующие элементы:
- выберите оператор запроса, вы можете настроить параметры и вернуть набор результатов;
- оператор вставки Insert, возвращающий целое число, указывающее количество вставленных баров;
- оператор update update возвращает целое число, указывающее количество обновлений;
- оператор удаления Удалить, возвращает целое число, указывающее количество удаленных элементов;
- sql позволяет определить часть SQL, а затем ссылаться на нее в разных местах;
- resultMap используется для описания загрузки объектов из набора результатов базы данных, а также может настраивать ассоциации;
- конфигурация кэш-памяти для заданного пространства имен;
Добавить, удалить, изменить, проверить операции
найти
Перед выполнением оператора select необходимо определить параметры.После выполнения он также предоставляет мощные правила сопоставления или автоматическое сопоставление для привязки возвращаемого набора результатов к Java-бину.
Элемент select имеет множество элементов конфигурации, которые кратко описаны ниже:
- paramterType: тип входящего параметра, который может быть базовым типом, картой, пользовательским компонентом Java;
- resultType: возвращаемый тип результата, который может быть базовым типом или пользовательским компонентом Java;
- resultMap: это самый сложный элемент, который может настраивать правила сопоставления, каскады, typeHandler и т. д. и не может существовать одновременно с ResultType;
- flushCache: после вызова SQL необходимо очистить локальный кеш и кеш второго уровня, запрошенные ранее, в основном используемые для обновления кеша, по умолчанию — false;
- useCache: переключатель для запуска кеша второго уровня, по умолчанию будет включен только кеш первого уровня;
- тайм-аут: установите параметр тайм-аута, и по истечении времени ожидания будет выдано исключение, единица измерения — секунды;
- fetchSize: устанавливается общее количество записей, которые необходимо получить;
Например, чтобы получить информацию о пользователе на основе номера Mi Chat:
<select id="findByMiliao" parameterType="string" resultType="User">
select
u.*
from mxt_user u
where u.miliao=#{miliao}
</select>
Когда в предыдущей статье была представлена конфигурация, есть элемент настройки autoMappingBehavior, который по умолчанию используется для автоматического сопоставления наборов результатов, которые не определяют сопоставление вложенных наборов результатов; также есть элемент настройки mapUnderscoreToCamelCase, если установлено значение true, он будет автоматически отображать базу данных. поля с именем «подчеркивание», которое автоматически сопоставляется с POJO с именем в «CamelCase».
При передаче нескольких параметров есть 3 способа:
- Используйте параметр Карта;
- Используйте аннотации для прохождения;
- использовать java-бины;
Аннотации используются следующим образом:
public List<Role> findRoleByNameAndNote(@Param("roleName") String rolename,
@Param("note") String note);
Использование Map для передачи параметров приведет к потере деловой читаемости, что приведет к неудобному расширению и сопровождению в дальнейшем Не рекомендуется, при количестве параметров
Используйте resultMap для сопоставления набора результатов, который будет представлен отдельно позже.
insert
Большинство атрибутов и select одинаковы, скажем, следующие 3 разных атрибута:
- keyProperty: укажите, какой столбец является первичным ключом, если это совместный первичный ключ, его можно разделить запятыми;
- keyColumn: указывает, какой столбец является первичным ключом, который нельзя использовать совместно с keyProperty;
- useGeneratedKeys: использовать ли автоматический рост, по умолчанию — false;
Если для параметра useGeneratedKeys установлено значение true, значение идентификатора Java Bean будет заполнено при вставке, а значение первичного ключа может быть получено через возвращаемый объект.
Если вы хотите установить значение первичного ключа в соответствии с каким-то особым отношением, вы можете использовать тег selectKey в теге вставки, например: если в t_role нет записи, вам нужно установить его в 1, в противном случае взять максимальный идентификатор плюс 2:
<insert id="insertRole" useGeneratedKeys="true" keyProperty="id" >
<selectKey keyProperty="id" resultType="int" order="before">
select if(max(id) is null,1,max(id)+2) as newId from t_role
</selectKey>
</insert>
обновить и удалить
Это относительно просто, поэтому я не буду вдаваться в подробности.
параметр
Передача параметров была введена выше, и вы можете указать тип параметров, чтобы позволить соответствующему обработчику типов обрабатывать их.
#{age , javaType=int , jdbcType=NUMERIC }
Вы также можете установить точность хранения для некоторых числовых параметров.
#{price, javaType=double , jdbcType=NUMERIC , numericScale=2 }
Обычно передается строка и задается параметр #{имя}.В большинстве случаев будет создан прекомпилированный оператор, но иногда передается сам оператор SQL, а не обязательный параметр, который может быть представлен символом $, например, передача столбцов параметров. Для «col1, col2, col3» это можно записать в виде следующего оператора:
select ${columns} from t_tablename
Но обратите внимание на безопасность SQL, чтобы предотвратить внедрение SQL.
SQL-элемент
определение:
<sql id="role_columns">
id,role_name,note
</sql>
использовать:
<include refid="role_columns">
<property name="prefix" value="r" />
</include>
сопоставление результатов
Введение элемента
resultMap — самый сложный элемент в MyBatis, его функция — определять правила сопоставления, каскадные обновления и пользовательские преобразователи типов.
Состоит из следующих элементов:
<resultMap>
<constructor> <!-- 配置构造方法 -->
<idArg/>
<arg/>
</constructor>
<id/> <!--指明哪一列是主键-->
<result/> <!--配置映射规则-->
<association/> <!--一对一-->
<collection/> <!--一对多-->
<discriminator> <!--鉴别器级联-->
<case/>
</discriminator>
</resultMap>
Для некоторых сущностей нет метода построения без параметров, нужно использовать конструктор для настройки метода построения с параметрами:
<resultMap id="role" type="com.xiaomi.kfs.mcc.core.domain.Role">
<constructor>
<idArg column="id" javaType="int"/>
<arg column="role_name" javaType="string"/>
</constructor>
</resultMap>
id указывает столбец первичного ключа, а result настраивает правила сопоставления для полей базы данных и атрибутов POJO:
<resultMap id="role" type="com.xiaomi.kfs.mcc.core.domain.Role">
<id property="id" column="id" />
<result property="roleName" column="role_name" />
<result property="note" column="note" />
</resultMap>
Ассоциация и коллекция используются для настройки каскадных отношений «один к одному» и «один ко многим». На практике отношения «многие ко многим» используются нечасто. используется для разложения их на двусторонние отношения.
Дискриминатор используется в таком сценарии: Например, когда мы идем на медицинский осмотр, предметы медицинского осмотра мужчины и женщины разные. Неразумно просить мальчиков проверить предметы гинекологии. Через дискриминатор можно вернуть разные предметы в зависимости от пола. .
Существует множество конфигураций каскадных отношений, которые здесь не будут продемонстрированы.Дополнительную информацию можно найти в документации.
ленивая загрузка
Преимущество каскадирования в том, что можно легко получить данные, но иногда нет необходимости получать все данные, что приведет к выполнению еще нескольких SQL-запросов и снижению производительности.Для решения этой проблемы необходимо использовать ленивую загрузку. получить данные.
В конфигурации MyBatis есть два глобальных параметра lazyLoadingEnabled и AgressLazyLoading, первый из которых означает, включать ли функцию ленивой загрузки, а второй — вызывать любое свойство ленивой загрузки, которое сделает объект ленивой загрузки полностью загруженным, в противном случае он загружаться только по требованию.
Затем разберитесь с агрессивным свойствомLazyLoading.Например, связанный объект студенческого объекта выглядит следующим образом:
При доступе к информации о студенте также будет найдено состояние здоровья в соответствии с дискриминатором; при доступе к оценкам курса также будет найдена информация об идентификаторе студента, потому что по умолчанию MyBatis лениво загружается по уровню. Но это не то, что нам нужно, и мы не хотим загружать информацию об идентификаторе учащегося при доступе к оценкам.Мы можем установить для параметра AgressLazyLoading значение false, чтобы отложить загрузку данных по мере необходимости.
Вышеуказанные два атрибута являются глобальными настройками, а значение атрибута fetchType также может быть добавлено к элементам ассоциации и коллекции.У него есть два значения — жадный и ленивый.
тайник
Когда кеш конфигурации не отображается, включается только кеш первого уровня. Кэш первого уровня относится к тому же SqlSession. Когда параметры и SQL точно такие же, использование одного и того же объекта SqlSession для вызова одного и того же метода Mapper будет выполнять SQL только один раз.
Если это другой объект SqlSession, поскольку разные SqlSession изолированы друг от друга, даже если используются одни и те же Mapper, параметры и методы, SQL будет снова отправлен в базу данных для выполнения.
Кэш второго уровня находится на уровне SqlSessionFactory и требует отображения и настройки.При реализации кеша второго уровня объекты POJO должны быть сериализуемыми, и требуется только простая настройка:
<cache />
Многие из этих параметров установлены по умолчанию, и можно настроить следующие свойства:
- выселение: представляет стратегию восстановления кеша.Необязательные значения: наименее используемый LRU, FIFO first in first out, Мягкая ссылка SOFT и слабая ссылка WEAK;
- flushInterval: интервал обновления в миллисекундах, если не настроен, кэш будет обновляться при выполнении SQL;
- размер: количество ссылок, представляющее максимальное количество объектов, которые может хранить кеш, не следует устанавливать слишком большим, так как это приведет к переполнению памяти;
- readOnly: только для чтения, что означает, что кэшированные данные могут быть только прочитаны и не могут быть изменены;
На больших серверах может использоваться выделенный кеш-сервер, такой как кеш Redis, который можно легко реализовать, реализовав интерфейс org.apache.ibatis.cache.Cache:
public interface Cache {
String getId(); //缓存编号
void putObject(Object var1, Object var2); //保存对象
Object getObject(Object var1); //获取对象
Object removeObject(Object var1); //移除对象
void clear(); //清空缓存
int getSize(); //获取缓存对象大小
ReadWriteLock getReadWriteLock(); //获取缓存的读写锁
}
Динамический SQL
Во многих случаях условия запроса должны быть собраны в соответствии с различными сценариями.MyBatis предоставляет возможность динамически собирать операторы SQL.
В основном обеспечивают следующие элементы:
- если: заявление о суждении, но условное отраслевое суждение;
- выбрать (когда, иначе): мультиусловное отраслевое суждение;
- урезать (где, установить): решить некоторые проблемы сборки SQL;
- foreach: оператор цикла, обычно используемый для перечисления условий, таких как оператор in;
- bind: настройка переменной контекста с помощью выражения OGNL, которое удобно использовать;
trim может обрабатывать конкатенацию и и запятой, например:
<select id="findRoles" parameterType="string" >
select id,role_name,note from t_role
<trim prefix="where" prefixOverrides="and">
<if test="roleName!=null and roleName!=''">
and role_name like concat('%',#{roleName},'%')
</if>
</trim>
</select>
В качестве альтернативы обновленный список полей можно установить с помощью элемента set:
<update id="updateRole" parameterType="role">
update t_role
<set>
<if test="roleName!=null and roleName!=''">
role_name=#{roleName},
</if>
<if test="note!=null and note!=''">
note=#{note}
</if>
</set>
where id=#{id}
</update>
В следующей статье будет представлен анализ и принцип работы MyBatis.
Добро пожаловать, чтобы отсканировать QR-код ниже и подписаться на мою личную общедоступную учетную запись WeChat ~