配置Mybatis环境
MyBatis是什么
MyBatis 一个支持普通 SQL 查询、存储过程以及高级映射的持久层框架。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,使得开发者可以更专注于 SQL 本身,而不必花费过多精力在繁琐的数据库操作细节上。
最原始的JDBC操作数据库的方式有以下问题:
- 数据库连接频繁创建、释放浪费资源进而影响系统性能;
- sql代码写在 java文件当中,如果在开发过程中我们改动某个sql,就需要去修改java代码,改完之后还需要重新编译;
- 对结果集的解析也是硬编码,对查询结果的解析过程依赖于硬编码的字段信息和显式的数据类型转换,缺乏灵活性和动态性,sql变化会导致解析结果的代码也跟着变化,系统不易维护。
针对 JDBC 编程的劣势,MyBatis 提供了以下解决方案:
- 在 SqlMapConfig.xml 中配置数据连接池,使用连接池管理数据库链接,避免了连接频繁创建和释放;
- 将 SQL 语句分离到配置文件中,MyBatis 允许将 SQL 语句写在 XML 映射文件或使用注解的方式定义,与 Java 业务代码完全分离;
- 提供自动映射机制,MyBatis 可以根据 SQL 查询结果的列名与 Java 实体类的属性名进行自动匹配,将结果集自动封装为对应的实体对象,无需手动编写结果集解析代码。
配置Mybatis环境
首先我们需要创建数据库和表结构准备数据
sql
create database mybatis_demo;
use mybatis_demo;
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime default NULL COMMENT '生日',
`sex` char(1) default NULL COMMENT '性别',
`address` varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'老王','2018-02-27
17:47:08','男','北京'),(2,'熊大','2018-03-02 15:09:37','女','上海'),(3,'熊二','2018-03-04
11:34:34','女','深圳'),(4,'光头强','2018-03-04 12:04:06','男','广州');
创建结果如下:

我们需要去官网下载 MyBatis,在D盘根目录解压下载的MyBatis文件 apache-maven-3.6.2,再新建 maven 文件夹用于存项目开发jar包

接下来我们需要创建maven的项目,打开IDEA,点击 Project -> New Project -> Maven -> next 即可创建成功

自动进入刚创建好的maven项目,我们点击 File -> Settings,进行maven配置

稍等几秒钟IDEA解析依赖项,创建成功的样子如图:

导入maven相关依赖配置,用于声明项目运行或编译时需要依赖的第三方库(Jar 包),Maven 会根据这些配置自动下载并管理这些依赖,在pox.xml中追加MyBatis的3.4.5的版本的坐标、MySQL驱动的jar包、Junit单元测试的jar包、log4j日志jar包内容进行配置:
xml
<dependencies>
<!--mybatis核心包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
再点击右上角图标进行加载jar包,稍等几秒就加载成功了

接下来我们需要创建 SqlMapConfig.xml 文件,是整个框架的核心配置入口,主要用于配置 MyBatis 的运行环境、数据库连接信息、类型别名、映射文件路径等关键信息。
下图是创建SqlMapConfig.xml模板内容,按照模板创建SqlMapConfig.xml文件,这里我们需要配置数据库环境,可以配置多个environment环境,通过 default 属性指定默认环境,以及配置 Mapper 映射文件的路径,告诉 MyBatis 去哪里找映射文件。

