MyBatis系列第3篇:Mybatis使用详解(1,字节跳动历年Java中高级面试题全收录

  • 引入logback支持(非必须)

  • 写一个测试用例

2、 使用SqlSesion执行sql操作

  • SqlSession常见的用法

  • 新增操作

  • 执行删除

  • 执行修改

  • 执行查询

3、 Mapper接口的使用

  • 为什么需要Mapper接口

  • Mapper接口的用法

  • 案例:使用Mapper接口来实现增删改查

  • Mapper接口使用时注意的几点

  • Mapper接口的原理

4、 案例源码获取方式

快速入门

准备数据库

mysql中执行下面sql:

/创建数据库javacode2018/

DROP DATABASE IF EXISTS javacode2018;

CREATE DATABASE javacode2018;

USE javacode2018;

/创建表结构/

DROP TABLE IF EXISTS t_user;

CREATE TABLE t_user (

id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT ‘主键,用户id,自动增长’,

name VARCHAR(32) NOT NULL DEFAULT ‘’ COMMENT ‘姓名’,

age SMALLINT NOT NULL DEFAULT 1 COMMENT ‘年龄’,

salary DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT ‘薪水’,

sex TINYINT NOT NULL DEFAULT 0 COMMENT ‘性别,0:未知,1:男,2:女’

) COMMENT ‘用户表’;

SELECT * FROM t_user;

上面我们创建了一个数据库:javacode2018,一个用户表t_user

我们的需求

使用mybatis来实现对t_user表增删改查。

使用idea创建项目

我们在上一篇文章mybatis-series项目中创建另外一个模块chat02,过程如下:

选中mybatis-series,如下图:

点击右键->New->Module,如下图:

选中上图中的Maven,点击Next,如下图:

出现下面窗口:

上图中输入ArtifactIdchat02,点击Next,如下图:

点击上图中的Finish完成chat02模块的创建,项目结构如下图:

pom.xml中引入mybatis依赖

org.mybatis

mybatis

mysql

mysql-connector-java

org.projectlombok

lombok

junit

junit

ch.qos.logback

logback-classic

上面我们引入了依赖mybatis、mysql驱动、lombok支持、junit、logback支持,其实运行mybatis只需要引入下面这一个构件就行了:

org.mybatis

mybatis

注意:上面pom引入的构建中没有写版本号,是因为构件的版本号在父pom.xml中已经声明了,所以chat03/pom.xml中就不需要再去写了。

配置mybatis全局配置文件

使用mybatis操作数据库,那么当然需要配置数据库相关信息,这个需要在mybatis全局配置文件中进行配置。

mybatis需提供一个全局配置的xml文件,可以在这个配置文件中对mybatis进行配置,如事务的支持,数据源的配置等等,这个属于配置文件,我们一般放在main/resource中。

chat03/src/main/resource中创建mybatis-config.xml文件,内容如下:

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

我们做一下解释。

configuration元素

这个是mybatis全局配置文件的根元素,每个配置文件只有一个

environments元素

用来配置mybatis的环境信息,什么是环境?比如开发环境、测试环境、线上环境,这3个环境中的数据库可能是不一样的,可能还有更多的环境。

environments元素中用来配置多个环境的,具体的一个环境使用environment元素进行配置,environment元素有个id用来标识某个具体的环境。

配置了这么多环境,那么mybatis具体会使用哪个呢?

environments元素有个default属性,用来指定默认使用哪个环境,如上面默认使用的是chat03

environment元素

用来配置具体的环境信息,这个元素下面有两个子元素:transactionManager和dataSource

  • transactionManager元素

用来配置事务工厂的,有个type属性,type的值必须是org.apache.ibatis.transaction.TransactionFactory接口的实现类,TransactionFactory看名字就知道是一个工厂,用来创建事务管理器org.apache.ibatis.transaction.Transaction对象的,TransactionFactory接口默认有2个实现:

org.apache.ibatis.transaction.managed.ManagedTransactionFactory

org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory

一般情况下我们使用org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory这个,mybatis和其他框架集成,比如和spring集成,事务交由spring去控制,spring中有TransactionFactory接口的一个实现org.mybatis.spring.transaction.SpringManagedTransactionFactory,有兴趣的朋友可以去研究一下,这个到时候讲到spring的使用会详细说。

  • dataSource元素

这个用来配置数据源的,type属性的值必须为接口org.apache.ibatis.datasource.DataSourceFactory的实现类,DataSourceFactory也是一个工厂,用来创建数据源javax.sql.DataSource对象的,mybatis中这个接口默认有3个实现类:

org.apache.ibatis.datasource.jndi.JndiDataSourceFactory

org.apache.ibatis.datasource.pooled.PooledDataSourceFactory

org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory

我们使用第2个org.apache.ibatis.datasource.pooled.PooledDataSourceFactory,这个用来创建一个数据库连接池类型的数据源,可以实现数据库连接共用,减少连接重复创建销毁的时间。

配置数据源需要指定数据库连接的属性信息,比如:驱动、连接db的url、用户名、密码,这个在dataSource元素下面的property中配置,property元素的格式:

创建Mapper xml文件

我们需要对t_user表进行操作,需要写sql,sql写在什么地方呢?

在mybatis中一般我们将一个表的所有sql操作写在一个mapper xml中,一般命名为XXXMapper.xml格式。

创建文件chat02/src/main/resource/mapper/UserMapper.xml,内容如下:

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

mapper xml根元素为mapper,这个元素有个namespace属性,系统中会有很多表,每个表对应一个Mapper xml,为了防止mapper文件重复,我们需要给每个mapper xml文件需要指定一个namespace,通过这个可以区分每个mapper xml文件,上面我们指定为com.javacode2018.chat02.UserMapper

一会对t_user表的所有操作相关的sql,我们都会写在上面这个xml中。

mybatis全局配置文件中引入Mapper xml文件

UserMapper.xml我们写好了,如何让mybatis知道这个文件呢,此时我们需要在mybatis-config.xml全局配置文件中引入UserMapper.xml,在mybatis-config.xml加入下面配置:

mappers元素下面有多个mapper元素,通过mapper元素resource属性可以引入Mapper xml文件,resource是相对于classes的路径。

上面说的都是一些配置文件,配置文件都ok了,下面我们就需要将mybatis跑起来了,此时需要使用到mybatis中的一些java对象了。

构建SqlSessionFactory对象

//指定mybatis全局配置文件

String resource = “mybatis-config.xml”;

//读取全局配置文件

InputStream inputStream = Resources.getResourceAsStream(resource);

//构建SqlSessionFactory对象

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

SqlSessionFactory是一个接口,是一个重量级的对象,SqlSessionFactoryBuilder通过读取全局配置文件来创建一个SqlSessionFactory,创建这个对象是比较耗时的,主要耗时在对mybatis全局配置文件的解析上面,全局配置文件中包含很多内容,SqlSessionFactoryBuilder通过解析这些内容,创建了一个复杂的SqlSessionFactory对象,这个对象的生命周期一般和应用的生命周期是一样的,随着应用的启动而创建,随着应用的停止而结束,所以一般是一个全局对象,一般情况下一个db对应一个SqlSessionFactory对象。

构建SqlSession对象

SqlSession相当于jdbc中的Connection对象,相当于数据库的一个连接,可以用SqlSession来对db进行操作:如执行sql、提交事务、关闭连接等等,需要通过SqlSessionFactory来创建SqlSession对象,SqlSessionFactory中常用的有2个方法来创建SqlSession对象,如下:

//创建一个SqlSession,默认不会自动提交事务

SqlSession openSession();

//创建一个SqlSession,autoCommit:指定是否自动提交事务

SqlSession openSession(boolean autoCommit);

SqlSession接口中很多方法,直接用来操作db,方法清单如下,大家眼熟一下:

 T selectOne(String statement);

 T selectOne(String statement, Object parameter);

 List selectList(String statement);

 List selectList(String statement, Object parameter);

 List selectList(String statement, Object parameter, RowBounds rowBounds);

<K, V> Map<K, V> selectMap(String statement, String mapKey);

<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);

<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);

 Cursor selectCursor(String statement);

 Cursor selectCursor(String statement, Object parameter);

 Cursor selectCursor(String statement, Object parameter, RowBounds rowBounds);

void select(String statement, Object parameter, ResultHandler handler);

void select(String statement, ResultHandler handler);

void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);

int insert(String statement);

int insert(String statement, Object parameter);

int update(String statement);

int update(String statement, Object parameter);

int delete(String statement);

int delete(String statement, Object parameter);

void commit();

void commit(boolean force);

void rollback();

void rollback(boolean force);

List flushStatements();

void close();

void clearCache();

Configuration getConfiguration();

 T getMapper(Class type);

Connection getConnection();

上面以select开头的可以对db进行查询操作,insert相关的可以对db进行插入操作,update相关的可以对db进行更新操作。

引入lombok支持(非必须)

声明一下:lombok不是mybatis必须的,为了简化代码而使用的,以后我们会经常使用。

Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。

Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。

lombok的使用步骤
  1. 先在idea中安装lombok插件

打开idea,点击File->Settings->plugins,然后搜索Lombok Plugin,点击安装就可以了。

  1. maven中引入lombok支持

org.projectlombok

lombok

1.18.10

provided

  1. 代码中使用lombok相关功能
引入logback(非必须)

