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: resultType и resultMap, association и collection

          Написано: Maryna Pylnyk, 06/02/2017     

В приложениях мы пишем разного рода запросы, которые могут возвращать результаты разного типа. В этой статье я хочу поговорить о двух важных атрибутах запроса выборки данных: resultType и resultMap Именно эти атрибуты и указывают на тип результата запроса.
Хочу обратить ваше внимание на то, что вы не можете использовать сразу оба атрибута в одном и том же запросе.
Как мы знаем из предыдущих статей о Mybatis, resultType может быть любым объектом, от примитивных (String) до POJO и JavaBean.
Есть и другой атрибут, который показывает какого типа наш результат - resultMap. Его можно использовать в тех случаях, когда наш результат не только простой объект, но и объект более сложной структуры.

Рассмотрим оба типа на примере. Использую MySql сервер. Хочу сказать, что начну с простого примера постепенно добавляя в наш запрос маппера некоторую сложность.
Наша таблица базы данных table1 имеет следующую структуру:

mysql> desc table1;
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| id          | int(11)      | NO   | PRI | NULL    |       |
| name        | varchar(25)  | NO   |     | NULL    |       |
| description | varchar(100) | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

В случае простого объекта JаvaBean мы имеем GenericBean такой структуры (который будет в последствии представлять результат через атрибут resultType):

public class GenericBean{
    private String           idField          = "";
    private String           fieldValue       = "";
    private String           description      = "";

    с соответствующими методами set() и get() для каждой переменной.
  
} 

Наш запрос в маппере будет следующий:

   <select id="getList" resultType="somePackage.GenericBean">
       SELECT
           id as idField,
           name as fieldValue,
           description as description
       FROM
           table1             
    </select>
    

Реклама
Т.е. мы указываем для каждого поля таблицы базы данных, alias, соответствующий имени переменной нашего класса GenericBean.
Замечу, что если вы создадите GenericBean с именами переменных полностью соответствующих именам полей вашей таблицы базы данных, то вы можете даже не использовать alias для каждого поля (столбца), просто использовать "*" (SELECT * FROM table.....). Но опять-таки вопрос в том, будет ли меняться структура базы данных со временем, например, в последующих разработках? Может имя какого-нибудь столбца вы должны будете изменить в ходе вашего программирования, либо же позже.
Есть ещё и другой способ делать маппинг вашего GenericBean как результата запроса - используя resultMap

   <select id="getList" resultMap="nameResultMap">
       SELECT
           *
       FROM
           table1             
    </select>

Т.е. мы указываем атрибут resultMap, который говорит о том, 
что тип результата нашего запроса некоторая карта (здесь "nameResultMap"),
которая в свою очередь указывает на тип. Смотрим, что получаем

   <resultMap id="nameResultMap" type="somePackage.GenericBean">
        <id column="id" property="idField"  />
        <result column="name" property="fieldValue" />
        <result column="description" property="description" />
   </resultMap>

Каждому полю "column" таблицы базы данных соответствует переменная "property" нашего GenericBean. И это самый простой тип нашего результата.
Елемент "id" играет важную роль. Все мои таблицы имеют PrimaryKey, как я думаю, и ваши. Я всегда указываю в "id" мой первичный ключ. Это сказывается на эффективности вашего запроса в плане стоимости. Но не будет ошибкой, если вы column="id" представите, как и другие поля через тег "result".

Представим, что мы должны для каждого поля "id" нашей таблицы table1 выбрать коллекцию данных из другой таблицы table2. Создаём новую таблицу:
mysql>  desc table2;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id        | int(11)     | NO   | PRI | NULL    |       |
| table1_id | int(11)     | NO   |     | NULL    |       |
| value     | varchar(15) | NO   |     | NULL    |       |
| field     | varchar(25) | NO   |     | NULL    |       |
| name      | varchar(25) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)

