MyBatis is a SQL mapper framework with support for mapping the custom SQL statements and stored procedures to Java objects, thus helping in using a relational database with object-oriented applications. In this tutorial, we will learn to configure MyBatis with Spring Boot 3 using mybatis-spring-boot-autoconfigure dependency and embedded database with an example.
1. Maven
When using with Spring boot, the easiest way is to include the mybatis-spring-boot-starter dependency in the project.
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
The above starter dependency transitively includes mybatis-spring-boot-autoconfigure, spring-boot-starter, spring-boot-starter-jdbc and mybatis-spring dependencies that otherwise must be included separately.
Additionally, we should include the relational database driver dependency for database connectivity. We are using H2 database, so include the following:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
2. Model
MyBatis maps the POJO objects to SQL statements, so let us create a very simple TODO object for demo purposes.
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TODO {
private Long id;
private String title;
private String body;
}
The equivalent database schema script file schema.sql is:
create TABLE IF NOT EXISTS `TBL_TODO`(
`id` INTEGER PRIMARY KEY,
`title` VARCHAR(100) NOT NULL,
`body` VARCHAR(2000) NOT NULL
);
We can initialize the table with some default data using data.sql, if needed:
TRUNCATE TABLE TBL_TODO;
INSERT INTO TBL_TODO VALUES (1, 'TITLE', 'BODY');
3. @Mapper Configuration
The mybatis-spring-boot-starter will search, by default, for mappers marked with the @Mapper annotation during the component scanning.
import com.howtodoinjava.app.model.TODO;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface ToDoMapper {
@Select("select * from TBL_TODO")
List<TODO> findAll();
@Select("SELECT * FROM TBL_TODO WHERE id = #{id}")
TODO findById(@Param("id") Long id);
@Delete("DELETE FROM TBL_TODO WHERE id = #{id}")
int deleteById(@Param("id") Long id);
@Insert("INSERT INTO TBL_TODO(id, title, body) " +
" VALUES (#{id}, #{title}, #{body})")
int createNew(TODO item);
@Update("Update TBL_TODO set title=#{title}, " +
" body=#{body} where id=#{id}")
int update(TODO item);
}
We can also use the @MapperScan annotation to specify the packages in a Spring @Configuration class. It will scan all the interfaces in the specified packages for the following mapper annotations and will register these interfaces as mappers.
- @Select
- @Insert
- @Update
- @Delete
import org.mybatis.spring.annotation.MapperScan;
@Configuration
@MapperScan("com.howtodoinjava.app.mapper")
public class PersistenceConfig {
...
}
And define the mapper interfaces as follows:
public interface ToDoMapper {
@Select("select * from TBL_TODO")
List<TODO> findAll();
...
}
4. DataSource Configuration
The MybatisAutoConfiguration class automatically scans and configures the SqlSessionFactory and DataSource beans as specified in the application.properties file.
spring.datasource.url=jdbc:h2:file:/data/articles
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.sql.init.mode=always
To programmatically configure the datasource, we can define the beans in @Configuration class:
@Configuration
public class PersistenceConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("schema.sql")
.addScript("data.sql")
.build();
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource());
return factoryBean.getObject();
}
}
5. Demo
Finally, after the above Mapper and DataSource configurations, we can test the mapper for various add/update operations in the database. We are using the CommandLineRunner to execute the demo code.
import com.howtodoinjava.app.mapper.ToDoMapper;
import com.howtodoinjava.app.model.TODO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App implements CommandLineRunner
{
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Autowired
private ToDoMapper todoMapper;
@Override
public void run(String... args) throws Exception {
TODO newItem = new TODO(2L, "title_2", "body_2");
int createdCount = todoMapper.createNew(newItem);
System.out.println("Created items count : " + createdCount);
TODO item = todoMapper.findById(2L);
System.out.println(item);
int deletedCount = todoMapper.deleteById(2L);
System.out.println("Deleted items count : " + deletedCount);
TODO deletedItem = todoMapper.findById(2L);
System.out.println("Deleted item should be null : " + deletedItem);
}
}
The program output:
Created items count : 1
TODO(id=2, title=title_2, body=body_2)
Deleted items count : 1
Deleted item should be null : null
6. Conclusion
In this short tutorial, we learned to configure MyBatis with Spring Boot. We learned about mapper scanning options and datasource configurations as well.
Happy Learning !!
Comments