1. Недостатки Mybatis
Mybatis — это превосходная и гибкая структура уровня сохраняемости, которая обеспечивает базовый ввод операций с данными для уровня службы посредством конфигурации XML и сопоставления с интерфейсом Mapper.
Такой хороший фреймворк, но есть еще недостатки?
Как говорится, никто не идеален, потому что Mybatis настолько гибок, что каждый интерфейс Mapper должен настраивать соответствующий XML, поэтому это вызовет некоторые проблемы.
Проблема 1: много файлов конфигурации
Если система включает 100 таблиц БД, нам нужно написать100
Интерфейс маппера, не доделан, самое страшное, надо100
Каждый интерфейс Mapper настраивает соответствующий100
Набор XML. И каждый Mapper должен добавлять, удалять, изменять и проверять функции, поэтому нам нужно написать100
Как благородный инженер-разработчик Java, я не могу этого допустить, поэтомуMybatis Generator
родился, возникает еще один вопрос!
Проблема 2: Сложность обслуживания
Мы используемMybatis Generator
Решил первую проблему, сколько бы файлов не генерировалось, просто и грубо, вроде решает все проблемы, Mybatis идеален!
Не радуйтесь, когда система только установлена, мы используемMybatis Generator
Сгенерировал кучу XML, продукт внезапно повысил новый спрос в процессе разработки, и менеджер проекта увеличился или изменил поле в кусок в соответствии с этим спросом. В это время я думаю, что ваша операция это:
- 1. Найдите XML соответствующей таблицы
- 2. Скопируйте пользовательский тег в XML и сохраните его локально.
- 3. Используйте
Mybatis Generator
Регенерировать XML для таблицы - 4. Перезаписать текущий XML
- 5. Вставьте пользовательский тег в новый XML
В этом процессе, если мы пропустим часть этикетки на шаге 2, после того, как вся операция будет завершена, это будет другое ощущение ~
Вопрос третий: трудности с написанием XML
Если печень хорошая, проблема также в небольшом случае, тогда проблема приходит, как мы пишем и изменим наш XML в растущем XML.
Когда мы открываем XML для редактирования, мы видим более 1000 строк XML, из которых 900 строк являются общими операциями добавления, удаления и модификации.Чтобы добавить тег, нам нужно потянуть в конец файла, чтобы написать новый операция с данными. Чтобы обновить метку, нам нужно передатьCtrl + F
Глядя на дальнейшее изменение этикетки.
Как избежать этих проблем?
Как сделать Mybatis более универсальным, не теряя гибкости?
2. Используйте нашу помощь, чтобы помочь MyBatis
Ourbatis — это небольшой и лаконичный инструмент для улучшения разработки Mybatis, адрес проекта:
- Гитхаб:GitHub.com/Люблю тебя, Лили/О…
- Гостиница:git ee.com/love you lili/even…
- Вики:GitHub.com/Люблю тебя, Лили/О…
- Демо:GitHub.com/Люблю тебя, Лили/О…
характеристика:
- 1, Краткий и удобный, Mybatis может развиваться без XML.
- 2, элегантная развязка, общие и пользовательские теги SQL полностью изолированы, что упрощает обслуживание.
- 3, Неинвазивный, Mybatis и Ourbatis можно использовать одновременно, а конфигурация проста.
- 4, Гибкие и управляемые общие шаблоны можно настраивать и расширять.
- 5, развертывание выполняется быстро, требуется только одна зависимость и две конфигурации, и его можно запустить напрямую.
- 6, несколько источников данных, а также может использоваться, как обычно, в среде с несколькими источниками данных.
Небольшая демонстрация, используемая Ourbatis
окрестности:
- Spring Boot 2.0.5.RELEASE
- Ourbatis 1.0.5
- JAVA 8
- Mysql
отSpring Boot 2.0.5.RELEASE
Возьмите версию в проекте, который можно использовать MyBatis обычно,pom.xml
Добавьте следующие зависимости:
<dependency>
<groupId>com.smallnico</groupId>
<artifactId>ourbatis-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
Добавьте следующую конфигурацию в файл конфигурации:
ourbatis.domain-locations=实体类所在包名
Далее, интерфейсу Mapper нужно только наследоватьSimpleMapper
Просто:
import org.nico.ourbatis.domain.User;
public interface UserMapper extends SimpleMapper<User, Integer>{
}
На данный момент развернуто простое приложение, использующее Ourbatis.После этого вы можете использовать некоторые общие методы работы Ourbatis по умолчанию:
public T selectById(K key);
public T selectEntity(T condition);
public List<T> selectList(T condition);
public long selectCount(Object condition);
public List<T> selectPage(Page<Object> page);
default PageResult<T> selectPageResult(Page<Object> page){
long total = selectCount(page.getEntity());
List<T> results = null;
if(total > 0) {
results = selectPage(page);
}
return new PageResult<>(total, results);
}
public K selectId(T condition);
public List<K> selectIds(T condition);
public int insert(T entity);
public int insertSelective(T entity);
public int insertBatch(List<T> list);
public int update(T entity);
public int updateSelective(T entity);
public int updateBatch(List<T> list);
public int delete(T condition);
public int deleteById(K key);
public int deleteBatch(List<K> list);
Пользовательский метод сопоставления
Во многих сценах мы используем более общий метод, который далек от удовлетворения наших собственных потребностей, нам часто требуется дополнительное расширение новых методов Mapper, XML-тегов, как достичь Ourbatis после его использования?
Сначала посмотрите на наши требования, в приведенной выше демонстрации мы добавляем метод в UserMapper.selectNameById
:
import org.nico.ourbatis.domain.User;
public interface UserMapper extends SimpleMapper<User, Integer>{
public String selectNameById(Integer userId);
}
Как Mybatis, это должно бытьresources
Создайте новую папку в каталоге ресурсовourbatis-mappers
, а затем создайте в нем новый файл XML с правилами именования:
DomainClassSimpleName + Mapper.xml
вDomainClassSimpleName
это имя класса нашего класса сущностей, вотUser
Затем назвал новый XMLUserMapper.xml
.
src/main/resources
- ourbatis-mappers
- UserMapper.xml
После этого откройтеUserMapper.xml
, начните писать MapperselectNameById
Метка, соответствующая методу:
<select id="selectNameById" resultType="java.lang.String">
select name from user where id = #{userId}
</select>
Обратите внимание, что писать теги нужно только во весь файл, больше ничего не нужно, зачем? После того, как вы углубитесь, вы поймете, что вы скажете это первым!
Далее рядом нет, вы можете использовать его напрямуюselectNameById
метод.
Узнайте больше об Урбатисе
При запуске службы Ourbatis сначала сканируетourbatis.domain-locations
Настройте все классы сущностей в пакете и сопоставьте их с соответствующими данными структуры таблицы:
затем пройтиourbatis.xml
Рендеринг, создание одного или другого XML-файла и, наконец, пересборка в контейнеры mybatis!
Весь процесс делится на два основных момента:
- 1. Сопоставление классов сущностей в виде метаданных
- 2. Используйте
ourbatis.xml
Отображать метаданные в виде XML-файла
Я буду представлять их одну за другой~
Сопоставление классов сущностей в качестве метаданных
При сопоставлении мы должны настроить правила сопоставления в соответствии со стилем, указанным в вашей базе данных, вам нужно сделать это в первой основной точке, Ourbatis использует оболочку для завершения:
public interface Wrapper<T> {
public String wrapping(T value);
}
Для полей, которые необходимо сопоставить, напримерИмя таблицыиимя поля таблицы, все они будут проходить через цепочку упаковщиков, прежде чем будут помещены вourbatis.xml
Сделайте рендеринг, чтобы мы могли настроить формат поля упаковки для замены карты, конкретный метод можно найти в официальной Wiki:Обертка
использоватьourbatis.xml
Отображать метаданные в виде XML-файла
Во втором ключевом моменте Ourbatis использует пользовательские теги для рендеринга шаблонов.Сначала мы можем посмотреть на официальные теги по умолчанию.ourbatis.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="@{mapperClassName}">
<resultMap id="BaseResultMap" type="@{domainClassName}">
<ourbatis:foreach list="primaryColumns" var="elem">
<id column="@{elem.jdbcName}" property="@{elem.javaName}" />
</ourbatis:foreach>
<ourbatis:foreach list="normalColumns" var="elem">
<result column="@{elem.jdbcName}" property="@{elem.javaName}" />
</ourbatis:foreach>
</resultMap>
<sql id="Base_Column_List">
<ourbatis:foreach list="allColumns" var="elem"
split=",">
`@{elem.jdbcName}`
</ourbatis:foreach>
</sql>
<select id="selectById" parameterType="java.lang.Object"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from @{tableName}
where 1 = 1
<ourbatis:foreach list="primaryColumns" var="elem">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</ourbatis:foreach>
</select>
<select id="selectEntity" parameterType="@{domainClassName}"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from @{tableName}
where 1 = 1
<ourbatis:foreach list="allColumns" var="elem">
<if test="@{elem.javaName} != null">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</if>
</ourbatis:foreach>
limit 1
</select>
<select id="selectCount" parameterType="@{domainClassName}"
resultType="long">
select count(0)
from @{tableName}
where 1 = 1
<ourbatis:foreach list="allColumns" var="elem">
<if test="@{elem.javaName} != null">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</if>
</ourbatis:foreach>
limit 1
</select>
<select id="selectPage"
parameterType="org.nico.ourbatis.entity.Page"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from @{tableName}
where 1 = 1
<if test="entity != null">
<ourbatis:foreach list="allColumns" var="elem">
<if test="entity.@{elem.javaName} != null">
and `@{elem.jdbcName}` = #{entity.@{elem.javaName}}
</if>
</ourbatis:foreach>
</if>
<if test="orderBy != null">
order by ${orderBy}
</if>
<if test="start != null and end != null">
limit ${start},${end}
</if>
</select>
<select id="selectList" parameterType="@{domainClassName}"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from @{tableName}
where 1 = 1
<ourbatis:foreach list="allColumns" var="elem">
<if test="@{elem.javaName} != null">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</if>
</ourbatis:foreach>
</select>
<select id="selectId" parameterType="@{domainClassName}"
resultType="java.lang.Object">
select
<ourbatis:foreach list="primaryColumns" var="elem"
split=",">
`@{elem.jdbcName}`
</ourbatis:foreach>
from @{tableName}
where 1 = 1
<ourbatis:foreach list="allColumns" var="elem">
<if test="@{elem.javaName} != null">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</if>
</ourbatis:foreach>
limit 1
</select>
<select id="selectIds" parameterType="@{domainClassName}"
resultType="java.lang.Object">
select
<ourbatis:foreach list="primaryColumns" var="elem"
split=",">
`@{elem.jdbcName}`
</ourbatis:foreach>
from @{tableName}
where 1 = 1
<ourbatis:foreach list="normalColumns" var="elem">
<if test="@{elem.javaName} != null">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</if>
</ourbatis:foreach>
</select>
<delete id="deleteById" parameterType="java.lang.Object">
delete
from @{tableName}
where 1=1
<ourbatis:foreach list="primaryColumns" var="elem">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</ourbatis:foreach>
</delete>
<insert id="insert" keyProperty="@{primaryColumns.0.jdbcName}"
useGeneratedKeys="true" parameterType="@{domainClassName}">
insert into @{tableName}
(
<include refid="Base_Column_List" />
)
values (
<ourbatis:foreach list="allColumns" var="elem"
split=",">
#{@{elem.javaName}}
</ourbatis:foreach>
)
</insert>
<insert id="insertSelective"
keyProperty="@{primaryColumns.0.jdbcName}" useGeneratedKeys="true"
parameterType="@{domainClassName}">
insert into @{tableName}
(
<ourbatis:foreach list="primaryColumns" var="elem"
split=",">
`@{elem.jdbcName}`
</ourbatis:foreach>
<ourbatis:foreach list="normalColumns" var="elem">
<if test="@{elem.javaName} != null">
,`@{elem.jdbcName}`
</if>
</ourbatis:foreach>
)
values (
<ourbatis:foreach list="primaryColumns" var="elem">
#{@{elem.javaName}}
</ourbatis:foreach>
<ourbatis:foreach list="normalColumns" var="elem">
<if test="@{elem.javaName} != null">
, #{@{elem.javaName}}
</if>
</ourbatis:foreach>
)
</insert>
<insert id="insertBatch"
keyProperty="@{primaryColumns.0.jdbcName}" useGeneratedKeys="true"
parameterType="java.util.List">
insert into @{tableName}
(
<include refid="Base_Column_List" />
)
values
<foreach collection="list" index="index" item="item"
separator=",">
(
<ourbatis:foreach list="allColumns" var="elem"
split=",">
#{item.@{elem.javaName}}
</ourbatis:foreach>
)
</foreach>
</insert>
<update id="update" parameterType="@{domainClassName}">
update @{tableName}
<set>
<ourbatis:foreach list="normalColumns" var="elem"
split=",">
`@{elem.jdbcName}` = #{@{elem.javaName}}
</ourbatis:foreach>
</set>
where 1=1
<ourbatis:foreach list="primaryColumns" var="elem">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</ourbatis:foreach>
</update>
<update id="updateSelective" parameterType="@{domainClassName}">
update @{tableName}
<set>
<ourbatis:foreach list="primaryColumns" var="elem"
split=",">
`@{elem.jdbcName}` = #{@{elem.javaName}}
</ourbatis:foreach>
<ourbatis:foreach list="normalColumns" var="elem">
<if test="@{elem.javaName} != null">
,`@{elem.jdbcName}` = #{@{elem.javaName}}
</if>
</ourbatis:foreach>
</set>
where 1=1
<ourbatis:foreach list="primaryColumns" var="elem">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</ourbatis:foreach>
</update>
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" index="index" item="item"
separator=";">
update @{tableName}
<set>
<ourbatis:foreach list="normalColumns" var="elem"
split=",">
`@{elem.jdbcName}` = #{item.@{elem.javaName}}
</ourbatis:foreach>
</set>
where 1=1
<ourbatis:foreach list="primaryColumns" var="elem">
and `@{elem.jdbcName}` = #{item.@{elem.javaName}}
</ourbatis:foreach>
</foreach>
</update>
<delete id="deleteBatch" parameterType="java.util.List">
delete from @{tableName} where @{primaryColumns.0.jdbcName} in
<foreach close=")" collection="list" index="index" item="item"
open="(" separator=",">
#{item}
</foreach>
</delete>
<delete id="delete" parameterType="@{domainClassName}">
delete from @{tableName} where 1 = 1
<ourbatis:foreach list="allColumns" var="elem">
<if test="@{elem.javaName} != null">
and `@{elem.jdbcName}` = #{@{elem.javaName}}
</if>
</ourbatis:foreach>
</delete>
<ourbatis:ref path="classpath:ourbatis-mappers/@{domainSimpleClassName}Mapper.xml" />
</mapper>
Видно, что,ourbatis.xml
Содержимое похоже на исходный XML Mybatis, разница в том, что есть два незнакомых тега:
- ourbatis: цикл foreach, отображающий список в метаданных
- ourbatis:ref Внедрить содержимое внешнего файла
Это уникальная метка в Ourbatis, и Ourbatis также предоставляет нам соответствующую запись для настройки метки:
Class: org.nico.ourbatis.Ourbatis
Field:
public static final Map<String, AssistAdapter> ASSIST_ADAPTERS = new HashMap<String, AssistAdapter>(){
private static final long serialVersionUID = 1L;
{
put("ourbatis:foreach", new ForeachAdapter());
put("ourbatis:ref", new RefAdapter());
}
};
мы можем изменитьorg.nico.ourbatis.Ourbatis
статические параметры в классеASSIST_ADAPTERS
Для удаления, обновления и добавления пользовательских тегов необходимо реализовать адаптер тегов, мы можем рассмотреть самый простойRefAdapter
Реализация адаптера:
public class RefAdapter extends AssistAdapter{
@Override
public String adapter(Map<String, Object> datas, NoelRender render, Document document) {
String path = render.rending(datas, document.getParameter("path"), "domainSimpleClassName");
String result = StreamUtils.convertToString(path.replaceAll("classpath:", ""));
return result == null ? "" : result.trim();
}
}
В Ourbatis определены только два вышеуказанных пользовательских тега, которых достаточно для удовлетворения потребностей.foreach
маркировать, просматривать и визуализировать коллекцию в метаданных с помощьюref
Метка вводит внешние ресурсы, которые, как мы уже говорили, являются расширением методов интерфейса Mapper!
<ourbatis:ref path="classpath:ourbatis-mappers/@{domainSimpleClassName}Mapper.xml" />
Путь — это относительный путь текущего пути к классам проекта, и@{domainSimpleClassName}
Он представляет собой имя класса сущности. Дополнительные системные параметры см. в Wiki:сопоставление метаданных
Благодаря этому механизму рендеринга шаблонов, Ourbatis достаточно гибок, мы можем не только расширять, вводя внешние файлы, когда нам нужно добавить или изменить общие методы, мы можем настроитьourbatis.xml
содержание, как это сделать? Просто сделайте копию и поместите ее в каталог ресурсов!
Увидев это, я полагаю, что все уже знают основные принципы Урбатиса и то, как они используются, поэтому я не буду много говорить. Для более подробной информации вы можете перейти на официальную Вики, чтобы прочитать:Ourbtis Wiki