MyBatis持久层

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: JavaEE 企业级 Java 项目中的经典三层架构为表现层,业务层和持久层,使用Java 代码操作数据库属于持久层内容,而 MyBatis 对 JDBC 代码进行了封装,作为一款优秀的持久层框架,专门用于简化JDBC开发。

1. 前言

JavaEE 企业级 Java 项目中的经典三层架构为表现层,业务层和持久层,使用Java 代码操作数据库属于持久层内容,而 MyBatis 对 JDBC 代码进行了封装,作为一款优秀的持久层框架,专门用于简化JDBC开发。




MyBatis 支持自定义 SQL,存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型,接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。


MyBatis 本是 Apache 的一个开源项目 iBatis, 2010 年这个项目由 Apache software foundation 迁移到了google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。


小tips:在学习一门全新的技术前,尽量做到从头到尾通读官网信息,MyBatis 的中文版官网相比于其他的网站还是非常友好的,建议首先阅读官网信息。


什么是框架呢?


框架的概念其实不难理解,这里的框架是指一个半成品的软件,是一套可重用,通用的,软件基础代码模型,在框架基础之上构建项目使编码更加高效,规范,通用并且扩展性强。


2. JDBC 存在的缺点

之前使用 JDBC 代码操作数据库时,我们一般分为注册驱动,获取连接,定义sql,设置参数值,获取 sql 执行对象,执行 sql,处理返回数据,释放资源等几个步骤。下面使用一个简单的例子分析 JDBC 究竟存在哪些缺点。


需求:使用 Java 代码操作数据库,查询学生表中所有男生信息,并且将其封装为对象,最终存放在集合中。


public class JDBCDemo {