声明一下:日志框架mybatis中也不是必须的,不用配置也可以正常运行。

为了方便查看mybatis运行过程中产生的日志,比如:执行的sql、sql的参数、sql的执行结果等等调试信息,我们需要引入日志框架的支持,logback是一个很好的日志框架,此处我们就使用这个

mybatis中集成logback步骤
  1. maven中引入logback支持

ch.qos.logback

logback-classic

1.2.3

  1. src/main/resources中创建logback.xml文件:
<?xml version="1.0" encoding="UTF-8"?>

%d{mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n

logback.xml具体的写法不是本文讨论的范围,有兴趣的朋友可以去研究一下logback具体的用法。

上面xml中配置了com.javacode2018包中所有的类,使用logback输出日志的时候,debug级别及以上级别的日志会输出到控制台,方便我们查看。

写一个测试用例

chat02/src/test下创建一个类:

com.javacode2018.chat02.UserTest

内容如下:

package com.javacode2018.chat02;

import lombok.extern.slf4j.Slf4j;

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.Before;

import org.junit.Test;

import java.io.IOException;

import java.io.InputStream;

@Slf4j

public class UserTest {

private SqlSessionFactory sqlSessionFactory;

@Before

public void before() throws IOException {

//指定mybatis全局配置文件

String resource = “mybatis-config.xml”;

//读取全局配置文件

InputStream inputStream = Resources.getResourceAsStream(resource);

//构建SqlSessionFactory对象

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

this.sqlSessionFactory = sqlSessionFactory;

}

@Test

public void sqlSession() {

SqlSession sqlSession = this.sqlSessionFactory.openSession();

log.info(“{}”, sqlSession);

}

}

上面代码中有个@Slf4j注解,这个是lombok提供的,可以在这个类中生成下面代码:

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UserTest.class);

运行一下上面的用例:sqlSession方法,输出如下:

45:51.289 [main] INFO  com.javacode2018.chat02.UserTest - org.apache.ibatis.session.defaults.DefaultSqlSession@1f021e6c

使用SqlSesion执行sql操作

SqlSession常见的用法

SqlSession相当于一个连接,可以使用这个对象对db执行增删改查操作,操作完毕之后需要关闭,使用步骤:

1.获取SqlSession对象:通过该sqlSessionFactory.openSession方法获取SqlSession对象

2.对db进行操作:使用SqlSession对象进行db操作

3.关闭SqlSession对象:sqlSession.close();

常见的使用方式如下:

//获取SqlSession

SqlSession sqlSession = this.sqlSessionFactory.openSession();

try {

//执行业务操作,如:增删改查

} finally {

//关闭SqlSession

sqlSession.close();

}

上面我们将SqlSession的关闭放在finally块中,确保close()一定会执行。更简单的方式是使用java中的try()的方式,如下:

try (SqlSession sqlSession = this.sqlSessionFactory.openSession()😉 {

//执行业务操作,如:增删改查

}

新增操作

需求:传入UserModel对象,然后将这个对象的数据插入到t_user表中。

创建一个`UserModel`

新建一个com.javacode2018.chat02.UserModel类,代码如下:

package com.javacode2018.chat02;

import lombok.*;

/**

* 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活!

*/

@Getter

@Setter

@NoArgsConstructor

@AllArgsConstructor

@Builder

@ToString

public class UserModel {

private Long id;

private String name;

private Integer age;

private Double salary;

private Integer sex;

}

这个类的字段和t_user表对应。

UserMapper.xml中定义插入操作

我们说过了,对t_user表的所有sql操作,我们都放在UserMapper.xml中,我们在UserMapper.xml中加入下面配置,使用insert元素定义插入操作:

<![CDATA[ INSERT INTO t_user (id,name,age,salary,sex) VALUES (#{id},#{name},#{age},#{salary},#{sex}) ]]>

insert元素用来定义了一个对db的insert操作

id:是这个操作的一个标识,一会通过mybatis执行操作的时候会通过这个namespace和id引用到这个insert操作,

parameterType:用来指定这个insert操作接受的参数的类型,可以是:各种javabean、map、list、collection类型的java对象,我们这个插入接受的是UserModel对象。

insert元素内部定义了具体的sql,可以看到是一个insert的sql,向t_user表插入数据。

需要插入的值从UserModel对象中获取,取UserModel对象的的字段,使用**#{字段}**这种格式可以获取到UserModel中字段的值。

调用SqlSession.insert方法执行插入操作

t_user插入的sql我们已经在UserMapper中写好,此时我们怎么调用呢?

需要调用SqlSession.insert方法:

int insert(String statement, Object parameter)

这个方法有2个参数:

statement:表示那个操作,值为Mapper xml的namespace.具体操作的id,如需要调用UserMapper.xml中的insertUser操作,这个值就是:

com.javacode2018.chat02.UserMapper.insertUser

parameter:insert操作的参数,和Mapper xml中的insert中的parameterType指定的类型一致。

返回值为插入的行数。

UserTest类中新增一个测试用例:

@Test

public void insertUser() {

try (SqlSession sqlSession = this.sqlSessionFactory.openSession(false)😉 {

//创建UserModel对象

UserModel userModel = UserModel.builder().id(2L).name(“javacode2018”).age(30).salary(50000D).sex(1).build();

//执行插入操作

int result = sqlSession.insert(“com.javacode2018.chat02.UserMapper.insertUser”, userModel);

log.info(“插入影响行数:{}”, result);

//提交事务

sqlSession.commit();

}

}

运行输出如下:

01:46.683 [main] DEBUG c.j.chat02.UserMapper.insertUser - ==>  Preparing: INSERT INTO t_user (id,name,age,salary,sex) VALUES (?,?,?,?,?)

01:46.745 [main] DEBUG c.j.chat02.UserMapper.insertUser - ==> Parameters: 2(Long), javacode2018(String), 30(Integer), 50000.0(Double), 1(Integer)

01:46.751 [main] DEBUG c.j.chat02.UserMapper.insertUser - <==    Updates: 1

01:46.751 [main] INFO com.javacode2018.chat02.UserTest - 影响行数:1

输出中打印了详细的sql语句,以及sql的参数信息,可以看到Mapper xml中的#{}被替换为了?,这个使用到了jdbc中的PreparedStatement来对参数设置值。

输出中的第二行详细列出了参数的值以及每个值的类型。

第三行输出了insert的结果为1,表示插入成功了1行记录。

去db中看一下,如下,插入成功:

mysql> SELECT * FROM t_user;

±—±--------------±----±---------±----+

| id | name          | age | salary   | sex |

±—±--------------±----±---------±----+

|  1 | 路人甲Java    |  30 | 50000.00 |   1 |

±—±--------------±----±---------±----+

1 row in set (0.00 sec)

上面代码中创建SqlSession,我们使用的是sqlSessionFactory.openSession()创建的,这个方法创建的SqlSession,内部事务是非自动提交的方式,所以需要我们手动提交:

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

01:46.751 [main] DEBUG c.j.chat02.UserMapper.insertUser - <==    Updates: 1

01:46.751 [main] INFO com.javacode2018.chat02.UserTest - 影响行数:1

输出中打印了详细的sql语句,以及sql的参数信息,可以看到Mapper xml中的#{}被替换为了?,这个使用到了jdbc中的PreparedStatement来对参数设置值。

输出中的第二行详细列出了参数的值以及每个值的类型。

第三行输出了insert的结果为1,表示插入成功了1行记录。

去db中看一下,如下,插入成功:

mysql> SELECT * FROM t_user;

±—±--------------±----±---------±----+

| id | name          | age | salary   | sex |

±—±--------------±----±---------±----+

|  1 | 路人甲Java    |  30 | 50000.00 |   1 |

±—±--------------±----±---------±----+

1 row in set (0.00 sec)

上面代码中创建SqlSession,我们使用的是sqlSessionFactory.openSession()创建的,这个方法创建的SqlSession,内部事务是非自动提交的方式,所以需要我们手动提交:

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-alybwhNH-1710886582659)]
[外链图片转存中…(img-c9ftCm20-1710886582660)]
[外链图片转存中…(img-TpUYeWL7-1710886582660)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-QuLAXADp-1710886582661)]

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值