大家好,我是可乐。

  上篇文章给大家撸了一遍用 JDBC 直接操作数据库的实例,还只是简单写了一个查询的接口,其代码量就已经很大了,并且可乐还给大家分析了直接使用 JDBC 带来的一些问题,总之是一种反人类的操作,为了让这种操作人类正常化,我们选择使用 ORM 框架。

  本篇文章给大家从头搭建一遍,如何基于 XML 配置,使用 Mybatis 进行增删改查操作。

  看到这,可能有读者就要问了,what?

  

  我现在使用 Springboot 多爽,还要这些复杂的配置干啥?

  可乐这里要说的是,Springboot 用起来是爽,它啥都给你封装好了,但是很多细节问题你可能并不知道,后续撸 Mybatis 的源码流程也是基于此,所以大家一定要过一遍 Mybatis 原始的执行方式。

  项目源码地址:https://github.com/YSOcean/mybatisproject

  这里可乐不会介绍各种配置含义,需要的可以直接参考官网,更加权威,你值得拥有:https://mybatis.org/mybatis-3/zh/configuration.html

1、创建库表

  以 Mysql 数据库为例,表比较简单,这里可乐就直接放图和建表语句了。

-- ----------------------------
-- Table structure for person
-- ----------------------------
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
`pid` int NOT NULL AUTO_INCREMENT,
`pname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`page` int DEFAULT NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

-- ----------------------------
-- Records of person
-- ----------------------------
BEGIN;
INSERT INTO `person` VALUES (1, 'itcoke', 11);
INSERT INTO `person` VALUES (2, 'IT可乐', 22);
COMMIT;

  

2、创建工程

  通过 IDEA 创建一个工程,并导入相应的jar包。

  以 maven 为例,配置 MySQL 和 Mybatis 即可。

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>

  整个项目结构可以参考我的GitHub地址:https://github.com/YSOcean/mybatisproject

3、创建与表对应的实体类对象

 1 package com.itcoke.bean;
2 ​
3 public class Person {
4 ​
5 private Long pid;
6 ​
7 private String pname;
8 ​
9 private Integer page;
10 ​
11 public Long getPid() {
12 return pid;
13 }
14 ​
15 public void setPid(Long pid) {
16 this.pid = pid;
17 }
18 ​
19 public String getPname() {
20 return pname;
21 }
22 ​
23 public void setPname(String pname) {
24 this.pname = pname;
25 }
26 ​
27 public Integer getPage() {
28 return page;
29 }
30 ​
31 public void setPage(Integer page) {
32 this.page = page;
33 }
34 ​
35 @Override
36 public String toString() {
37 return "Person{" +
38 "pid=" + pid +
39 ", pname='" + pname + '\'' +
40 ", page=" + page +
41 '}';
42 }
43 }

4、编写数据库配置文件 mybatis-config.xml

关于配置文件的详细介绍,可以参考官网:https://mybatis.org/mybatis-3/zh/configuration.html

<?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>

<!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境 -->
<!-- 默认使用的环境 ID,名字随意,但是要匹配下面其中一个环境 ID -->
<environments default="development">
<!-- 环境ID -->
<environment id="development">
<!--事务管理器
一、JDBC:这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围
二、MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期
比如 spring 或 JEE 应用服务器的上下文,默认情况下,它会关闭连接。然而一些容器并不希望这样,
因此如果你需要从连接中停止它,就可以将 closeConnection 属性设置为 false,比如:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
-->
<transactionManager type="JDBC"/>
<!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis-study"/>
<property name="username" value="root"/>
<property name="password" value="root1234"/>
</dataSource>
</environment>
</environments>
</configuration>

5、定义person表映射文件

官方权威地址:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html

<?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.itcoke.mapper.PersonMapper">


<!-- 根据 id 查询 person 表中的数据
id:唯一标识符,此文件中的id值不能重复
resultType:返回值类型,一条数据库记录也就对应实体类的一个对象
parameterType:参数类型,也就是查询条件的类型
-->
<select id="selectPersonById"
resultType="com.itcoke.bean.Person" parameterType="java.lang.Long" >
<!-- 这里和普通的sql 查询语句差不多,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着 -->
select * from person where pid = #{pid}
</select>



<!-- 根据 id 更新 person 表的数据 -->
<update id="updatePersonById" parameterType="com.itcoke.bean.Person">
update person p
<trim prefix="set" suffixOverrides=",">
<if test="pname != null and pname != ''">
p.pname = #{pname},
</if>
<if test="page != null and page != ''">
p.page = #{page},
</if>
</trim>

where pid=#{pid}
</update>


<!-- 向 person 表插入一条数据 -->
<insert id="insertPerson" parameterType="com.itcoke.bean.Person">
insert into person(pname,page)
value(#{pname},#{page})
</insert>



<!-- 根据 id 删除 person 表的数据 -->
<delete id="deletePersonById" parameterType="Long">
delete from person where pid=#{pid}
</delete>

</mapper>

6、向 mybatis-config.xml 中注册映射文件

<mappers>
<!-- 注册PersonMapper.xml文件 -->
<mapper resource="com/itcoke/mapper/PersonMapper.xml"/>
</mappers>

7、编写测试类

 1 package com.itcoke;
2 ​
3 ​
4 import com.itcoke.bean.Person;
5 import com.itcoke.mapper.PersonMapper;
6 import org.apache.ibatis.io.Resources;
7 import org.apache.ibatis.session.SqlSession;
8 import org.apache.ibatis.session.SqlSessionFactory;
9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
10 import org.junit.Before;
11 import org.junit.Test;
12 ​
13 import java.io.IOException;
14 import java.io.InputStream;
15 ​
16 public class MybatisprojectApplicationTests {
17 // 定义SqlSessionFactory
18 SqlSessionFactory sessionFactory = null;
19 ​
20 @Before
21 public void init() {
22 //定义mybatis全局配置文件
23 String resource = "mybatis-config.xml";
24 //加载 mybatis 全局配置文件
25 InputStream inputStream = null;
26 try {
27 inputStream = Resources.getResourceAsStream(resource);
28 } catch (IOException e) {
29 e.printStackTrace();
30 }
31 //构建sqlSession的工厂
32 sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
33 ​
34 }
35 ​
36 //根据id查询person表数据
37 @Test
38 public void testSelectPersonById() {
39 /*这个字符串由 PersonMapper.xml 文件中 两个部分构成
40 <mapper namespace="com.itcoke.mapper.PersonMapper"> 的 namespace 的值
41 <select id="selectPersonById" > id 值
42 */
43 String namespace = "com.itcoke.mapper.PersonMapper";
44 String method = "selectPersonById";
45 //根据 sqlSessionFactory 产生 session
46 SqlSession sqlSession = sessionFactory.openSession();
47 Person person = sqlSession.selectOne(namespace + "." + method, 1L);
48 System.out.println(person);
49 sqlSession.close();
50 }
51 ​
52 ​
53 //根据id更新person表数据
54 @Test
55 public void testUpdatePersonById() {
56 String statement = "com.itcoke.mapper.PersonMapper.updatePersonById";
57 Person p = new Person();
58 p.setPid(2L);
59 p.setPage(18);
60 //根据 sqlSessionFactory 产生 session
61 SqlSession sqlSession = sessionFactory.openSession();
62 sqlSession.update(statement, p);
63 sqlSession.commit();
64 sqlSession.close();
65 }
66 ​
67 ​
68 //向 person 表插入数据
69 @Test
70 public void testInsertPerson() {
71 String statement = "com.itcoke.mapper.PersonMapper.insertPerson";
72 Person p = new Person();
73 p.setPname("可乐");
74 p.setPage(18);
75 //根据 sqlSessionFactory 产生 session
76 SqlSession sqlSession = sessionFactory.openSession();
77 sqlSession.insert(statement, p);
78 sqlSession.commit();
79 sqlSession.close();
80 }
81 ​
82 //根据id更新person表数据
83 @Test
84 public void testDeletePersonById() {
85 String statement = "com.itcoke.mapper.PersonMapper.deletePersonById";
86 Person p = new Person();
87 p.setPid(4L);
88 //根据 sqlSessionFactory 产生 session
89 SqlSession sqlSession = sessionFactory.openSession();
90 sqlSession.delete(statement, p);
91 sqlSession.commit();
92 sqlSession.close();
93 }
94 }

9、通过接口

  在上面的例子中,我们发现 statement 每次都要自己书写拼接,很容易就写错了,这时候 MyBatis 提供了接口注册方式。

  ①、在 mapper 包下面新建一个 PersonMapper 接口

  注意要和 PersonMapper.xml 同名,且在同一个包下,因为要和 namespace 相同。

 1 package com.itcoke.mapper;
2 ​
3 import com.itcoke.bean.Person;
4 ​
5 ​
6 public interface PersonMapper {
7 ​
8 Person selectPersonById(long pid);
9 ​
10 void updatePersonById(Person person);
11 ​
12 void insertPerson(Person person);
13 ​
14 void deletePersonById(long pid);
15 }

  ②、测试

 1 //根据id查询person表数据
2 //通过接口代理的方式
3 @Test
4 public void testInterfaceSelectPersonById() {
5 //根据 sqlSessionFactory 产生 session
6 SqlSession sqlSession = sessionFactory.openSession();
7 PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
8 Person person = mapper.selectPersonById(1L);
9 System.out.println(person);
10 sqlSession.close();
11 }

8、小结

  至此,我们从头到尾撸了一遍利用 Mybatis 进行增删改查,后面便会深入底层,梳理架构。

Mybatis源码解析2—— 实例搭建的更多相关文章

  1. Mybatis源码解析,一步一步从浅入深(四):将configuration.xml的解析到Configuration对象实例

    在Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们看到了XMLConfigBuilder(xml配置解析器)的实例化.而且这个实例化过程在文章:Mybatis源码解析,一步一步从浅 ...

  2. Mybatis源码解析3——核心类SqlSessionFactory,看完我悟了

    这是昨晚的武汉,晚上九点钟拍的,疫情又一次来袭,曾经熙熙攘攘的夜市也变得冷冷清清,但比前几周要好很多了.希望大家都能保护好自己,保护好身边的人,生活不可能像你想象的那么好,但也不会像你想象的那么糟. ...

  3. 【MyBatis源码解析】MyBatis一二级缓存

    MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相 ...

  4. mybatis源码-解析配置文件(三)之配置文件Configuration解析

    目录 1. 简介 1.1 系列内容 1.2 适合对象 1.3 本文内容 2. 配置文件 2.1 mysql.properties 2.2 mybatis-config.xml 3. Configura ...

  5. Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码

    在文章:Mybatis源码解析,一步一步从浅入深(一):创建准备工程,中我们为了解析mybatis源码创建了一个mybatis的简单工程(源码已上传github,链接在文章末尾),并实现了一个查询功能 ...

  6. Mybatis源码解析,一步一步从浅入深(三):实例化xml配置解析器(XMLConfigBuilder)

    在上一篇文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码 ,中我们看到 代码:XMLConfigBuilder parser = new XMLConfigBuilder(read ...

  7. Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析

    在上一篇文章Mybatis源码解析,一步一步从浅入深(四):将configuration.xml的解析到Configuration对象实例中我们谈到了properties,settings,envir ...

  8. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  9. Mybatis源码解析,一步一步从浅入深(七):执行查询

    一,前言 我们在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码的最后一步说到执行查询的关键代码: result = sqlSession.selectOne(command.ge ...

随机推荐

  1. elk 日志收集 filebeat 集群搭建 php业务服务日志 nginx日志 json 7.12版本 ELK 解决方案

    难的不是技术,难的是业务.熟悉业务流程才是最难的. 其实搜索进来的每一个人的需求不一样,希望你能从我的这篇文章里面收获到. 建议还是看官方文档,更全面一些. 一.背景 1,收集nginx  acces ...

  2. shell下读取文件数据

    参考:https://www.imzcy.cn/1553.html while和for对文件的读取是有区别的: 1. for对文件的读是按字符串的方式进行的,遇到空格什么后,再读取的数据就会换行显示 ...

  3. php漏洞 strcmp漏洞

    0x01: 背景:strcmp函数,参数是两个字符串,相等返回为零,大于,返回大于零,小于,返回小于零. 0x02: 如果传入的值,不是字符串的话,会报错,同时使得两个字符串直接相等,返回为零. 一般 ...

  4. MySQL服务器 IO 100%的分析与优化方案

    前言 压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等.而问题定位分析通常情况下,最优先排查的是监控服务器资源利用率,例如先用TOP 或者nmon等 ...

  5. mysql 索引介绍与运用

    索引 (1)什么是索引? 是一种提升查询速度的 特殊的存储结构. 它包含了对数据表里的记录的指针,类似于字典的目录. 当我们添加索引时会单独创建一张表来去存储和管理索引,索引比原数据大,会占用更多的资 ...

  6. MQTT介绍与使用(转载)

    物联网是新一代信息技术的重要组成部分,也是"信息化"时代的重要发展阶段.其英文名称是:"Internet of things(IoT)".顾名思义,物联网就是物 ...

  7. 一道内部ctf文件包含题

    拿到题目 在burp里看下 拿到源码 很明显是一道文件包含题目,包含cookie里的值,于是构造Cookie:language=chinese试试   文件变成中文的了,说明中文语言进行了包含并替换 ...

  8. Mysql学生课程表SQL面试集合

    现有如下2个表,根据要求写出SQL语句. student表:编号(sid),姓名(sname),性别(sex) course表:编号(sid),科目(subject),成绩(score)  问题1:查 ...

  9. python使用笔记21--发邮件

    发邮件需要第三方模块 pip install yamail 1 #import yagmail #--别人写的,发中文附件的时候是乱码 2 import yamail #牛牛基于yagmail改的 3 ...

  10. python使用笔记12--操作mysql数据库

    1.创建连接 1 import pymysql 2 connect = pymysql.connect(host='127.0.0.1', 3 user='root', 4 password='123 ...