Let's automatically generate Mapper & Entity with MyBatis Generator!

About this page

I want to try the automatic generation of DB Mapper and Entity in Java development. ⇒Let's use Mybatis Generator! That is.


What is MyBatis Generator?

An interpreter who exchanges data between Java programs and DBs. (A type of Object-Relational Mapper (O / RM)) So, what I want to do this time is the "Generate" (= Java Object and Mapper automatic generation) function.


Development policy

It is a policy to add MyBatis on top of Spring Boot & Gradle. If you are from environment construction, please refer to the following. ⇒ Introduction to Spring Boot ... It's good, so I'm sure!

environment service/version
Execution environment Windows10
Development environment eclipse Oxygen.2 Release (4.7.2)Java version
development language Java 8
DB PostgreSQL 10
Framework SpringBoot 2.1.3
Dependencies PostgreSQL、Thymeleaf、Web

Install Mybatis Generator on eclipse

Let's get it from the marketplace in eclipse → "Help".


Welcome MyBatis to the project

Add mybatis-spring-boot-starter to Gradle. Then perform a Gralde refresh to update the dependencies.

build.gralde


plugins {
	id 'org.springframework.boot' version '2.1.3.RELEASE'
	id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.lab.app.ketman'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	//Postscript
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.0.0'
	//So far
	runtimeOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'org.postgresql:postgresql'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

image.png


Prepare a table on the DB side

Make a trial table appropriately.

CREATE TABLE orange.songs
(
    title character varying(30) NOT NULL,
    release_date date,
    sales integer,
    winning_flag boolean,
    song_id character(4) NOT NULL,
    CONSTRAINT song_id PRIMARY KEY (song_id)
)
WITH (
    OIDS = FALSE
);

ALTER TABLE orange.songs
    OWNER to postgres;

Create an execution configuration file

Create an xml file that defines the table to be automatically generated and the storage location of the product. Store in the directory under src / main / resources.

generationConfig.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
  <context id="PostgresTables" targetRuntime="MyBatis3">

    <!--Connection settings to the DB for acquiring schema information-->
    <jdbcConnection driverClass="org.postgresql.Driver"
        connectionURL="jdbc:postgresql://localhost:5432/* Schema name *"
        userId="* User ID *"
        password="※password※">
    </jdbcConnection>

    <!--Settings to generate a domain model that stores SELECT results, etc.-->
    <javaModelGenerator targetPackage="com.lab.app.ketman.mybatis.domain" targetProject="※Project name※/src/main/java">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>

    <!--Settings that generate XML with SQL settings-->
    <sqlMapGenerator targetPackage="com/lab/app/ketman/mybatis" targetProject="※Project name※/src/main/resources">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
    <!--Settings to generate mapper class-->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.lab.app.ketman.mybatis.mapper" targetProject="※Project name※/src/main/java">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>

    <!--Specify the table to generate the code-->
    <table schema="orange" tableName="songs">
      <property name="useActualColumnNames" value="true" />
    </table>

  </context>
</generatorConfiguration>

Execute

"Run"-> "Run Configuration"-> "MyBatis Generator" Select generatorConfig.xml in the configuration file and execute it. The following files should be created in the directory specified in generationConfig.xml.

image.png


Let's display it on the screen

Insert it appropriately.

INSERT INTO orange.songs(
	title, release_date, sales, winning_flag, song_id)
	VALUES ('Kirikirimai', '2003-06-04', 20206, false, '0001');
COMMIT;

This time it is assumed to run on Spring Boot, so Add "@Mapper" annotation to the generated Mapper class.

SongsMapper.java


@Mapper
public interface SongsMapper {

Call Mapper from Controller.

SampleController.java


package com.lab.app.ketman.controller;

//import omitted

@Controller
//Must specify the path where the Mapper class is stored
@MapperScan(basePackages = { "com.lab.app.ketman.mybatis.mapper.*"})
public class SampleController {
	@Autowired
	SongsMapper sm;

	@RequestMapping("/index")
	public String index(Model model) {
		Songs s = sm.selectByPrimaryKey("0001");	//Store search results in Songs object
		model.addAttribute("title", s.getTitle());	//Get the value with getter
		return "index";
	}
}


Get the value addedAttribute from the HTML side. (Since this time it is assumed to run on Spring Boot, I am using the recommended Thymeleaf. )

index.html


<h1 th:text="${title}"></h1>

I was able to output it safely. image.png


Supplement ①

At first, the link between SongsMapper.xml and SongsMapper.java didn't work, Invalid bound statement (not found) I have thrown an error. This time, it was solved by matching the paths on the xml and java sides.

Quoted below: Spring Boot + Mybatis mapper-locations

In Spring Boot + Mybatis, if the path of Mapper XML and Mapper class is the same, Mybatis will read Mapper XML without specifying the above. The image of "Mapper XML and Mapper class have the same path" looks like the following. ・ Src / main / java / jp / co / arsware / example / mapper / CityMapper.java ・ Src / main / resources / jp / co / arsware / example / mapper / CityMapper.xml

  • If the path below co is the same, it will be read.

However, even if I define mapper-locations in application.properties, it is not solved ... This point is unknown.


Supplement ②

You also need to be careful about the configuration of packages such as Controller. This article was easy to read. Causes and countermeasures when No qualifying bean of type appears in Spring Boot


in conclusion

In this article, we have dealt with the confirmation of operation using Mybatis Generator. I think that you can handle joins and dynamic SQL by maintaining XML and Example.java.

Recommended Posts

Let's automatically generate Mapper & Entity with MyBatis Generator!
Automatically generate jpa entity using Gradle