【介绍】Mybatis
框架
成熟稳健的框架作用是高效稳定的封装好开发中需要的基本操作,让开发人员可以专注于业务逻辑开发。
三层架构
目前比较成熟的后端开发架构基本上分为了三层,表现层、业务层、持久层。
JDBC
在最初没有框架时是直接通过JDBC与数据库进行交互的,实现方式如下:
package com.local.demo;
import org.junit.Test;
import java.sql.*;
/**
* 直接通过JDBC来实现程序与数据库交互的方式,
*/
public class TestCase0 {
@Test
public void testFindOne() {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//通过驱动获取数据库连接
connection = DriverManager.getConnection(
"jdbc:mysql://xxxxx:3306/xxx?useUnicode=true&characterEncoding=utf8",
"xxx",
"xxx"
);
//编写sql语句
String sql = "select * from user_dev where id = ?";
//预处理sql
preparedStatement = connection.prepareStatement(sql);
//设置参数
preparedStatement.setInt(1, 1);
//获取结果集
resultSet = preparedStatement.executeQuery();
//遍历获取结果
while (resultSet.next())
System.out.println(resultSet.getString("user_name"));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
什么是Mybatis
Mybatis前身是Apache开源项目ibatis。
Mybatis架构

Mybatis依赖
-
将mybatis-x.x.x.jar文件置于classpath中
-
Maven项目在pom.xml中注入依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
Mybatis相关配置文件
db.properties
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://xxx:3306/xxx?useUnicode=true&characterEncoding=utf8
db.username=xxx
db.password=xxx
Configuration.xml
可以看到,数据库的连接信息都配置到xml文件中,或者说配置到了xml中获取的db.properties中。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml" />
</mappers>
</configuration>
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.local.mapper.UserDevMapper">
<resultMap id="userDevResultMap" type="com.local.entity.UserDev">
<id column="id" jdbcType="INTEGER" property="id"/>
<result column="user_name" jdbcType="VARCHAR" property="userName"/>
<result column="age" jdbcType="INTEGER" property="age"/>
<result column="gender" jdbcType="INTEGER" property="gender"/>
<result column="gmt_created" jdbcType="TIMESTAMP" property="gmtCreated"/>
<result column="creator" jdbcType="VARCHAR" property="creator"/>
<result column="gmt_modified" jdbcType="TIMESTAMP" property="gmtModified"/>
<result column="modifier" jdbcType="VARCHAR" property="modifier"/>
<result column="is_deleted" jdbcType="VARCHAR" property="isDeleted"/>
</resultMap>
<select id="findUserById" parameterType="int" resultMap="userDevResultMap">
select * from user_dev where id = #{id}
</select>
<insert id="insertOne" parameterType="com.local.entity.UserDev">
insert into user_dev (
user_name,
age, gender,
creator,
gmt_created,
modifier,
gmt_modified,
is_deleted
) values (
#{userName},
#{age},
#{gender},
#{creator},
#{gmtCreated},
#{modifier},
#{gmtModified},
#{isDeleted}
)
</insert>
</mapper>
Mybatis的第一个例子
package com.local.config;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisConfiguration {
private static final String configPath = "Configuration.xml"; // 配置文件
private static SqlSessionFactory sqlSessionFactory;
static {
init();
}
private MybatisConfiguration(){}
private static class SqlSessionFactoryInner {
private static final MybatisConfiguration INSTANCE = new MybatisConfiguration();
}
private static void init() {
try {
InputStream inputStream = Resources.getResourceAsStream(configPath);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
public static SqlSessionFactory getSqlSessionFactory() throws IOException {
return SqlSessionFactoryInner.INSTANCE.sqlSessionFactory;
}
}
工具类。
package com.local.demo;
import com.local.config.MybatisConfiguration;
import com.local.entity.UserDev;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import java.io.IOException;
import java.util.Date;
public class TestCase1 {
@Test
public void testFindOne() throws IOException {
SqlSessionFactory sqlSessionFactory = MybatisConfiguration.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
UserDev userDev = sqlSession.selectOne("com.local.mapper.UserDevMapper.findUserById", 1);
sqlSession.close();
System.out.print(userDev == null ? null : userDev.getUserName());
}
@Test
public void testAddOne() throws IOException {
SqlSessionFactory sqlSessionFactory = MybatisConfiguration.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
UserDev userDev = getUserDev();
int insert = sqlSession.insert("com.local.mapper.UserDevMapper.insertOne", userDev);
sqlSession.commit();
sqlSession.close();
System.out.print(insert);
}
public static UserDev getUserDev() {
UserDev userDev = new UserDev();
userDev.setAge(11);
userDev.setCreator("SYSTEM");
userDev.setGender(1);
userDev.setGmtCreated(new Date());
userDev.setGmtModified(new Date());
userDev.setIsDeleted("N");
userDev.setModifier("SYSTEM");
userDev.setUserName("YY");
return userDev;
}
}
初始化流程
可以看到对于开发人员来说整个流程是这样的:开始–>获取SqlSessionFactory–>通过SqlSessionFactory打开一个SqlSession–>通过SqlSession与数据库进行交互–>结束流程。
执行中是如何找到对应的sql的?
“com.local.mapper.UserDevMapper”是在UserMapper.xml中定义的namespace,再通过”findUserById”或者”insertOne”定位到对应的sql。
Mybatis Dao层
方式一
定义Dao层接口
package com.local.dao;
import com.local.entity.UserDev;
public interface UserDevDao {
UserDev selectOneById(int id);
int insertOne(UserDev userDev);
}
定义Dao层接口实现
package com.local.dao.impl;
import com.local.dao.UserDevDao;
import com.local.entity.UserDev;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class UserDevDaoImpl implements UserDevDao {
private SqlSessionFactory sqlSessionFactory;
public UserDev selectOneById(int id) {
SqlSession session = sqlSessionFactory.openSession();
UserDev userDev = null;
try {
userDev = session.selectOne("com.local.mapper.UserDevMapper.findUserById", id);
} finally {
session.close();
}
return userDev;
}
public int insertOne(UserDev userDev) {
SqlSession sqlSession = sqlSessionFactory.openSession();
int result = 0;
try {
result = sqlSession.insert("com.local.mapper.UserDevMapper.insertOne", userDev);
sqlSession.commit();
} finally {
sqlSession.close();
}
return result;
}
public UserDevDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
}
测试类
package com.local.demo;
import com.local.config.MybatisConfiguration;
import com.local.dao.UserDevDao;
import com.local.dao.impl.UserDevDaoImpl;
import com.local.entity.UserDev;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import java.io.IOException;
public class TestCase2 {
@Test
public void testFindOne() throws IOException {
SqlSessionFactory sqlSessionFactory = MybatisConfiguration.getSqlSessionFactory();
UserDevDao userDevDao = new UserDevDaoImpl(sqlSessionFactory);
UserDev userDev = userDevDao.selectOneById(1);
System.out.print(userDev == null ? null : userDev.getUserName());
}
@Test
public void testAddOne() throws IOException {
SqlSessionFactory sqlSessionFactory = MybatisConfiguration.getSqlSessionFactory();
UserDevDao userDevDao = new UserDevDaoImpl(sqlSessionFactory);
UserDev userDev = TestCase1.getUserDev();
int insert = userDevDao.insertOne(userDev);
System.out.print(insert);
}
}
方式二
定义Dao(Mapper)层接口
package com.local.mapper;
import com.local.entity.UserDev;
public interface UserDevMapper {
UserDev findUserById(int id);
int insertOne(UserDev userDev);
}
测试类
package com.local.demo;
import com.local.config.MybatisConfiguration;
import com.local.entity.UserDev;
import com.local.mapper.UserDevMapper;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import java.io.IOException;
public class TestCase3 {
@Test
public void testFindOne() throws IOException {
SqlSessionFactory sqlSessionFactory = MybatisConfiguration.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
UserDevMapper mapper = sqlSession.getMapper(UserDevMapper.class);
UserDev userDev = mapper.findUserById(1);
sqlSession.close();
System.out.print(userDev == null ? null : userDev.getUserName());
}
@Test
public void testAddOne() throws IOException {
SqlSessionFactory sqlSessionFactory = MybatisConfiguration.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
UserDevMapper mapper = sqlSession.getMapper(UserDevMapper.class);
UserDev userDev = TestCase1.getUserDev();
int insert = mapper.insertOne(userDev);
sqlSession.commit();
sqlSession.close();
System.out.print(insert);
}
}
配置文件细节
配置文件标签、Mapper配置文件标签、动态sql等就不说了。
缓存
Mybatis分为一级缓存(session)和二级缓存(全局)。
Mybatis逆向工程
所谓逆向工程就是通过数据库中创建的表生成对应的DO、DAO、Mapper等信息。
下一篇源码篇~