   public static void main(String[] args) throws Exception {

       //1. 注册驱动

       Class.forName("com.mysql.jdbc.Driver");

       //2. 获取连接

       String url = "jdbc:mysql://localhost:3306/blog?useSSL=false";

       String username = "root";

       String ppassword = "abc123";//密码

       Connection conn = DriverManager.getConnection(url, username, password);

       //接收输入的查询条件

       String gender = "男";

       //3. 定义sql

       String sql = "select * from student where gender=?";

       //4. 获取sql执行对象

       Statement stmt = conn.createStatement();

       //设置参数的值

       pstmt.setString(1,gender);

       //5. 执行sql

       ResultSet rs = stmt.executeQuery(sql);

       //6. 处理结果

       //遍历结果集,获取数据,封装为对象,装入集合

       Student s = null;

       List<Student> students = new ArrayList<>();

       while (rs.next()) {

           s = new Student();

           int id = rs.getInt(1);

           String name = rs.getString(2);

           String gender = rs.getString(3);


           s.setId(id);

           s.setName(name);

           s.setGender(gender);


           students.add(s);

       }

       System.out.println(students);

       //7. 释放资源

       rs.close();

       stmt.close();

       conn.close();

   }

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

上面是一段简单标准的使用 JDBC 操作数据库的代码,分析代码我们不难看出,在注册驱动,获取连接和定义 sql 部分,代码中出现了大量的字符串信息,这些字符串信息非常不利于后期的维护,例如后期修改要连接的数据库等。我们把这个问题称为 JDBC 的硬编码问题。示例,存在硬编码问题的代码:


//1. 注册驱动

Class.forName("com.mysql.jdbc.Driver");

//2. 获取连接

String url = "jdbc:mysql://localhost:3306/blog?useSSL=false";

String username = "root";

String ppassword = "abc123";//密码

Connection conn = DriverManager.getConnection(url, username, password);

//接收输入的查询条件

String gender = "男";

//3. 定义sql

String sql = "select * from student where gender=?";

1

2

3

4

5

6

7

8

9

10

11

在手动设置参数,封住结果集对象部分,代码中出现了大量的相似代码,例如将来的参数较多时,手动设置参数也是一件麻烦的事情等,这个问题被称为 JDBC 的操作繁琐问题。示例,存在操作繁琐问题的代码:


//设置参数的值

pstmt.setString(1,gender);

//5. 执行sql

ResultSet rs = stmt.executeQuery(sql);

//6. 处理结果

//遍历结果集,获取数据,封装为对象,装入集合

Student s = null;

List<Student> students = new ArrayList<>();

while (rs.next()) {

   s = new Student();

   int id = rs.getInt(1);

   String name = rs.getString(2);

   String gender = rs.getS  

   s.setId(id);

   s.setName(name);

   s.setGender  

   students.add(s);

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

JDBC的缺点,如下图:




3. MyBatis 优化

JDBC 作为基础性的代码,固然会出现很多操作繁琐等的问题,那么这个问题怎么解决呢?前面说使用 MyBatis 简化 JDBC 开发,那么具体是怎么避免这些问题的呢?


首先,要解决操作繁琐的问题,只需要让JDBC中手动设置参数和手动封装结果集对象的操作由程序自动封装完成。例如下面一行代码就解决了 JDBC 封装结果集对象操作繁琐的问题:


List<Student> students = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的namespace.id

1

MyBatis 将注册驱动,获取连接,定义sql 的语句从 Java 代码中抽离,并单独写到配置文件中,解决了硬编码的问题。例如:在 mybatis-cinfig.xml 配置文件中定义数据库连接信息。


4. MyBatis 快速入门

每一个初学者,在学习一门全新的技术时,都要在实战练习中掌握其使用方法。今天,我们使用一个小小的案例来入门 MyBatis,学会 MyBatis 的基本使用。


需求:查询数据库中 student 表中所有的数据。


我们使用以下 5 个步骤来解决这个问题:


创建 student 表,添加数据


创建新项目,创建Maven模块,导入坐标


编写MyBatis核心配置文件


编写sql映射文件


编写代码


定义 POJO实体类

加载核心配置文件,获取 SqlSessionFactory 对象

获取 SqlSession 对象,执行 sql 语句

释放资源

接下来,我们按照上面的步骤讲解需求中的问题,学习 MyBatis 的基本使用。下面为详细过程和代码演示,整个过程的分析参考文末的过程剖析。


第一步:创建 student 表,添加数据


drop table if exists student;


create table student(

id int primary key auto_increment,

name varchar(10),

gender char(1)

);


insert into student(name,gender) values

('张三','男'),

('李四','女'),

('王五','男');

1

2

3

4

5

6

7

8

9

10

11

12

第二步:


创建空项目,创建 Maven 模块,项目结构如下图:




在创建好的模块中的 pom.xml 配置文件中添加依赖坐标,点击刷新使坐标信息生效:


<dependencies>

   <!--mybatis 依赖-->

   <dependency>

       <groupId>org.mybatis</groupId>

       <artifactId>mybatis</artifactId>

       <version>3.5.5</version>

   </dependency>


   <!--mysql 驱动-->

   <dependency>

       <groupId>mysql</groupId>

       <artifactId>mysql-connector-java</artifactId>

       <version>5.1.46</version>

   </dependency>


   <!--junit 单元测试-->

   <dependency>

       <groupId>junit</groupId>

       <artifactId>junit</artifactId>

       <version>4.13</version>

       <scope>test</scope>

   </dependency>


   <!-- 添加slf4j日志api -->

   <dependency>

       <groupId>org.slf4j</groupId>

       <artifactId>slf4j-api</artifactId>

       <version>1.7.20</version>

   </dependency>

   <!-- 添加logback-classic依赖 -->

   <dependency>

       <groupId>ch.qos.logback</groupId>

       <artifactId>logback-classic</artifactId>

       <version>1.2.3</version>

   </dependency>

   <!-- 添加logback-core依赖 -->

   <dependency>

       <groupId>ch.qos.logback</groupId>

       <artifactId>logback-core</artifactId>

       <version>1.2.3</version>

   </dependency>

</dependencies>


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

在 resources 目录下创建 logback 的配置文件 logback.xml,用于查看日志信息:


<?xml version="1.0" encoding="UTF-8"?>

<configuration>

   <!--

       CONSOLE :表示当前的日志信息是可以输出到控制台的。

   -->

   <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">

       <encoder>

           <pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>

       </encoder>

   </appender>


   <logger name="org.chengzi" level="DEBUG" additivity="false">

       <appender-ref ref="Console"/>

   </logger>



   <!--

     level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 默认debug

     <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。

     -->

   <root level="DEBUG">

       <appender-ref ref="Console"/>

   </root>

</configuration>


第三步:编写 MyBatis 核心配置文件


编写 MyBatis 核心配置文件,可以用于替换连接信息,解决了 JDBC 硬编码的问题。在模块下的 resources 目录下创建 MyBatis 的配置文件 mybatis-config.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>


   <typeAliases>

       <package name="org.chengzi.pojo"/>

   </typeAliases>

 

   <!--

   environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment

   -->

   <environments default="development">

       <environment id="development">

           <transactionManager type="JDBC"/>

           <dataSource type="POOLED">

               <!--数据库连接信息-->

               <property name="driver" value="com.mysql.jdbc.Driver"/>

               <property name="url" value="jdbc:mysql://localhost:3306/blog?useSSL=false"/>

               <property name="username" value="root"/>

               <property name="password" value="abc123"/>

           </dataSource>

       </environment>


       <environment id="test">

           <transactionManager type="JDBC"/>

           <dataSource type="POOLED">

               <!--数据库连接信息-->

               <property name="driver" value="com.mysql.jdbc.Driver"/>

               <property name="url" value="jdbc:mysql://localhost:3306/blog?useSSL=false"/>

               <property name="username" value="root"/>

               <property name="password" value="abc123"/>

           </dataSource>

       </environment>

   </environments>

   <mappers>

      <!--加载sql映射文件-->

      <mapper resource="StudentMapper.xml"/>

   </mappers>

</configuration>


这里使用了<typeAliases>标签以后,在 sql 映射配置文件中的 resultType 的值可以直接设置为 Student ,而不是:




第四步:编写 sql 映射文件


编写 sql 映射配置文件,用于统一管理 sql 语句,同样也是为了解决 JDBC 硬编码的问题。在模块的 resources 目录下创建映射配置文件 StudentMapper.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="test">

   <select id="selectAll" resultType="org.chengzi.pojo.User">

       select * from student;

   </select>

</mapper>

1

2

3

4

5

6

7

第五步:编写代码


在编写代码时,大概可以分为四步。首先是定义 POJO 类,在指定的包下创建 Student 类,如下:


package org.chengzi.pojo;


public class Student {

   private int id;

   private String name;

   private String gender;


   public int getId() {

       return id;

   }


   public void setId(int id) {

       this.id = id;

   }


   public String getName() {

       return name;

   }


   public void setName(String name) {

       this.name = name;

   }


   public String getGender() {

       return gender;

   }


   public void setGender(String gender) {

       this.gender = gender;

   }


   @Override

   public String toString() {

       return "Student{" +

               "id=" + id +

               ", name='" + name + '\'' +

               ", gender='" + gender + '\'' +

               '}';

   }

}


接下来在 org.chengzi 包下创建 MyBatisDemo 测试类,用于加载核心配置文件,获取SqlSessionFactory 对象,获取 SQLSession 对象并执行 sql 语句,最后释放资源。


public class MyBatisDemo {


   public static void main(String[] args) throws IOException {

       //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory

       String resource = "mybatis-config.xml";

       InputStream inputStream = Resources.getResourceAsStream(resource);

       SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);


       //2. 获取SqlSession对象,用它来执行sql

       SqlSession sqlSession = sqlSessionFactory.openSession();

       //3. 执行sql

       List<Student> students = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的namespace.id

       System.out.println(students);

       //4. 释放资源

       sqlSession.close();

   }

}



过程剖析:


在使用 MyBatis 持久层框架开发时,我们首先创建 Maven 模块,使用 Maven 构建和管理这个 Java 项目,所以我们要导入项目依赖的坐标信息,例如 MySQL 数据库的驱动坐标,用于单元测试的 Junit 和用于查看日志信息的依赖坐标。


接下来是编写 MyBatis 核心配置文件,一般命名为 mybatis-config.xml,其中<environments>标签用于配置数据库连接环境信息,可以配置多个<environment>标签,通过 default 属性切换不同的环境。我们还要定义<mapper> 标签用于加载 sql 映射文件。


而 sql 映射文件在哪里呢?接下来一步就是编写 sql 映射文件,在模块的 resources 文件目录下创建映射文件的核心配置文件,一般命名有其语法规则,使用 xxxMapper.xml 命名,而 xxx 表示要操作的数据库表。其中使用 namespace 作为命名空间,而 id 作为标签中 sql 语句的唯一标识,使用命名空间的方式类似于 Java 中包的概念,允许在不同的命名空间中存在相同名称的 id ,方便在不同的 sql 映射文件中使用相同的 id,resultType 参数表示对应语句返回结果的类型,例如案例中将数据包装为 Student 类型的对象,其 resultType 参数的值就为 Student。


接下来就是定义 POJO 实体类,用于封装查询结果数据,例如案例中查询学生表,将每条记录封装为一个对象,这里就在 POJO 包中定义 Student 类。


最后就是核心的一部分,编写相关测试类来操作数据库,在源代码 Java 文件目录对应的包中创建测试类来操作数据库并封装结果集对象。内容大致为加载核心配置文件 mybatis-config.xml ,获取 SqlSessionFactory 类对象,使用该对象的openSession() 方法获取 SqlSession 对象,用于执行 sql,然后封装结果集对象 ,此时传入的参数是一个字符串,该字符串是映射配置文件的 namespace.id ,最后释放资源。


5. 总结

初学者入门时,整个构建过程可以多参考官网给出的示例教程和代码,直接 C V 到 IDE 练习即可。


本文是 MyBatis 持久层框架的入门篇,MyBatis 作为大多数Java 开发者第一个学习的大型框架,其思想十分重要,慢慢体会其中每个步骤的意义,多练习就能熟练掌握。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
SQL 缓存 Java
使用MyBatis优化Java持久层操作
使用MyBatis优化Java持久层操作
|
5月前
|
SQL 缓存 Java
使用MyBatis优化Java持久层操作
使用MyBatis优化Java持久层操作
|
Java 数据库连接 数据库
Spring Boot之Mybatis Plus:简化持久层开发的利器
本篇详细介绍了如何在Spring Boot应用中使用MyBatis Plus,一个用于简化持久层开发的工具。读者可以轻松实现CRUD操作,从而提高开发效率。展示了使用MyBatis Plus进行数据库操作的具体步骤。
685 5
Spring Boot之Mybatis Plus:简化持久层开发的利器
|
Java 数据库连接 数据库
探索Java中的MyBatis Plus:简化持久层开发的利器
在现代软件开发中,持久层是一个不可或缺的部分。为了更高效地操作数据库,开发者们经常使用ORM(对象关系映射)工具来简化数据库交互。而在Java领域,MyBatis Plus正是这样一个备受欢迎的ORM工具,它通过提供一系列便捷的特性,极大地简化了持久层的开发。本文将深入探讨MyBatis Plus的特点以及如何在项目中使用它。
126 0
|
SQL Java 数据库连接
Mybatis[Mybatis plus]就是持久层
目录 什么叫持久层? 为什么要使用持久化框架呢?
152 0
|
关系型数据库 Java 数据库连接
bboss持久层事务管理组件托管第三方持久层框架(mybatis等)事务功能介绍
bboss持久层事务管理组件托管第三方持久层框架(mybatis等)事务功能介绍 bboss持久层框架中的TXDataSource数据源类,可以实现第三方数据库事务代理功能 com.frameworkset.
948 0
|
2月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
131 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
65 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
2月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
441 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
2月前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
21 0
mybatis使用二:springboot 整合 mybatis,创建开发环境