目前我本人正在学习MyBatis框架,在原先了解并且懵懵懂懂使用的基础上,开始系统正式的学习。目前已经阐述了MVC架构模式和三层架构,明晰了在Web项目中的普遍编码层次,认识了框架,回顾了JDBC连接数据库,介绍了MyBatis框架,初步建立了使用MyBatis和MySQL的Maven项目,简单解释了STDOUT_LOGGING日志和INSERT语句手动提交事务,记录了MyBatis中#占位符的使用方法,回顾了MyBatis执行SQL语句的过程和使用到的一些重要类和接口。本篇博客记录将一些固定化的代码整合到一个工具类MyBatisUtil中,以减少代码量。
我们在使用MyBatis的时候,如果需要执行一个SQL语句,总是需要加载总配置文件,然后创建SqlSessionFactoryBuilder对象,SqlSessionFactory对象,SqlSession对象。由于SqlSession不是线程安全的,因此每次需要执行SQL语句的时候,都需要新创建一个SqlSession对象。如果在不同的类中要执行SQL语句,上面的过程代码是不是需要重写很多遍啊!!!尽管我们可以复制粘贴,但是代码量很多啊!!!
那么,我们能不能将上面的过程代码作为一个行为方法封装到一个工具类里面呢?当我们需要执行SQL语句的时候,只需要在类中new出来一个工具类对象,然后调用这个行为方法之后就得到一个SqlSession对象呢?所以:MyBatisUtil工具类就诞生了!!
项目文件结构如下图所示:

POM文件代码如下所示:
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0modelVersion>
-
- <groupId>com.dcygroupId>
- <artifactId>MyBatis20220728artifactId>
- <version>1.0-SNAPSHOTversion>
-
- <properties>
- <maven.compiler.source>11maven.compiler.source>
- <maven.compiler.target>11maven.compiler.target>
- properties>
-
- <dependencies>
-
- <dependency>
- <groupId>junitgroupId>
- <artifactId>junitartifactId>
- <version>4.12version>
- <scope>testscope>
- dependency>
-
- <dependency>
- <groupId>org.mybatisgroupId>
- <artifactId>mybatisartifactId>
- <version>3.5.6version>
- dependency>
-
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <version>8.0.28version>
- dependency>
-
- dependencies>
- <build>
- <resources>
- <resource>
-
- <directory>src/main/javadirectory>
- <includes>
- <include>**/*.propertiesinclude>
- <include>**/*.xmlinclude>
- includes>
- <filtering>falsefiltering>
- resource>
- resources>
- build>
-
- project>
里面的依赖就是测试的junit依赖,mybatis的依赖,MySQL数据库驱动的依赖。最后由于mapper.xml文件没有写在resources目录下,因此需要有resources标签说明一下。
- configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
-
- <settings>
- <setting name="logImpl" value="STDOUT_LOGGING"/>
- settings>
- <environments default="development">
- <environment id="development">
- <transactionManager type="JDBC">transactionManager>
-
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
- <property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Hongkong&allowMultiQueries=true"/>
- <property name="username" value="root"/>
- <property name="password" value="123456"/>
- dataSource>
- environment>
- environments>
-
- <mappers>
- <mapper resource="com/dcy/dao/StudentDao.xml">mapper>
- mappers>
- configuration>
- mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
- <mapper namespace="com.dcy.dao.StudentDao">
- <select id="selectById" resultType="com.dcy.domain.Student">
- select id,name,email,age from student where id=#{studentId}
- select>
- <insert id="insertStudent">
- insert into student values (#{id},#{name},#{email},#{age})
- insert>
- <select id="selectStudents" resultType="com.dcy.domain.Student">
- select * from student
- select>
-
- mapper>
- package com.dcy.dao;
-
- import com.dcy.domain.Student;
-
- import java.util.List;
-
- public interface StudentDao {
- public Student selectById(Integer id);
- public List
selectStudents(); - public int insertStudent(Student student);
- }
- package com.dcy.domain;
-
- public class Student {
-
- //这里我们的属性名和数据库表中的列名保持一致,如果不一致的话我们需要在mapper.XML文件中配置或者是使用注解配置
-
- private Integer id;
- private String name;
- private String email;
- private Integer age;
-
- 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 String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public Integer getAge() {
- return age;
- }
-
- public void setAge(Integer age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "一个学生实体的信息{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", email='" + email + '\'' +
- ", age=" + age +
- '}';
- }
- }
这里我截一下图片,只展示表中字段名和字段类型:

- package com.dcy.utils;
-
- 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 java.io.IOException;
- import java.io.InputStream;
-
- /*
- 这个类是一个工具类,是为了解决 使用MyBatis执行SQL语句之前需要准备的对象太多的问题
- */
- public class MyBatisUtil {
- /*
- 静态代码块只会执行一次,在加载类的时候执行,先于Main方法执行
- */
- private static SqlSessionFactory factory=null;
- static {
- String config="mybatis.xml";
- try {
- InputStream inputStream = Resources.getResourceAsStream(config);
- factory= new SqlSessionFactoryBuilder().build(inputStream);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- //下面创建方法来获取SqlSession对象
- public static SqlSession getSqlSession(){
- SqlSession sqlSession=null;
- if (factory!=null){//说明存在SqlSessionFactory对象
- sqlSession=factory.openSession(true);//自动提交事务
- }
- return sqlSession;
- }
- }
首先是一个静态代码块。静态代码块只会执行一次,并且是在加载类的时候执行,先于Main方法执行。也就是我们启动项目以后,由于静态代码块的存在,这个类中就已经加载好了SqlSessionFactory这个对象,并且只有一个此对象。
然后又写了一个静态方法,我们只需要使用类名就可以调用这个方法,然后获得一个自动提交事务的SqlSession对象,然后可以使用这个对象的方法执行SQL语句。
- package com.dcy;
-
- import com.dcy.domain.Student;
- import com.dcy.utils.MyBatisUtil;
- import org.apache.ibatis.session.SqlSession;
-
- import java.util.List;
-
- public class starter {
- public static void main(String[] args) {
- //获取SqlSession对象
- SqlSession sqlSession= MyBatisUtil.getSqlSession();
- //拿到要执行的SQL语句的“地址”
- String SqlId="com.dcy.dao.StudentDao"+"."+"selectStudents";
- //执行SQL语句并拿到执行结果
- List
students = sqlSession.selectList(SqlId); - System.out.println(students);
- //关闭SqlSession对象
- sqlSession.close();
- }
- }
上面代码比较简单,我不多解释了,运行后控制台的结果如下所示:

因为在总配置文件中开启了STDOUT_LOGGING日志,所以打印的有日志。
上一篇博文解释了MyBatis执行SQL的具体过程和需要使用到的一些重要类和对象,感兴趣的读者可以移步阅读,链接如下: