Bootstrap

1月月更|推荐学Java——第一个MyBatis程序

本文首发于公众号`推荐学java`,

什么是 MyBatis

一款优秀的持久层框架。MyBatis 使用 XML 将 SQL 与程序解耦,便于维护。MyBatis 学习成本低,执行高效,底层是对 JDBC 的封装和扩展。

  • MyBtis官网:

  • github地址:

tips:本文所涉及的源码和数据表,在公众号 回复 即可获得。

创建一个 MyBatis 项目的整体流程

以上 6 点,其中前 3 点之前的内容都有实战,这里不再做详细介绍,4 和 5 是本节的核心内容,最后一点不在本节内容实战,等学完 SSM 综合框架后,会专门做讲解,那个时候也更适合一些。

保证项目与数据库链接成功

1、创建数据表

一条记录是一部电视剧的简单记录,包括这些信息:

:主键自增,不可为空。

:电视剧名称,也就是标题,不可为空。

:电视剧描述,也可以是子标题宣传短文本。

:电视剧的类型,这里列举了 、、、、、 6 类。

2、创建基于 Maven 的 Java 项目

创建步骤这里不做解释,需要提示一点,当创建项目点击了最后的 按钮后,在新的 IDE 窗口中右下角会出现如下图提示,记得点击这里箭头标注的地方:

如果你能看到红框标注的信息,这就说明项目是构建成功的。可以接下来的工作啦!

3、完成项目基本配置

下图是在创建完成后的项目结构基础上,增加了必须的配置,大家可以跟自己创建的新项目对比一下,箭头标注的都是需要手动创建的:

这里做具体的解释,操作步骤基本都是“套路”,哈哈

   package com.javafirst.bean;
   
   /**
    * desc: 数据表对应的 java 实体类
    * author weChat: studyingJava
    */
   public class TVSeriesBean {
   
       private int tvId;
       private String tvTitle;
       private String tvSubTitle;
       private int tvType;
   
       public int getTvId() {
           return tvId;
       }
   
       public void setTvId(int tvId) {
           this.tvId = tvId;
       }
   
       public String getTvTitle() {
           return tvTitle;
       }
   
       public void setTvTitle(String tvTitle) {
           this.tvTitle = tvTitle;
       }
   
       public String getTvSubTitle() {
           return tvSubTitle;
       }
   
       public void setTvSubTitle(String tvSubTitle) {
           this.tvSubTitle = tvSubTitle;
       }
   
       public int getTvType() {
           return tvType;
       }
   
       public void setTvType(int tvType) {
           this.tvType = tvType;
       }
   
       @Override
       public String toString() {
           return "TVSeriesBean打印信息:\n{" +
                   "tvId=" + tvId +
                   ", tvTitle='" + tvTitle + '\'' +
                   ", tvSubTitle='" + tvSubTitle + '\'' +
                   ", tvType=" + tvType +
                   '}';
       }
   
   }

这里手动生成了 、 方法,其实还有一些插件可以自动搞定,这里先不做用法,不适合新手。

package com.javafirst.dao;

import com.javafirst.bean.TVSeriesBean;

import java.util.List;

/**
 * desc: 与数据库操作的相关业务接口
 * 

* author weChat: studyingJava */ public interface TVSeriesDao { /** * 根据 id 查询某部电视剧 * * @param tvId * @return */ TVSeriesBean selectTVSeriesById(Integer tvId); /** * 查询所有电视剧 * * @return */ List selectTVSeriesAll(); /** * 添加一条记录(电视剧)通过字段方式 * * @param title * @param subTitle * @param type */ void addTVSeriesOne(String title, String subTitle, int type); /** * 添加一条记录(电视剧)通过对象方式 * * @param tvSeriesBean */ void addTVSeriesObject(TVSeriesBean tvSeriesBean); }

   
   
   
   
   
   

这里其他的都是固定写法,唯一需要改变的是 标签里的 的值,很熟悉吧,这个值就是我们前面已经创建过的 的全路径。

标签里面的节点,就是我们日常操作表的 xml 语法,包括 、 、 、 这些标签,而这些标签里面的内容就是我们在章节学习过的 语句。具体本文后面会给出示例代码。

   
   
   
   
       
           
           
               
               
                   
                   
                   
                   
                   
                   
                   
                   
               
           
   
       
   
       
           
           
       
   

