Краткое руководство по MyBatis

Краткое руководство по MyBatis

1. Вступление

MyBatis - это среда персистентности с открытым исходным кодом, которая упрощает реализацию доступа к базе данных в приложениях Java. Он обеспечивает поддержку пользовательских SQL, хранимых процедур и различных типов отношений сопоставления.

Проще говоря, это альтернатива JDBC и Hibernate.

2. Maven Зависимости

Чтобы использовать MyBatis, нам нужно добавить зависимость к нашемуpom.xml:


    org.mybatis
    mybatis
    3.4.4

Последнюю версию зависимости можно найтиhere.

3. API Java

3.1. SQLSessionFactoryс

SQLSessionFactory - это базовый класс для каждого приложения MyBatis. Этот класс создается с помощью методаSQLSessionFactoryBuilder'sbuilder(), который загружает файл конфигурации XML:

String resource = "mybatis-config.xml";
InputStream inputStream Resources.getResourceAsStream(resource);
SQLSessionFactory sqlSessionFactory
  = new SqlSessionFactoryBuilder().build(inputStream);

Файл конфигурации Java включает в себя такие параметры, как определение источника данных, сведения о диспетчере транзакций и список сопоставителей, которые определяют отношения между сущностями, вместе они используются для создания экземпляраSQLSessionFactory:

public static SqlSessionFactory buildqlSessionFactory() {
    DataSource dataSource
      = new PooledDataSource(DRIVER, URL, USERNAME, PASSWORD);

    Environment environment
      = new Environment("Development", new JdbcTransactionFactory(), dataSource);

    Configuration configuration = new Configuration(environment);
    configuration.addMapper(PersonMapper.class);
    // ...

    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    return builder.build(configuration);
}

3.2. SQLSessionс

SQLSession содержит методы для выполнения операций с базой данных, получения сопоставителей и управления транзакциями. Его можно создать из классаSQLSessionFactory. Экземпляры этого класса не являются потокобезопасными.

После выполнения операции с базой данных сессия должна быть закрыта. ПосколькуSqlSession реализует интерфейсAutoCloseable, мы можем использовать блокtry-with-resources:

try(SqlSession session = sqlSessionFactory.openSession()) {
    // do work
}

4. Mappers

Mappers - это интерфейсы Java, которые отображают методы на соответствующие операторы SQL. MyBatis предоставляет аннотации для определения операций с базой данных:

public interface PersonMapper {

    @Insert("Insert into person(name) values (#{name})")
    public Integer save(Person person);

    // ...

    @Select(
      "Select personId, name from Person where personId=#{personId}")
    @Results(value = {
      @Result(property = "personId", column = "personId"),
      @Result(property="name", column = "name"),
      @Result(property = "addresses", javaType = List.class,
        column = "personId", [email protected](select = "getAddresses"))
    })
    public Person getPersonById(Integer personId);

    // ...
}

5. MyBatis Аннотации

Давайте посмотрим на некоторые из основных аннотаций, предоставленных MyBatis:

  • *@Insert, @Select, @Update, @Delete* – эти аннотации представляют операторы SQL, которые должны выполняться путем вызова аннотированных методов:

    @Insert("Insert into person(name) values (#{name})")
    public Integer save(Person person);
    
    @Update("Update Person set name= #{name} where personId=#{personId}")
    public void updatePerson(Person person);
    
    @Delete("Delete from Person where personId=#{personId}")
    public void deletePersonById(Integer personId);
    
    @Select("SELECT person.personId, person.name FROM person
      WHERE person.personId = #{personId}")
    Person getPerson(Integer personId);
  • @Results - это список сопоставлений результатов, которые содержат подробную информацию о том, как столбцы базы данных сопоставляются с атрибутами класса Java:

    @Select("Select personId, name from Person where personId=#{personId}")
    @Results(value = {
      @Result(property = "personId", column = "personId")
        // ...
    })
    public Person getPersonById(Integer personId);
  • @Result - представляет собой единственный экземплярResult из списка результатов, полученных из@Results.. Он включает в себя такие детали, как сопоставление столбца базы данных со свойством bean-компонента Java, тип свойства Java и также связь с другими объектами Java:

    @Results(value = {
      @Result(property = "personId", column = "personId"),
      @Result(property="name", column = "name"),
      @Result(property = "addresses", javaType =List.class)
        // ...
    })
    public Person getPersonById(Integer personId);
  • *@Many* – он определяет отображение одного объекта на коллекцию других объектов:

    @Results(value ={
      @Result(property = "addresses", javaType = List.class,
        column = "personId",
        [email protected](select = "getAddresses"))
    })

    ЗдесьgetAddresses - это метод, который возвращает коллекциюAddress путем запроса таблицы адресов.

    @Select("select addressId, streetAddress, personId from address
      where personId=#{personId}")
    public Address getAddresses(Integer personId);

    Подобно аннотации@Many, у нас есть аннотация@One, которая определяет взаимно однозначное соответствие между объектами.

  • *@MapKey* – используется для преобразования списка записей вMap записей с ключом, определенным атрибутомvalue:

    @Select("select * from Person")
    @MapKey("personId")
    Map getAllPerson();
  • *@Options* – в этой аннотации указывается широкий диапазон переключателей и конфигураций, которые должны быть определены, чтобы вместо их определения в других операторах мы могли@Options определять их:

    @Insert("Insert into address (streetAddress, personId)
      values(#{streetAddress}, #{personId})")
    @Options(useGeneratedKeys = false, flushCache=true)
    public Integer saveAddress(Address address);

6. Динамический SQL

Динамический SQL - очень мощная функция, предоставляемая MyBatis. Благодаря этому мы можем структурировать наш сложный SQL с точностью.

В традиционном коде JDBC мы должны писать операторы SQL, объединять их с точностью между ними и ставить запятые в нужных местах. Это очень подвержено ошибкам и очень трудно отлаживать в случае больших операторов SQL.

Давайте посмотрим, как мы можем использовать динамический SQL в нашем приложении:

@SelectProvider(type=MyBatisUtil.class, method="getPersonByName")
public Person getPersonByName(String name);

Здесь мы указали класс и имя метода, которые фактически создают и генерируют окончательный SQL:

public class MyBatisUtil {

    // ...

    public String getPersonByName(String name){
        return new SQL() {{
            SELECT("*");
            FROM("person");
            WHERE("name like #{name} || '%'");
        }}.toString();
    }
}

Динамический SQL предоставляет все конструкции SQL в виде класса, например SELECT,WHERE и т. д. Благодаря этому мы можем динамически изменять генерацию предложенияWHERE.

7. Поддержка хранимых процедур

Мы также можем выполнить хранимую процедуру, используя аннотацию@Select. Здесь нам нужно передать имя хранимой процедуры, список параметров и использовать явныйCall для этой процедуры:

@Select(value= "{CALL getPersonByProc(#{personId,
  mode=IN, jdbcType=INTEGER})}")
@Options(statementType = StatementType.CALLABLE)
public Person getPersonByProc(Integer personId);

8. Заключение

В этом кратком руководстве мы увидели различные функции, предоставляемые MyBatis, и то, как он упрощает разработку приложений для работы с базами данных. Мы также видели различные аннотации, предоставленные библиотекой.

Полный код этой статьи доступенover on GitHub.