摘要:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。在本文中,我们会学习一些mybatis的相关概念,以及搭建其开发环境以便快速入门。
作者:来自ArimaMisaki创作
说明:MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
当前,最新版本是MyBatis 3.5.9,其发布时间是2021年12月26日。
特性:
官网:入门_MyBatis中文网
下载:我们推荐使用maven来构建MyBatis项目。主要的方法是在pom.xml中导入下列坐标,也可以通过alt+insert搜索mybatis导入坐标。
org.mybatis
mybatis
x.x.x
步骤:
在pom.xml中配置所需的jar包
<dependencies>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.11version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.28version>
dependency>
dependencies>
创建数据库mybatis_test,并且创建一张名为t_user的表。
create table mybatis_test.t_user
(
id int auto_increment,
username varchar(255) null,
password varchar(255) null,
age int null,
gender char null,
email varchar(255) null,
constraint key_name
primary key (id)
);
新建一个实体类,里面是该表的各项数据。
package mybatis.pojo;
public class User {
private Integer id;
private String username;
private Integer age;
private String gender;
private String email;
public User(Integer id, String username, Integer age, String gender, String email) {
this.id = id;
this.username = username;
this.age = age;
this.gender = gender;
this.email = email;
}
public User(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", email='" + email + '\'' +
'}';
}
}
创建配置文件;习惯上将配置文件名命名为mybatis-config.xml
;配置文件主要用于配置链接数据库的环境和mybatis的全局配置信息;在配置文件中,记得自己修改对应的jdbc驱动、数据库地址、用户名和密码;里面的mappers标签包裹的mapper的rosouce属性值为mybatis的映射文件。何为映射文件?我们可以理解为sql语句啥的不会写在该配置文件中,而是从新建立一个.xml后缀的文件来书写sql语句,该文件我们用术语映射文件
来称呼他。
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource=""/>
mappers>
configuration>
创建一个mapper接口。该接口可以理解为以前的dao,但是区别在于mapper仅仅是接口,而无需提供实现类。接口名一般看操作哪个表,如操作t_user表就把接口命名为UserMapper;我们在该接口中还书写了一个表插入数据的insertUser
方法。
public interface UserMapper{
int insertUser();
}
创建一个映射文件;其中有个概念为ORM(对象关系映射);一般映射文件的命名遵循表的实体类类名+Mapper.xml
,如我们现在要创建一个名为UserMapper.xml
文件,这侧面可以看出一个映射文件对应一个表和一个实体类;映射文件主要用于编写SQL,访问以及操作表中的数据。映射文件的模板可以在官网找到,需要注意的是,其中的namespace用于和mapper接口关联,也就是说namespace需要填入接口在项目中的位置;而mapper标签中的子标签可以根据不同的操作选择不同的子标签,我们这里选择insert插入标签
,并且配置属性id为对应接口中书写的插入方法,做完这些,我们就可以在insert标签中写上sql语句了。
上面的话可能稍显复杂,但是完美阐述了配置的过程。我们总结一下mapper配置文件需保持两个一致:命名空间和接口名一致;接口的方法名和映射文件中sql操作标签的id一致。
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mybatis.mapper.UserMapper">
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男','[email protected]')
insert>
mapper>
返回mybatis配置文件,将mapper标签中的resource属性值写上映射文件对应的路径。
创建一个MyBatisTest测试类
package mybatis.test;
import mybatis.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
// 1.需要调用mybatis提供的方法来获取mybatis的配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 3.通过构建器来根据输入流生成一个一个sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 4.获取sql的会话对象sqlSession,该对象用于操作数据库
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5.获取UserMapper代理对象,底层使用了代理模式,帮我们创建了一个代理实现类
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 6.可以调取接口的方法了
int result = mapper.insertUser();
System.out.println(result);
// 7.调取后的方法虽然执行了,但没有持久化到数据库(未提交事务)
sqlSession.commit();
// 8.关闭会话
sqlSession.close();
}
}
查看数据库数据是否添加成功
说明1:在测试类中我们写了不少代码,但是有很多代码都是被重复使用的,故我们可以将其封装到工具类lib中的某个方法中,这样就可以减少代码量。
// 1.需要调用mybatis提供的方法来获取mybatis的配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 3.通过构建器来根据输入流生成一个一个sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 4.获取sql的会话对象sqlSession,该对象用于操作数据库
SqlSession sqlSession = sqlSessionFactory.openSession();
说明2:如果不想通过获取mapper接口的代理对象再调用其方法,那我们可以通过sqlSession.insert(namespace.sqlId)
的方式来调用接口中的方法,但这种方式较少使用。
package mybatis.test;
import mybatis.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
// 1.需要调用mybatis提供的方法来获取mybatis的配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 3.通过构建器来根据输入流生成一个一个sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 4.获取sql的会话对象sqlSession,该对象用于操作数据库
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5.获取UserMapper代理对象,底层使用了代理模式,帮我们创建了一个代理实现类
// UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 6.可以调取接口的方法了
// int result = mapper.insertUser();
int result = sqlSession.insert("mybatis.mapper.UserMapper.insertUser");
System.out.println(result);
// 7.调取后的方法虽然执行了,但没有持久化到数据库(未提交事务)
sqlSession.commit();
// 8.关闭会话
sqlSession.close();
}
}
说明3:如果不想每次写完sql后都调用sqlSession来提交事务,则在开启会话时,即调用sqlSessionFactory.openSession
方法时,可以通过其构造器传入参数true,其对应开启autoCommit
属性。
package mybatis.test;
import mybatis.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
@Test
public void testInsert() throws IOException {
// 1.需要调用mybatis提供的方法来获取mybatis的配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 2.获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 3.通过构建器来根据输入流生成一个一个sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 4.获取sql的会话对象sqlSession,该对象用于操作数据库
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 5.获取UserMapper代理对象,底层使用了代理模式,帮我们创建了一个代理实现类
// UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 6.可以调取接口的方法了
// int result = mapper.insertUser();
int result = sqlSession.insert("mybatis.mapper.UserMapper.insertUser");
System.out.println(result);
// 7.调取后的方法虽然执行了,但没有持久化到数据库(未提交事务)
// sqlSession.commit();
// 8.关闭会话
sqlSession.close();
}
}
搭配步骤:
在pom.xml中导入log4j坐标
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.12version>
dependency>
新建log4j.xml配置文件
DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}
%m (%F:%L) \n" />
layout>
appender>
<logger name="java.sql">
<level value="debug" />
logger>
<logger name="org.apache.ibatis">
<level value="info" />
logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
root>
log4j:configuration>