Наш GenericBean должен иметь ещё одну переменную, назовём её valueList, которая будет содержать нашу коллекцию объектов OtherBean. Добавляем в наш GenericBean новую переменную с соответствующими методами set() и get(). Здесь смотрим на новый объект OtherBean
Попробуем составить наш новый тип результата:

      <resultMap id="nameResultMap" type="somePackage.GenericBean" >
            <id column="id" property="idField"  />
            <result column="name" property="fieldValue" />
            <result column="description" property="description" />
		
         <!-- collections of values from table2 -->
            <collection property="valueList" ofType="package.OtherBean"
                       column="id" select="selectValuesList" />
      </resultMap>
      

Мы видим, что наша collection :
  • состоит из объектов OtherBean, представленных атрибутом ofType,
  • представлена переменной valueList объекта GenericBean через атрибут property,
  • указывает на связь с полем id таблицы в базе данных через атрибут column,
  • является результатом запроса selectValuesList через атрибут select.
Создаём здесь же, в нашем маппере, этот новый запрос selectValuesList.
     <select id="selectValuesList" resultType="package.OtherBean">
         SELECT
             id,
             value,
             field,
             name	
         FROM
             table2 
         WHERE
             table1_id = #{id} 
     </select>

collection рассматривает тип связи между данными один-ко-многим.

Тип связи один-к-одному более простой. Он предполагает использование association. Добавим в нашу таблицу table1 поле table3_id:
+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| id          | int(11)      | NO   | PRI | NULL    |       |
| name        | varchar(25)  | NO   |     | NULL    |       |
| description | varchar(100) | YES  |     | NULL    |       |
| table3_id   | int(11)      | NO   |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

Представим, что мы должны для каждой строки нашей таблицы table1 выбрать дополнительную информацию из другой таблицы table3, зная что в table3 эта информация представлена в виде одной строки, т.е. выборка произведёт лишь один результат. Новое значение "table3_id" служит связывающим звеном с новой таблицей table3:
mysql< desc table3;
+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id        | int(11)     | NO   | PRI | NULL    |       |
| alias     | varchar(15) | NO   |     | NULL    |       |
| title     | varchar(25) | NO   |     | NULL    |       |
| name      | varchar(25) | NO   |     | NULL    |       |
+-----------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)

Маленькое отступление на счёт дополнительной информации. Дополнительная информация может быть разного вида, например, если посмотрим на нашу таблицу table3, то мы можем захотеть в виде дополнительной информации выбрать либо только "alias", либо же целый объект, содержащий полную информацию id+alias+title+name. В первом случае мы можем обойтись и без association, указав прямо в нашем основном запросе дополнительный запрос(subquery), которые можно посмотреть здесь

Во втором случае нам просто необходимо воспользоваться тегом association.
Важно помнить, что тег association должен находиться перед тегом collection.

Добавляем в наш GenericBean ещё одну новую переменную с соответствующими методами set() и get() - объект TableThreeBean (смотрим здесь)

Теперь добавляем:

в тег результата resultMap id="nameResultMap" 

         <association property="type" column="table3_id" select="selectFromTable3"/>

в маппер новый запрос
     
         <select id="selectFromTable3" resultType="package.TableThreeBean">
             SELECT
                 id,
                 alias,
                 title,
                 name	
             FROM
                 table3 
             WHERE
                 id = #{table3_id} 
         </select>


Мы видим, что наша association :
  • представлена переменной type объекта TableThreeBean через атрибут property,
  • указывает на связь с полем table3_id таблицы в базе данных через атрибут column,
  • является результатом запроса selectFromTable3 через атрибут select, в котором в своё время указан тип объекта (TableThreeBean) через атрибут resultType.
Если же наши названия полей в таблице не совпадают с названиями переменных нашего объекта, то мы можем использовать снова атрибут resultMap вместо resultType="package.TableThreeBean".
Читайте статью о том, как посылать параметры в запросы мапперов
" 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

Реклама