Guida rapida a MyBatis

1. Introduzione

MyBatis è un framework di persistenza open source che semplifica l'implementazione dell'accesso al database nelle applicazioni Java. Fornisce il supporto per SQL personalizzato, stored procedure e diversi tipi di relazioni di mapping.

In poche parole, è un'alternativa a JDBC e Hibernate.

2. Dipendenze di Maven

Per utilizzare MyBatis dobbiamo aggiungere la dipendenza al nostro pom.xml:

 org.mybatis mybatis 3.4.4 

L'ultima versione della dipendenza può essere trovata qui.

3. API Java

3.1. SQLSessionFactory

SQLSessionFactory è la classe principale per ogni applicazione MyBatis. Questa classe viene creata un'istanza utilizzando SQLSessionFactoryBuilder' s costruttore () metodo che carica un file XML di configurazione:

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

Il file di configurazione Java include impostazioni come la definizione dell'origine dati, i dettagli del gestore delle transazioni e un elenco di mappatori che definiscono le relazioni tra le entità, questi insieme vengono utilizzati per creare l' istanza 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 contiene metodi per eseguire operazioni di database, ottenere mappatori e gestire transazioni. Può essere istanziato dalla classe SQLSessionFactory . Le istanze di questa classe non sono thread-safe.

Dopo aver eseguito l'operazione sul database, la sessione dovrebbe essere chiusa. Poiché SqlSession implementa l' interfaccia AutoCloseable , possiamo utilizzare il blocco try-with-resources :

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

4. Mappatori

I mapping sono interfacce Java che associano i metodi alle istruzioni SQL corrispondenti. MyBatis fornisce annotazioni per definire le operazioni del database:

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. Annotazioni MyBatis

Vediamo alcune delle principali annotazioni fornite da MyBatis:

  • @Insert, @Select, @Update, @Delete : queste annotazioni rappresentano istruzioni SQL da eseguire chiamando metodi annotati:
    @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 - è un elenco di mappature dei risultati che contengono i dettagli di come le colonne del database vengono mappate agli attributi della classe Java:
    @Select("Select personId, name from Person where personId=#{personId}") @Results(value = { @Result(property = "personId", column = "personId") // ... }) public Person getPersonById(Integer personId);
  • @Result : rappresenta una singola istanza di Result fuori dall'elenco dei risultati recuperati da @Results. Include dettagli come la mappatura dalla colonna del database alla proprietà del bean Java, il tipo Java della proprietà e anche l'associazione con altri oggetti 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 - specifica una mappatura di un oggetto su una raccolta di altri oggetti:
    @Results(value ={ @Result(property = "addresses", javaType = List.class, column = "personId", [email protected](select = "getAddresses")) })

    Qui getAddresses è il metodo che restituisce la raccolta di Address interrogando la tabella degli indirizzi.

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

    Simile all'annotazione @Many , abbiamo l' annotazione @One che specifica la relazione di mappatura uno a uno tra gli oggetti.

  • @MapKey : viene utilizzato per convertire l'elenco dei record in Mappa dei record con la chiave definita dall'attributo value :
    @Select("select * from Person") @MapKey("personId") Map getAllPerson();
  • @Options - questa annotazione specifica un'ampia gamma di opzioni e configurazioni da definire in modo che invece di definirle su altre istruzioni possiamo @Options per definirle:
    @Insert("Insert into address (streetAddress, personId) values(#{streetAddress}, #{personId})") @Options(useGeneratedKeys = false, flushCache=true) public Integer saveAddress(Address address);

6. SQL dinamico

Dynamic SQL è una funzionalità molto potente fornita da MyBatis. Con questo, possiamo strutturare il nostro complesso SQL con precisione.

Con il codice JDBC tradizionale, dobbiamo scrivere istruzioni SQL, concatenarle con la precisione degli spazi tra di loro e mettere le virgole al posto giusto. Questo è molto soggetto a errori e molto difficile da eseguire il debug, nel caso di istruzioni SQL di grandi dimensioni.

Esploriamo come possiamo utilizzare SQL dinamico nella nostra applicazione:

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

Qui abbiamo specificato una classe e un nome di metodo che effettivamente costruisce e genera l'SQL finale:

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

Dynamic SQL fornisce tutti i costrutti SQL come una classe, ad esempio SELECT , WHERE ecc. Con questo, possiamo cambiare dinamicamente la generazione della clausola WHERE .

7. Supporto per stored procedure

Possiamo anche eseguire la stored procedure utilizzando l' annotazione @Select . Qui dobbiamo passare il nome della stored procedure, l'elenco dei parametri e utilizzare una chiamata esplicita a quella procedura:

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

8. Conclusione

In questo breve tutorial, abbiamo visto le diverse funzionalità fornite da MyBatis e come facilita lo sviluppo di applicazioni per database. Abbiamo anche visto varie annotazioni fornite dalla libreria.

Il codice completo per questo articolo è disponibile su GitHub.