同样这里的代码基本都是模板,只需要修改几个关键地方就可以了。

   
                   
                   
                   
                   
                   

  • 这里小编是在本地跑项目,所以 的值 是本地的,如果你在安装 的时候修改了端口号,那么这里要使用你修改过的;

  • 是我们前面创建的数据库的名字,也就是本节内容整体流程里的第一步;

  • 值对应的是你登录mysql的账户名,这在我们一节里讲解过了;

  • 值对应的是你登录mysql的密码;

   
   
   
       4.0.0
   
       com.javafirst
       TV_series
       1.0
   
       
       
       
       
   
       
           UTF-8
           1.8
           1.8
       
   
       
           
           
               junit
               junit
               4.11
               test
           
   
           
           
               mysql
               mysql-connector-java
               8.0.25
           
   
           
           
               org.mybatis
               mybatis
               3.5.7
           
       
   
       
           
               
                   
                   
                       maven-clean-plugin
                       3.1.0
                   
                   
                   
                       maven-resources-plugin
                       3.0.2
                   
                   
                       maven-compiler-plugin
                       3.8.0
                   
                   
                       maven-surefire-plugin
                       2.22.1
                   
                   
                       maven-jar-plugin
                       3.0.2
                   
                   
                       maven-install-plugin
                       2.5.2
                   
                   
                       maven-deploy-plugin
                       2.8.2
                   
                   
                   
                       maven-site-plugin
                       3.7.1
                   
                   
                       maven-project-info-reports-plugin
                       3.0.0
                   
               
           
       
   

比如后期要用到什么三方的框架之类的,都可以在上节内容提到的 搜索配置,然后添加到这里,这就是 maven 的方便之处。

   package com.javafirst.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;
   
   /**
    * desc:MyBatis工具类
    * 

* author weChat: studyingJava */ public class MyBatisUtil { private static SqlSessionFactory sqlSessionFactory = null; static { String configXml = "mybatis-config.xml"; try { InputStream inputStream = Resources.getResourceAsStream(configXml); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession openSqlSession() { SqlSession sqlSession = null; if (null != sqlSessionFactory) { sqlSession = sqlSessionFactory.openSession(); } else { String configXml = "mybatis-config.xml"; try { InputStream inputStream = Resources.getResourceAsStream(configXml); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); sqlSession = sqlSessionFactory.openSession(); } catch (IOException e) { e.printStackTrace(); } } return sqlSession; } }

之所以会有这个工具类,是因为我们要避免重复的代码,关于为什么这样写,大家可以在 官网查看。

下面就开始写功能代码,测试链接数据,激动人心的时刻要到来了!

4、测试链接成功

本文的核心是 ,现在我们就测试下 与数据库链接是否成功,代码如下:

@Test
public void testSqlConnection() {
    SqlSession sqlSession = MyBatisUtil.openSqlSession();
    System.out.println("测试 MyBatis 链接数据库驱动:" + sqlSession.toString());
}

这段代码大家自行新建一个java类,然后写上这段代码,进行单元测试,结果如下图,则为链接成功,说明前面的 里的配置没有出错。

操作数据表

接下来就可以操作数据库中的表了,在本文的最开始我们新建了一张表,里面没有任何数据,现在我们先来做一次查询,然后再做一次插入数据,再做一次全部查询,证明我们通过java项目可以操作数据库。

   /**
    * 查询所有记录
    */
   @Test
   public void testSelectTVSeriesAll() {
       SqlSession sqlSession = MyBatisUtil.openSqlSession();
       TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);
       List tvSeriesBeans = tvSeriesDao.selectTVSeriesAll();
       sqlSession.close();
   
       System.out.println("查询所有记录(电视剧):" + tvSeriesBeans.size());
       for (TVSeriesBean tvSeries : tvSeriesBeans) {
           System.out.println(tvSeries);
       }
   }

对应的 中的 语句如下:

   
   
       
       
   

需要注意,这里的 ,需要和我们 中定义的接口名保持一致。

sql 语句和我们以往不同的是,这里不再需要以 `;` 结尾了。执行后的结果如下则为正确。

   /**
    * 添加一条记录 通过字段方式
    */
   @Test
   public void testAddTVSeriesOne() {
       SqlSession sqlSession = MyBatisUtil.openSqlSession();
       TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);
   
       tvSeriesDao.addTVSeriesOne("《射雕英雄传》", "金庸武侠经典之作,永久传承", 1);
       sqlSession.commit();
       sqlSession.close();
   
       System.out.println("添加记录成功!");
   }

添加记录的时候相比于查询需要多一步操作,就是 ,这个要和我们之前学过的事务有关,MySQL 是默认开启事务的,所以插入记录后,我们需要手动提交事务才起作用。当然我们也可以在 工具类中在初始化 的时候通过参数来指定默认自动提交,即:

   sqlSession = sqlSessionFactory.openSession(true);

