1 MyBatis入门
摘要:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。在本文中,我们会学习一些mybatis的相关概念,以及搭建其开发环境以便快速入门。作者:来自ArimaMisaki创作
[TOC]
1.1 历史
说明: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日。
1.2 特性
特性:
- MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
- MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
- MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
- MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架
1.3 下载
下载:我们推荐使用maven来构建MyBatis项目。主要的方法是在pom.xml中导入下列坐标,也可以通过alt+insert搜索mybatis导入坐标。
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
1.4 搭建开发环境
步骤:
在pom.xml中配置所需的jar包
<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.11</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </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语句,该文件我们用术语映射文件
来称呼他。<?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> <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一致。
<?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="mybatis.mapper.UserMapper"> <insert id="insertUser"> insert into t_user values(null,'admin','123456',23,'男','12345@qq.com') </insert> </mapper>
返回mybatis配置文件,将mapper标签中的resource属性值写上映射文件对应的路径。
<?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> <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/UserMapper.xml"/> </mappers> </configuration>
创建一个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.5 优化测试类
说明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();
}
}
1.6 搭配日志框架
搭配步骤:
在pom.xml中导入log4j坐标
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency>
新建log4j.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!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>