Java alternatives to hibernate

MyBatis как более быстрая альтернатива Hibernate

В Java сообществе Hibernate framework де-факто считается стандартом для удобной работы с базой данных. Разработчику трудно выбрать другой фреймфорк, потому что порой он не знает о существовании альтернатив. В этой статье я проведу курс молодого бойца по работе с MyBatis framework. Полностью охватить весь framework не получится, но информации будет достаточно, что бы увидеть преимущества и слабые стороны данного framework’а и начать работать с MyBatis.

MyBatis не реализует JPA спеки, а является альтернативой JPA. Основное отличие MyBatis от Hibernate — это то как производится мапинг объектов. Hibernate мапит таблицы БД на сущности, давая нам доступ к данным. Для получения данных Hibernate генерирует SQL запросы, а генерируемые запросы хороши до поры — до времени, а потом они съедают кучу времени, становятся громоздкими и не управляемыми. MyBatis мапится не на таблицы, а на SQL запросы, за формирование запросов отвечает разработчик и только от него будет зависеть как быстро будет работать приложение.

С преамбулой закончили, теперь можно перейти непосредственно к созданию небольшого проекта с использованием MyBatis, что бы познакомиться с ним поближе. Не буду оригинальным, сделаем пару запросов к БД с использованием MyBatis. В примере буду использовать СУБД MySQL, а вы можете использовать любую другую СУБД, которая вам по душе.

Создадим таблицы subscriber, tariff, payments:

