Getting Started with MyBatis: Building Your First Application
Understanding Frameworks
A framework is a reusable design structure that defines the architecture of an application, outlining dependencies, responsibilities, and control flow among components. It serves as a foundation upon which developers build applications, abstracting common functionalities to reduce repetitive coding efforts.
Introduction to MyBatis
Originally known as iBatis, this project was moved from Apache to Google in 2010 and later migrated to GitHub in 2013. MyBatis is a Java persistence framework that simplifies database interactions by encapsulating JDBC operations. Developers can focus on writing SQL statements rather than managing connection setup, transaction handling, and statement creation.
MyBatis maps Java objects to SQL parameters using XML or annotations. The framework generates SQL based on these mappings and handles result set mapping back to Java objects.
Comparison with Hibernate
Hibernate offers full automation for ORM mapping between POJOs and database tables, automatically generating SQL queries. In contrast, MyBatis requires manual SQL writing while automating mapping processes, allowing better control over query optimization and complex operations.
MyBatis uses XML configuraton files to separate SQL from code, improving maintainability. It's also lightweight with minimal dependencies and faster learning curve compared to Hibernate.
MyBatis Architecture Overview
The runtime mechanism involves reading configuration files (like mybatis.xml) containing database settings and mapper locations. When executing a query, MyBatis maps interface methods to corresponding SQL tags in mappers, binds parameters, executes the SQL, and returns mapped results.
Setting Up Your First Project in IntelliJ IDEA
Creating Database Schema
Execute the following commands:
CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE `student` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) NOT NULL,
`age` INT NOT NULL,
`score` DOUBLE NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM;
Project Setup Using Maven
Create a new Maven project in IntelliJ IDEA. Configure dependencies in pom.xml:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
</dependencies>
Add log4j.properties in resources directory:
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[service] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.logger.java.sql.Statement = debug
log4j.logger.java.sql.PreparedStatement = debug
log4j.logger.java.sql.ResultSet = debug
Configuration File Structure
Create mybatis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<environments default="mysqlEM">
<environment id="mysqlEM">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper.xml"/>
</mappers>
</configuration>
Mapper Definition
Create mapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<mapper namespace="abc">
<insert id="insertStudent" parameterType="bean.Student">
insert into student(name,age,score) values(#{name},#{age},#{score})
</insert>
</mapper>
Data Model Class
Create Student.java in bean package:
package bean;
public class Student {
private Integer id;
private String name;
private int age;
private double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
// Getters and setters
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public double getScore() { return score; }
public void setScore(double score) { this.score = score; }
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", score=" + score + "]";
}
}
DAO Interface
Create IStudentDao interface:
package dao;
import bean.Student;
public interface IStudentDao {
void insertStu(Student student);
}
Implementation Class
Implement the DAO interface:
package dao;
import java.io.IOException;
import java.io.InputStream;
import bean.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class StudentDaoImpl implements IStudentDao {
public void insertStu(Student student) {
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("insertStudent", student);
sqlSession.commit();
sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Testing with JUnit
import bean.Student;
import dao.IStudentDao;
import dao.StudentDaoImpl;
import org.junit.Before;
import org.junit.Test;
public class MyTest {
private IStudentDao dao;
@Before
public void setUp() {
dao = new StudentDaoImpl();
}
@Test
public void testInsert() {
Student student = new Student("1ADAS", 23, 94.6);
dao.insertStu(student);
}
}
Summary
The workflow involves:
- Loading configuration via InputStream
- Building SqlSessionFactory from configuration
- Opening SqlSession instance
- Executing SQL through session methods
- Committing or rolling back transactions
- Closing session resources
This approach demonstrates basic MyBatis functionality. Advanced implementations would typical extract session management into utility classes for beter code organization.