xml
<?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>
<!-- settings:控制mybatis的全局行为-->
<settings>
<!--设置mybatis输出日志-->
<!--logImpl:表示对日志的控制-->
<!--STDOUT_LOGGING:将日志输出到控制台上-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<environments default="mysql">
<environment id="mysql">
<!--配置事务的类型,使用本地事务策略-->
<transactionManager type="JDBC"></transactionManager>
<!--是否使用连接池 POOLED表示使用链接池,UNPOOLED表示不使用连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
创建 entity 包,在包中编写 User 的实体类,用于封装 User 对象的属性,该代码中的属性尽量使用包装类型,同时各变量名称需要与数据库里的保持一致,具体的代码如下(快捷键alt+enter:导入类; alt+insert:添加Getter、Setter、toString方法):
java
package com.qcby.entity;
import java.util.Date;
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public User(){};
public User(String username, Date birthday, String sex, String address) {
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
@Override
public String toString() {
return "User{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';
}
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 Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
创建 dao 包,在包中创建 UserDao 接口,并且定义方法,接口将使用与实现分离,调用者只需依赖接口,无需依赖具体实现类,当需要替换实现时,只需更换实现类无需修改调用代码,降低了代码间的耦合度。
java
package com.qcby.dao;
import com.qcby.entity.User;
import java.util.List;
public interface UserDao {
public List<User> findAll();
}
在resources目录下,创建mapper文件夹编写 Mapper 映射文件用于管理sql语句,创建UserMapper.xml文件模板新建mybatis-mapper.xml文件,如图

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.qcby.dao.UserDao">
<select id="findAll" resultType="com.qcby.entity.User">
select * from user
</select>
</mapper>
mapper namespace="com.qcby.dao.UserDao"
是名称空间,该文件相当于是UserDao接口的实现类,实现类要实现接口中的方法
select id="findAll"
中的id属性是方法名,实现UserDao接口中方法的名称
parameterType
指定输入参数的类型,resultType
指定输出结果的类型
在Test文件下创建测试类sqlsession会话Userdao.java:
java
import com.qcby.Dao.UserDao;
import com.qcby.entity.User;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class UserTest {
private InputStream in = null;
private SqlSession session = null;
private UserDao mapper = null;
@Before //前置通知, 在方法执行之前执行
public void init() throws IOException {
//加载主配置文件,目的是为了构建SqlSessionFactory对象
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//通过SqlSessionFactory工厂对象创建SqlSesssion对象
session = factory.openSession();
//通过Session创建UserDao接口代理对象
mapper = session.getMapper(UserDao.class);
}
@After //@After: 后置通知, 在方法执行之后执行 。
public void destory() throws IOException {
//释放资源
session.close();
in.close();
}
@Test
public void findAll(){
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user.toString());
}
}
}
@Before
前置通知,在方法执行之前执行。init() 该方法初始化MyBatis框架的核心组件,通过逐步创建核心对象,完成了从配置文件加载到数据访问层对象初始化的全流程,为后续数据库操作做准备。首先,方法通过MyBatis提供的Resources工具类,调用getResourceAsStream方法读取类路径下名为SqlMapConfig.xml的主配置文件,将文件内容以输入流in的形式加载到内存中,这个配置文件包含了数据库连接信息、映射文件路径等关键配置;接着,创建SqlSessionFactoryBuilder构建者对象,并调用其build方法,传入前面获取的配置文件输入流,由此构建出SqlSessionFactory会话工厂对象,它是MyBatis框架的核心工厂,负责管理数据库会话的创建;然后,通过SqlSessionFactory的openSession方法创建SqlSession会话对象,SqlSession就像Java程序与数据库之间的桥梁,后续所有的数据库操作都需要通过它来完成;最后,调用SqlSession的getMapper方法,传入UserDao接口的字节码对象,MyBatis会通过动态代理技术在运行时生成UserDao接口的代理实现类对象,并将其赋值给userDao变量,这个代理对象内部已经整合了SQL执行逻辑,后续只需调用userDao的方法就能直接操作数据库。
@Test
注解用于标识这是一个可独立运行的测试用例。方法内部的逻辑是:首先调用之前通过动态代理生成的userDao对象的findAll方法,这个方法会触发MyBatis执行对应的SQL查询,并将查询结果封装成User
对象的集合List;接着通过增强for循环遍历这个用户集合,对集合中的每个User对象调用toString()方法,将用户的详细信息转换为字符串并打印到控制台。整个方法的作用是测试UserDao接口中findAll方法的功能是否正常,通过执行查询并输出结果,验证数据库查询操作是否能正确获取并展示所有用户数据。
@After
是后置通知注解,它的作用是指定该方法会在当前测试类中每个测试方法执行完毕之后自动运行。方法内部主要实现了资源释放的功能:首先通过session.close()关闭SqlSession对象,SqlSession作为Java程序与数据库交互的会话桥梁,使用完毕后关闭可以释放数据库连接等资源,避免连接泄露;接着通过in.close()关闭之前打开的配置文件输入流in,输入流属于IO资源,及时关闭能释放系统文件句柄等资源,防止资源耗尽。整个方法的核心作用就是在测试方法执行完成后,清理初始化阶段创建的资源,保证资源的合理使用和系统的稳定运行。
findAll() 方法的实现结果如图:
