The MyBatis supremacy or how to add a persistence layer framework to your Spring Boot application
MyBatis (formerly known as iBatis) is a persistence framework with support for custom SQL, stored procedures and advanced mappings. With little configuration you can have your application write and read to your database in no time.
And since we're talking about configuration - we will not use any XML files for that (as a friend used to say, no "XML Hell!")
We will create a Spring Boot application that will insert data into a table and then select from the same table. If you're new to Spring Boot check out our post The Spring Boot revolution . Our application will be based on that example.
First of all, we need to choose a database, in this case I will use MySQL. This is the table you need to create to run the example.
Table: Musician
To build and deploy our app we will be using Maven. Here is the complete POM file.
Your application need to have spring-boot-starter-parent as a parent.
Apart from the Lombok library, for the boilerplate code, we are adding the connector for MySQL and the mybatis-spring-boot-starter dependency. This dependency will help you build quickly MyBatis applications on top of Spring Boot.
As we mentioned in earlier posts, Spring Boot will build your application by looking at your configuration.
Here is the project structure:
In our case the main Application class is located in the package com.example.
The
We use the
Here is our Application class:
We inject the MySQLSetting class in our main class in order to obtain the connection properties to create our datasource.
The connection properties will be in a YAML file . YAML is a superset of JSON and as such is a very convenient format for specifying hierarchical configuration data.
This is the MySQLSetting class:
To bind the properties defined like that in your YAML file using the Spring @DataBinder utilities (which is what @ConfigurationProperties does in your MySQLSetting class) you need to have a property with a setter in your class - this will bind the properties above.
Spring Boot favours Java-based configuration. Whenever you can, try to create your application without an XML source. When we add the @Configuration annotation to MySQLSetting class we make sure it is picked up automatically by @ComponentScan .
Back to our main Application class. Once we have the connection properties, we need to create our datasource which will be auto detected by the mybatis-spring-boot-starter. Now that we have the datasource we can create an SQLSessionFactory ; We need this to use MyBatis with Spring Boot. We also need at least one mapper interface.
mybatis-spring-boot-starter will autoscan your mappers and register them to your Spring context so they can be injected into your beans. Here is our mapper interface:
The @Insert and @Select annotations will allow us to persist and look for our entity in the DB, respectively.
This mapper will be injected in our MusicianController like this:
And here is our Musician entity:
Then we can call the first endpoint declared in our controller to persist our entity
http://localhost:8080/insert?firstName=Phil&lastName=Collins&instrument=Drums
Go to your MySQL client and check the DB:
http://localhost:8080/findByLastName?lastName=Collins
You'll see:
You don't need much else to make MyBatis work, it is very easy and straightforward.
You defined your properties file using YAML. And you were able to persist an entity on your MysQL database, and then searched for that entity.
That's all for today!
And since we're talking about configuration - we will not use any XML files for that (as a friend used to say, no "XML Hell!")
We will create a Spring Boot application that will insert data into a table and then select from the same table. If you're new to Spring Boot check out our post The Spring Boot revolution . Our application will be based on that example.
First of all, we need to choose a database, in this case I will use MySQL. This is the table you need to create to run the example.
Table: Musician
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
first_name | varchar(35) | YES | NULL | ||
last_name | varchar(35) | YES | NULL | ||
instrument | varchar(35) | YES | NULL |
To build and deploy our app we will be using Maven. Here is the complete POM file.
Your application need to have spring-boot-starter-parent as a parent.
Apart from the Lombok library, for the boilerplate code, we are adding the connector for MySQL and the mybatis-spring-boot-starter dependency. This dependency will help you build quickly MyBatis applications on top of Spring Boot.
As we mentioned in earlier posts, Spring Boot will build your application by looking at your configuration.
Here is the project structure:
└── src └── main └── java └── com.example -+ Application.java └── controller └── entity └── mapper └── setting -+ MySQLSetting.java └── resources -+ application.ymlSpring recommends to locate your main application class in a root package above all other classes.
In our case the main Application class is located in the package com.example.
The
@EnableAutoConfiguration
annotation is often placed on your main class, and it implicitly defines a base "search package" for certain items.We use the
@SpringBootApplication
annotation in our Application class, which includes @EnableAutoConfiguration
, @Configuration
and @ComponentScan
.Here is our Application class:
@SpringBootApplication
public class Application {
@Autowired
private MySQLSetting mySQLSetting;
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
@Bean
@Qualifier("mysql")
public DataSource dataSourceMs() {
return DataSourceBuilder
.create()
.username(mySQLSetting.getUsername())
.password(mySQLSetting.getPassword())
.url(mySQLSetting.getUrl())
.driverClassName(mySQLSetting.getDriverClassName())
.build();
}
@Bean(name = "mySqlSessionFactory")
public SqlSessionFactory sqlSessionFactory1(@Qualifier("mysql") DataSource ds)
throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(ds);
return factory.getObject();
}
}
There are some things worth mentioning here. Let's focus on how we get the connection properties and then we can discuss the rest of the main class.We inject the MySQLSetting class in our main class in order to obtain the connection properties to create our datasource.
The connection properties will be in a YAML file . YAML is a superset of JSON and as such is a very convenient format for specifying hierarchical configuration data.
This is the MySQLSetting class:
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "mysql")
@Getter
@Setter
public class MySQLSetting {
private String username;
private String password;
private String url;
private String driverClassName;
}
And this is our application.yml file in our resources directory:
mysql:
username: root
password: database
url: jdbc:mysql://127.0.0.1:3306/MyDemo
driverClassName: com.mysql.jdbc.Driver
By default Spring Boot will try to create an embedded H2 database for you; we need to override that action in order to let Spring know we will be using MySQL. To do that we'll define the datasource properties in our application.yml file .To bind the properties defined like that in your YAML file using the Spring @DataBinder utilities (which is what @ConfigurationProperties does in your MySQLSetting class) you need to have a property with a setter in your class - this will bind the properties above.
Spring Boot favours Java-based configuration. Whenever you can, try to create your application without an XML source. When we add the @Configuration annotation to MySQLSetting class we make sure it is picked up automatically by @ComponentScan .
Back to our main Application class. Once we have the connection properties, we need to create our datasource which will be auto detected by the mybatis-spring-boot-starter. Now that we have the datasource we can create an SQLSessionFactory ; We need this to use MyBatis with Spring Boot. We also need at least one mapper interface.
mybatis-spring-boot-starter will autoscan your mappers and register them to your Spring context so they can be injected into your beans. Here is our mapper interface:
package com.example.Mapper;
import com.example.entity.Musician;
import org.apache.ibatis.annotations.*;
@Mapper
public interface MusicianMapper {
@Results(id = "musicianResult", value = {
@Result(property = "firstName", column = "first_name"),
@Result(property = "lastName", column = "last_name")})
@Select("SELECT * FROM sys.Musician WHERE last_name = #{lastName}")
Musician findByLastName(@Param("lastName") String lName);
@Insert("INSERT INTO sys.Musician (first_name, last_name, instrument) " +
"VALUES (#{firstName}, #{lastName}, #{instrument})")
void insertMusician(Musician musician);
}
mybatis-spring-boot-starter will search, by default, for mappers with the @Mapper annotation.The @Insert and @Select annotations will allow us to persist and look for our entity in the DB, respectively.
This mapper will be injected in our MusicianController like this:
package com.example.controller;
import com.example.Mapper.MusicianMapper;
import com.example.entity.Musician;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MusicianController {
@Autowired
private MusicianMapper musicianMapper;
@RequestMapping("/insert")
public void greeting(@RequestParam(value="firstName", defaultValue = "Peter") String firstName,
@RequestParam(value="lastName", defaultValue = "Gabriel") String lastName,
@RequestParam(value="instrument", defaultValue = "VOICE") String instrument){
Musician musician= new Musician();
musician.setFirstName(firstName);
musician.setLastName(lastName);
musician.setInstrument(instrument);
musicianMapper.insertMusician(musician);
}
@RequestMapping("/findByLastName")
public Musician searchByLastName(@RequestParam(value="lastName") String lastName){
return musicianMapper.findByLastName(lastName);
}
}
And here is our Musician entity:
package com.example.entity;
import lombok.Data;
@Data
public class Musician {
private String firstName;
private String lastName;
private String instrument;
}
You can now start your Spring Boot application, running this maven command on the command line, in the directory where your pom file resides:$ mvn spring-boot:run
Then we can call the first endpoint declared in our controller to persist our entity
http://localhost:8080/insert?firstName=Phil&lastName=Collins&instrument=Drums
Go to your MySQL client and check the DB:
mysql> SELECT * FROM sys.musician;
+------------+-----------+------------+
| first_name | last_name | instrument |
+------------+-----------+------------+
| Phil | Collins | Drums |
+------------+-----------+------------+
1 row in set (0.00 sec)
And if you try your "search by name" method,http://localhost:8080/findByLastName?lastName=Collins
You'll see:
{
firstName: "Phil",
lastName: "Collins",
instrument: "Drums"
}
You don't need much else to make MyBatis work, it is very easy and straightforward.
Summary
You learned today how to create a Spring Boot application using MyBatis with little configuration.You defined your properties file using YAML. And you were able to persist an entity on your MysQL database, and then searched for that entity.
That's all for today!
Comments
Post a Comment