对应的 文件中的 标签内容如下:


    insert into tv_series (tv_title,tv_sub_title,tv_type) values (#{param1},#{param2},#{param3})

如果使用字段方式,这里的列值(也叫参数)推荐使用 这种方式,否则可能会遇到坑。

执行结果如下,则正确插入一条记录,此时,可以打开 查看表中数据(这里不展示截图了)。

第二种方式

java代码如下

/**
 * 添加一条记录 通过对象方式
 */
@Test
public void testAddTVSeriesObject() {
    SqlSession sqlSession = MyBatisUtil.openSqlSession();
    TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);

    TVSeriesBean tvSeriesBean = new TVSeriesBean();
    tvSeriesBean.setTvTitle("《天龙八部》");
    tvSeriesBean.setTvSubTitle("北宋末年,宋辽边境冲突不断,一场大阴谋正在悄然来袭...");
    tvSeriesBean.setTvType(2);

    tvSeriesDao.addTVSeriesObject(tvSeriesBean);
    sqlSession.commit();
    sqlSession.close();

    System.out.println("添加记录成功!!");
}

对应的 文件中的 标签内容如下:


    insert into tv_series (tv_title,tv_sub_title,tv_type) values (#{tvTitle},#{tvSubTitle},#{tvType})

这里需要注意传参(列值),这种方式需要和自定义的实体类中的字段值保持一致,否则会出现映射异常。

到这一步,我们已经添加了两条记录了,用我们前面的查询所有记录测试方法,看看是否真的有两条数据,看下图:

注意到没? 奇怪的问题发生了,数据总数是合适的,但是每条记录都显示为 ,这明显是不对的,因为我们已经重写了 方法啊。

细心的同学有没注意到我们在前面第一步写实体类的时候,提到使用驼峰命名才能和数据表中带有下划线的字段对应(映射)起来,但我们没有在 中配置打开驼峰匹配开关,现在添加如下代码:

 
 
     
 

再次执行查询结果如下:

这是初学者需要注意的一个点,切记!

   /**
     * 删除一条记录 根据ID
     */
    @Test
    public void testDeleteTVSeriesBeanById() {
        SqlSession sqlSession = MyBatisUtil.openSqlSession();
        TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);
   
        tvSeriesDao.deleteTVSeriesBeanById(2);
        sqlSession.commit();
        sqlSession.close();
   
        System.out.println("删除一条记录成功!!");
    }

到这还没有完,还需要在 中增加如下代码:

    
    
        delete from tv_series where tv_id = #{tvId}
    

到这就可以运行测试方法了,结果如下:
![根据ID删除一条记录](https://gitee.com/codexiaosheng/md-pictures/raw/master/2021-12-16/1639648382954-image.png)
可以通过再次查询或者直接查看数据库中表的数据证明结果的正确性,这里就不贴图了。

细心的同学有没有发现,当我们前期的工作搞定之后,剩下的基本都是固定的操作模式,需要修改的地方都很流程化。

   /**
    * 根据ID 来修改标题
    * @param tvId
    */
   void updateTVSeriesBeanTitleById(Integer tvId,String tvTitle);

`TVSeriesMapper.xml` 中代码:

   
   
       update tv_series set tv_title = #{param2} where tv_id = #{param1}
   

测试方法代码:

   /**
    * 修改指定记录的数据
    */
   @Test
   public void testUpdateTVSeriesBeanTitleById() {
       SqlSession sqlSession = MyBatisUtil.openSqlSession();
       TVSeriesDao tvSeriesDao = sqlSession.getMapper(TVSeriesDao.class);
   
       tvSeriesDao.updateTVSeriesBeanTitleById(1, "《新版射雕英雄传》");
       sqlSession.commit();
       sqlSession.close();
   
       System.out.println("update一条记录成功!!");
   }

执行结果如下:
![update记录成功](https://gitee.com/codexiaosheng/md-pictures/raw/master/2021-12-16/1639649648509-image.png)
此时打开数据库,或者再次执行查询查看结果,就是我们修改过的结果。

到这里,我们的基本增删改查都已经实操了一遍,这是核心内容,关于前期项目配置那一套,自己实操一遍,把流程记录下来,这就是本节的核心内容。

但本节的操作都是基于单表,操作业务特别单一简单,比如我们插入一条数据现在是没有任何途径证明是插入成功的,那么能不能插入后给我返回该条记录的主键呢?删除也是相同的道理,因为真实业务中我们不可能每次都查看数据库,而且大项目中,表中的记录可能千万条,查看也不现实,所以关于 MyBatis 的高级内容后面章节就会讲解到,大家赶紧撸码吧~~

总结

  • MyBatis 是一个框架,掌握其使用流程和高级用法是一个合格Java工程师必备条件

  • 前期学习的 SQL 知识要熟练掌握,本节的内容亦是如此,知识环环相扣

  • 学习编程没有捷径,埋头苦练即可

本文所涉及的源码和数据表,在公众号 回复 即可获得。

小编特意创建了一个公众号:,分享原创 内容,欢迎大家搜索关注(关注即送精品视频教程),一起学Java,下次见!