Cloud with rain
.:G
G:.
0 and 1 serie, black on white
pulled card
myjsp.feelinglinux.com
ver. 1.1.9-4
Hallo, welcome to my world.
Here you can find some stuff about computer science.
<<< Enjoy your visit! >>>
0 and 1 serie, white on black

MyBatis в java приложениях, конфигурация и имплементация

          Написано: Maryna Pylnyk, 17/01/2017     

Много лет назад я писала запросы SQL прямо в программном коде, что было действительно малоэффективным,
да и просто непрофессиональным, как мне сейчас кажется.
Всё, что описываю - фрукт моей практической работы с этим программным средством.
Я не ставлю перед собой цели писать все теоретические основы и понятия, всё это можно найти в интернете.
Привожу только практическое применение.
Буквально пару слов. Сначала начала использовать Ibatis-маппинг, который через пару лет заменила на его форк, который называется MyBatis. MyBatis осуществляет маппинг между методами java и запросами SQL (конечно же не только в среде java, но и других платформ, таких как например, DotNet, которые я здесь не рассматриваю). А раз так, то естественно эффективность того или иного SQL запроса остается на плечах разработчика.
Последние годы я использую Mysql, поэтому буду описывать процедуру, используя эту СУБД.
Посмотрим, как конфигурировать в ваш проект MyBatis+Mysql.
Во-первых, нам нужно включить в проект следующие библиотеки:
  • mysql-connector-java-x.x.x-bin.jar
    (5.1.40 на момент написания статьи). Если вы используете другую ветку классического Mysql, которая называется MariaDb, включите библиотеку
    mariadb-java-client-x.x.x.jar
    (1.5.6 на момент написания статьи)
  • mybatis-x.x.x.jar
    (3.2.8 на момент написания статьи)


Конфигурационные файлы MyBatis+Mysql

Понятно, что должен существовать файл, где указывается вся необходимая конфигурация доступа к базе данных и связь с framework MyBatis. И этот файл - файл xml, который имеет определённую структуру. В моём случае это SqlMapConfig.xml (название файла вы можете изменить).
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- Не забывайте включать вышестоящую информацию в ваш файл xml для его правильного использования! -->
<configuration>
   <!-- Файл, где находятся параметры конфигурации базы данных, приведенные ниже -->
    <properties resource="SqlMapConfig.properties"/> 
<environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> <далее приведены другие параметры, которые я обычно использую, когда тип соединения к базе данных производится через пул. --> <property name="poolMaximumActiveConnections" value="10" /> <property name="poolMaximumIdleConnections" value="2" /> <property name="poolMaximumCheckoutTime" value="120000" /> <property name="poolTimeToWait" value="10000" /> <property name="poolPingQuery" value="select 1" /> <property name="poolPingEnabled" value="true" /> <property name="poolPingConnectionsNotUsedFor" value="900000" /> </dataSource> </environment> </environments> <mappers> <mapper resource="<package>/<Name File with SQL queries>.xml" /> </mappers> </configuration>

Как мы указали, параметры доступа к базе данных находятся в файле : <SqlMapConfig.properties>.
Вот его содержание:
# Database access parameters
# Mysql access parameters
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://<host alias>:3306/<Name of Database>?zeroDateTimeBehavior=round&
useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
# MariaDb access parameters
#driver = org.mariadb.jdbc.Driver
#url = jdbc:mariadb://<host alias>:3306/<Name of Database>?zeroDateTimeBehavior=round&
useUnicode=true&characterEncoding=UTF-8&autoReconnect=true

username = <username>
password = <password>

Реклама
Обратите внимание на использование ключевых слов driver, url, username, password между файлами SqlMapConfig.properties(здесь это ключи) и SqlMapConfig.xml(здесь это переменные).
Конечно же вы можете спросить почему бы не указать все эти параметры прямо в основном конфигурационном файле. Можно конечно и driver, и url, и остальные параметры указать прямо в SqlMapConfig.xml. Я описываю способ, который обычно использую, он позволяет мне и конфигурировать другую информацию, и кодифицировать нужные параметры.
Обычно в строке "url" я пишу alias сервера базы данных и помещаю его в файл hosts (/etc/hosts в ОС Linux, в Windows C:\Windows\System32\Drivers\etc\hosts ).
SqlMapConfig.properties я помещаю в src/ , как и сам файл SqlMapConfig.xml.
Ещё одна важная деталь - это тег <mappers>. Именно под этим тегом помещаются все мапперы. Важно указать их правильное размещение в файловой структуре вашего проекта. Я обычно для всех мапперов создаю одну папку где-нибудь в структуре src/.
Вообще конфигурационный файл имеет и другие теги, которые могут быть тоже полезны, как например, <typeAliases>. О нем я расскажу позже. Но для самой простой конфигурации, рассмотренная нами - вполне достаточна. Пришло время перейти к имплементации со стороны кода java.

Имплементация в java

Привожу пример создания и использования соединения с базой данных.
    // Наш класс - singleton DatabaseInstance.java
    private static DatabaseInstance instance = null;

    В конструктор добавляем:

    try (Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml")) {
        setFactory(new SqlSessionFactoryBuilder().build(reader));
    } catch (Exception e) {}

    и метод:

    /**
     * Method used to create the singleton of the class.
     */
    private static DatabaseInstance getInstance() {
        if (instance == null)
        instance = new DatabaseInstance();
        return instance;
    }

    Теперь легко можно использовать наш класс в нашей программе,
    когда нам надо подключиться к базе данных и сделать SQL запрос.
    Метод, который мы можем вызвать в любом месте нашей программы, 
    может выглядеть таким образом:

    SqlSession session = null;
    try {
        session = DatabaseInstance.getInstance().getFactory().openSession();
        /* с openSession() без параметра, открываем SqlSession 
        с default NON-AUTOCOMMIT, и это работает с запросами по выборке данных, 
        однако, если вы хотите использовать запросы, 
        которые должны вносить изменения данных в базу данных, 
        вы должны правильно указывать
        это значение через openSession(true)*/

        List<Object> = session.selectList("selectObjects");
        /* selectObjects, это имя нашего запроса, 
        который мы должны указать в маппере*/

    } catch (Exception e) {
        // всегда полезно включать распечатку исключений
    } finally {
        if (session != null)
            session.close();
    }

Реклама
В такого плана методы мы можем включить различную логическую цепочку, например, используя транзакции с rollback. Всё зависит от вашего проекта. И понятно, что здесь мы можем делать SQL запросы не только выборки (select), но и insert, delete и update.
Наконец, подошли к имплементации самого маппера.

Способы имплементации мапперов

В файле SqlMapConfig.xml все мапперы находятся в теге <mappers>. Помните, что мы написали? Вот эта строка:
     <mapper resource="<package>/<Name File with SQL queries>.xml" />
Как мы видим, файл с запросами - тоже формата xml. Создаём такой файл и заносим туда все наши запросы. В нашем примере это запрос selectObjects
<?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="package.Example">
    <select id="selectObjects" resultType="<some Object>">
        select
            <field1>,
            <field2> 
        from <table>
    </select>
</mapper>

Атрибут "id" содержит в себе имя запроса, и нужно помнить, что имя запроса должно быть уникальным внутри namespace(о namespace напишу чуть дальше). Атрибут "resultType" содержит указание какого типа у нас будет результат. <some Object> может быть любым объектом, от примитивных (String) до POJO и JavaBean, и должен соответствовать тому, который указан в методе. И это один из способов взаимосвязи между маппером и java-кодом. Есть и другой способ подключения к мапперу, через интерфейсы, которые указываются в namespace (в предыдущем способе имя namespace не имеет особого значения). В этом случае, наш программный код будет выглядить чуть-чуть другим образом. В namespace мы указываем полностью package+имя интерфейса, в свою очередь интерфейс должен содержать методы, которые соответствуют методам в маппере. Естественно и <resultType> должен соответствовать тому, который указан в методе интерфейса.
    package <package>

    public interface Example {
        List<Object> selectObjects();
    }

    И в нашем методе мы вызовем маппер таким образом:

    SqlSession session = null;
    try {
        session = DatabaseInstance.getInstance().getFactory().openSession();
        Example exampleMapper = session.getMapper(Example.class);
	List<Object> listObjects = exampleMapper.selectObjects();
    } catch (Exception e) {
        // всегда полезно включать распечатку исключений
    } finally {
        if (session != null)
            session.close();
    }

В некоторых проектах я имею дело в несколькими базами данных (иногда на одном и том же сервере, иногда на разных). Хочу остановиться на такой конфигурации в практическом применении. Если вам интересно, читайте здесь:
Конфигурация нескольких баз данных

И напоследок пару слов об обещанном теге <typeAliases>, действительно полезном. Когда мы создавали наш маппер, мы упоминали о том, что результатом (resultType="<some Object>") могут быть объекты разного типа. Так вот, если ваш объект, например, JavaBean, значит есть ему соответствующий класс, находящийся в вашей структуре в каком-нибудь каталоге package. Получается, каждый раз, когда ваш запрос будет иметь результатом ваш JavaBean класс, вы постоянно должны указывать в вашем маппере правильное его местоположение. А если вы захотите в ходе вашего программирования изменить его местоположение? Что ж придётся позаботиться об изменении названия каталога и в маппере (хорошо, если только в одном. Всё зависит от сложности вашего приложения). Для упрощения и служит тег <typeAliases>. В конфигурационном файле вы просто указываете для каждого класса свой alias, и потом используете этот alias в маппере.
Конфигурационный файл SqlMapConfig.xml:

<typeAliases>
  <typeAlias alias="ObjectTest1" type="<package>.Object1"/>
  <typeAlias alias="ObjectTest2" type="<package>.Object2"/>
  <typeAlias alias="ObjectTest3" type="<package>.Object3"/>
</typeAliases>

и наш маппер:

<mapper namespace="package.Example">
    <select id="selectObjects" resultType="ObjectTest3">
        select
            <field1>,
            <field2>
            from <table>
    </select>
</mapper>

В заключение хочу написать, что в статье рассмотрена базовая структура маппера. Стоит отметить, что помещение всех запросов в одном или нескольких мапперах, в зависимости от сложности вашего проекта или приложения, сможет значительно облегчить вам жизнь в его последующем сопровождении. Для написания запросов с входными параметрами советую прочитать статью
" MyBatis и параметры в запросах SQL "


Если Вы нашли эту статью полезной для себя
поделитесь ею с друзьями в социальных сетях или поставьте "Мне нравится" (вверху справа) .
Большое спасибо!


Вы должны разрешить сохранение куки-файлов и согласиться на правила о конфиденциальности для использования "поделиться" и "мне нравится".
Вы всегда можете отказаться от сохранения куки-файлов и можете удалить куки "cookieconsent_status" из вашего браузера.

 

Tools (myjsp.feelinglinux.com)
Gioco: allenamento con la tastiera Strumenti di codifica/decodifica URI (%-encoding) e Base64 Strumenti di calcolo online per IP e Reti
QUIZ GAME
Quiz game

Поиск в @myjsp.feelinglinux.com

Реклама