CREATE TABLE `mybatis`.`subscriber` ( `id` INT( 10 ) NOT NULL , `name` VARCHAR( 255 ) NOT NULL , `ref_tariff` VARCHAR( 10 ) NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = MYISAM 
CREATE TABLE `mybatis`.`tariff` ( `id` INT( 10 ) NOT NULL , `descr` VARCHAR( 255 ) NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = MYISAM 
CREATE TABLE `mybatis`.`payments` ( `id` INT( 10 ) NOT NULL , `ref_subscriber` INT( 10 ) NOT NULL , `summa` INT( 10 ) NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = MYISAM 

Самое скучное позади — у нас есть БД, из которой мы будем получать данные, теперь приступим непосредственно к работе с MyBatis. Для начала нам необходима библиотека MyBatis. Для получения библиотеки мы будем использовать maven, необходимо добавить зависимость в настройки проекта(pom.xml):

На момент написания статьи последняя версия MyBatis 3.2.8

После того как библиотека успешно загрузилась, необходимо настроить подключение к БД. Настройки осуществляются в конфигурационном файле mybatis-config.xml.

Ниже приведен листинг конфигурационного файла:

В листинге выше я указал 3 мапера — все взаимодействие с БД будет осуществляться через маперы и чем детальнее вы будете понимать как работать с маперами и формировать запросы, тем более производительней будут ваши приложения.

Для корректной работы с MyBatis необходимо создать интерфейс мапера в котором будут предопределены методы, которые будут использоваться и xml файл настроек в котором будут описаны sql запросы, правила их мапинга на объекты и тп.

Читайте также:  Python regexp get group

Создадим интерфейс kz.jazzsoft.mapper.SubscriberMapper:

package kz.jazzsoft.mapper; import kz.jazzsoft.dal.Subscriber; public interface SubscriberMapper

В данном интерфейсе мы определили два метода:

1. getSubscriberById — вернет одного пользователя по id;

2. getSubscriber — вернет список пользователей;

Но что бы данные методы заработали необходимо создать xml маппер с sql запросами.

      

Я упустил еще один момент, который необходимо было сделать — это создать классы beanEntity, на которые мы будем мапить результаты выполнения запросов.

package kz.jazzsoft.dal; import java.util.List; public class Subscriber < private Long id; private String name; private Tariff tariff; private Listpayments public Long getId() < return id; >public void setId(Long id) < this.id = id; >public String getName() < return name; >public void setName(String name) < this.name = name; >public Tariff getTariff() < return tariff; >public void setTariff(Tariff tariff) < this.tariff = tariff; >public List getPayments() < return paymentList; >public void setPayments(List payments) < this.payments = payments; >public List getConnections() < return connections; >> 
package kz.jazzsoft.dal; public class Tariff < private Long id; private String descr; public Long getId() < return id; >public void setId(Long id) < this.id = id; >public String getDescr() < return descr; >public void setDescr(String descr) < this.descr = descr; >> 
package kz.jazzsoft.dal; public class Payment < private Long id; private Integer summa; public Long getId() < return id; >public void setId(Long id) < this.id = id; >public Integer getSumma() < return discount; >public void getSumma(Integer summa) < this.summa = summa; >> 

Можно сразу посмотреть, как работает код, для этого необходимо подключиться к БД и инициализировать нужный мапер, а пока он у нас один (SubscriberMapper). Создадим класс, в котором будем работать:

package kz.jazzsoft; import kz.jazzsoft.mapper.SubscriberMapper; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.Reader; public class Work < public static void main(String[] args) < SqlSessionFactory sqlSessionFactory; SubscriberMapper subscriberMapper; Reader reader = null; try < reader = Resources .getResourceAsReader("mybatis-config.xml"); //Читаем файл с настройками подключения и настройками MyBatis sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); subscriberMapper = sqlSessionFactory.openSession().getMapper(SubscriberMapper.class); //Создаем маппер, из которого и будем вызывать методы getSubscriberById и getSubscribers Listsubscribers = subscriberMapper.getSubscribers(); Subscriber subscriber = subscriberMapper.getSubscriberById(101); > catch (IOException e) < e.printStackTrace(); >> > 

Запросы выполнились и у нас есть объекты, с которыми мы можем работать. Вы можете посмотреть, что у объектов есть id и другие поля заполнены, но не все. Тут есть один нюанс, если колонка в БД имеет такое же имя как переменная, то она автоматически смапиться на нее. Что бы расширить возможности мапинга и создавать сложные структуры в арсенале MyBatis есть тег ResultMap, который позволяет настраивать произвольный мапинг. Делать связи one-to-one и one-to-many.

Читайте также:  Null input method java

ResultMap представляет из себя описание правил связи полей EntityBean с колонками из таблиц. Пример для Subscriber:

В итоге маппер для Subscriber будет выглядеть следующим образом:

         

Связь one-to-one осуществляется не сложнее примера выше. Но нам сначала необходимо будет описать следующий мапер Tariff. Через него мы будем получать данные для связанного поля в Subscriber.

package kz.jazzsoft.dal; public class Tariff < private Long id; private String descr; public Long getId() < return id; >public void setId(Long id) < this.id = id; >public String getDescr() < return descr; >public void setDescr(String descr) < this.descr = descr; >> 

Создаем интерфейс мапера TariffMapper, нам понадобится только один метод:

package kz.jazzsoft.mapper; import kz.jazzsoft.dal.Tariff; public interface TariffMapper
        

Теперь можно добавить Subscriber c Tariff в SubscriberMaper, в resultMap необходимо добавить правило связи:

    column="ref_tariff" javaType="kz.jazzsoft.dal.Tariff" select="kz.jazzsoft .mapper.TariffMapper.getTariffById" fetchType="eager" /> 

Необходимо заменить данный resultMap и можно будет узнать на каком тарифном(Tariff) плане у нас находится Абонент(Subscriber)

Добавим к Абоненту(Subscriber) список его платежей(Payments)(one-to-many):

Для начала необходимо создать EntityBean Payment:

package kz.jazzsoft.dal; public class Payment < private Long id; private Integer summa; public Long getId() < return id; >public void setId(Long id) < this.id = id; >public Integer getSumma() < return discount; >public void getSumma(Integer summa) < this.summa = summa; >> 

Теперь необходимо создать интерфейс мапера PaymentMapper, он будет простой. Только один метод получения списка платежей по id пользователя.

package kz.jazzsoft.mapper; import kz.jazzsoft.dal.Payment; import java.util.List; public interface PaymentMapper < ListgetPaymentsByIdSub(Integer id); > 

Необходимо создать xml мапер:

      select * from payment where ref_subscriber = # Свяжем список платежей (payment) с абонентом (Subscriber):      column="id" javaType="List" ofType="Payment" select="kz.jazzsoft.mapper.PaymentMapper.getPaymentsByIdSub" fetchType="eager" /> 

Полученный resultMap заменяем в SubscriberMapper и можно посмотреть все платежи пользователя. Но на этом все самое интересное только начинается.

MyBatis имеет функционал, который позволяет формировать sql запросы динамически в зависимости от параметров, которые были в него переданы. Например нам нет необходимости создавать кучу sql на каждое действие(выборки из одной таблицы, но по разным параметрам), можно отделаться одним методом, который будет фильтровать тех же абонентов по нескольким колонкам или вообще не будет фильтровать и вернет всех в зависимости от входных данных, но обо всем по порядку.

Для динамического формирования SQL запросов в арсенале MyBatis имеется достаточно компонентов для решения большинства задач. Рассматривать все мы не будем, так как их достаточно много и их можно комбинировать и тп. Для примера расмотрим IF оператор, больше информации можно прочитать в официальном руководстве: mybatis.github.io/mybatis-3/dynamic-sql.html

  

В запросе приведенном выше выполняется проверка, на то что объект в Map по ключу descr не null, тогда в запрос будет добавлена строка в блоке if и таких блоков может быть сколько угодно, они могу быть вложенными.

Читайте также:  Kotlin get current time millis

 udpate subscriber  descr = #,  where при разумном использовании может дать ощутимый прирост в скорости работы приложения. Может показаться страшно писать самому запросы и правила мапинга, но это только кажется, Hibirnate тоже не так уж прост.

Не существует одного универсального решения, которое подошло бы всем, в каждом выборе нужен четкий расчет. MyBatis можно использовать совместно с Hibernate там где это действительно нужно, а это сможете определить только вы.

Источник

Hibernate Alternatives

The best Hibernate alternatives based on verified products, community votes, reviews and other factors.
Latest update: 2023-04-13

Sequelize

Spring Framework

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications — on any kind of deployment platform.

✓ Flagsmith

Flagsmith lets you manage feature flags and remote config across web, mobile and server side applications. Deliver true Continuous Integration. Get builds out faster. Control who has access to new features. We’re Open Source. Try for free freemium

Spark

Spark helps you take your inbox under control. Instantly see what’s important and quickly clean up the rest. Spark for Teams allows you to create, discuss, and share email with your colleagues

Grails

Apache Struts

Entity Framework

SQLAlchemy

SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL.

Beego

Mikro orm

Eclipse RAP

Eclipse Jetty

Jetty is a highly scalable modular servlet engine and http server that natively supports many modern protocols like SPDY and WebSockets.

Vaadin Framework

Apache Jena

Generic Hibernate discussion

Hibernate Reviews

External sources with reviews and comparisons of Hibernate

MyBatis is somewhat similar to the Hibernate framework, as both facilitate communication between the application layer and the database. However, MyBatis doesn’t map Java objects to database tables like Hibernate does — instead, it links Java methods to SQL statements. As a result, SQL is visible when you’re working with the.

Hibernate is one of the best Frameworks which is capable of extending Java’s Persistence API support. Hibernate is an open-source, extremely lightweight, performance-oriented, and ORM (Object-Relational-Mapping) tool.

Was this Hibernate alternatives list helpful? Your feedback is important!

12 out of 15 people consider this list as helpful.
This is equivalent to 4.0 / 5 rating.

Источник

Оцените статью