MyBatis 优秀的持久层框架(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MyBatis 优秀的持久层框架

1、介绍

1.1什么是mybatis

  • MyBatis 是一款优秀的持久层框架。
  • 它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了[google code](https://baike.baidu.com/item/google code/2346604),并且改名为MyBatis 。2013年11月迁移到Github
    iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

如何获得Mybatis

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


  1. github:https://github.com/mybatis/mybatis-3
  2. 中文注释版:https://github.com/tuguangquan/mybatis

1.2、持久化

数据持久化

  • 持久化就是将数据在持久状态和瞬时状态转化的过程
  • 内存特性:断电即消失
  • 数据库(JDBC),IO文件持久化(太过浪费资源)
  • 生活中的例子:冷藏,罐头

为什么需要持久化?

  • 有些对象,不能让他丢掉
  • 内存太贵了OVO

1.3、持久层

Dao层,service层,controller层

  • 完成成就花工作的代码块
  • 层是界限十分明显的

1.4、为什么要用Mybatis

  • 方便
  • 帮助程序员将数据存入数据库中
  • 传统的jdbc代码太复杂了,简化,框架
  • 不用Mybatis也可以,只是更容易上手,技术没有高低之分
  • 优点
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql。

最重要的一点,用的人多!

路程:Spring,SpringMVC,SpringBoot

2、第一个Mybatis程序

思路:搭建环境--》导入Mybatis--》测试

2.1、搭建环境

搭建数据库

CREATE DATABASE myBatis;
USE myBatis
CREATE TABLE  USER(
   id INT(20) NOT NULL PRIMARY KEY,
   NAME VARCHAR(255) DEFAULT NULL,
   pwd VARCHAR(20) 
)DEFAULT CHARSET = utf8;
INSERT INTO USER(id,NAME,pwd) VALUES (1,"张三","123456");
INSERT INTO USER(id,NAME,pwd) VALUES (2,"李四","123456");
INSERT INTO USER(id,NAME,pwd) VALUES (3,"王五","123456");

新建项目

  1. 创建一个maven项目
  2. 删除src,把项目作为父项目
  3. 父项目依赖导入,
<dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
    </dependencies>


2.2创建模块

  • 编写myBatis核心配置文件
<?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>
    <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/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>


  • 编写Mybatis工具类
public class mybatisUtils {
    private  static  SqlSessionFactory sqlSessionFactory = null;
    static {
        try {
            //使用mybatis第一步
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
    public  static SqlSession getSqlSession(){
        return  sqlSessionFactory.openSession();
    }
}


2.3、编写代码

  • 实体类
  • Dao接口
public interface UserDao {
    public List<user> getuserlist();
}


  • 接口实现类,由原来的userDAOimpl转变为一个Mapper配置文件
<?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">
<!--namespoce绑定一个对应的DAO/mapper接口-->
<mapper namespace="org.mybatis.example.BlogMapper">
   <select id="getuserlist" resultType="com.hyc.pojo.user">
    select * from user;
   </select>
</mapper>


2.4、测试

注意报错点:

org.apache.ibatis.binding.BindingException: Type interface com.hyc.dao.UserDao is not known to the MapperRegistry.

没有添加mapper注册

  1. 配置文件注册
  2. 绑定接口错误
  3. 方法名不对
  4. 返回类型不对
  5. 权限命名
  6. mavaen导出资源问题
  7. idea2020版本全局配置文件不要放在resource里
  8. 基本上只操作配置文件

junit测试

public class Test {
@org.junit.Test
    public  void test(){
    SqlSession sqlSession = null;
    try {
        sqlSession = MybatisUtlis.getsqlsession();
        userDao mapper = sqlSession.getMapper(userDao.class);
        List<user> userList = mapper.getuserList();
        for (user user : userList) {
            System.out.println(user);
        }
    }catch (Exception e){
e.printStackTrace();
    }finally {
        sqlSession.close();
    }
    }
}

3、CRUD增删改查

1、namespace

namespace中的包名要和DAO/Mapper一致

2、select查询

选择,查询语句

  • id:对应的namespace中的方法名
  • resultType:sql语句执行的返回值
  • parmeterType:参数的类型
  1. 编写接口
//查询全部用户
    public List<user> getuserList();


  1. 编写对应的mapper中的sql语句
<select id="getuserList" resultType="com.hyc.pojo.user">
    select * from user
  </select>


  1. 测试
@org.junit.Test
    public  void test(){
    SqlSession sqlSession = null;
    try {
        sqlSession = MybatisUtlis.getsqlsession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<user> userList = mapper.getuserList();
        for (user user : userList) {
            System.out.println(user);
        }
    }catch (Exception e){
e.printStackTrace();
    }finally {
        sqlSession.close();
    }
    }


3、insert

<!--    对象中的属性可以直接取出来-->
    <insert id="addUser" parameterType="com.hyc.pojo.user">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd});
    </insert>

4、update

<update id="UpdateUser" parameterType="com.hyc.pojo.user">
update user  set name = #{name},pwd=#{pwd} where id = #{id}  ;
 </update>

5、Delete

<delete id="DelUser" parameterType="com.hyc.pojo.user">
    delete from user where id = #{id}
</delete>

注意点:

增删改都需要提交事务

6、万能的map

假设,我们的实体类,或者数据库中的表,字段,参数过多,我们应当考虑使用map

public  void addUser(){
        SqlSession sqlSession = MybatisUtlis.getsqlsession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        HashMap<Object, Object> map = new HashMap<Object, Object>();
        map.put("id",6);
        map.put("name","showis");
        map.put("pwd","hyc2005");
        int i= mapper.getUser(map);
        if (i>0){
            System.out.println("map新增成功");
        }
    sqlSession.commit();
        sqlSession.close();
    }

sqlMapper配置文件

<insert id="getUser" parameterType="map">
        insert into user (id,name,pwd) values (#{id},#{name},#{pwd});
    </insert>

Map传递参数,直接在sql中取出key即可{parameterType="map"}

对象传递参数,直接在sql中取对象的属性即可{parameterType="object"}

只有一个基本类型参数的情况下,可以直接在sql中取到

多个参数用Map或者注解

7、模糊查询

  1. java代码执行的时候,传递通配符%%
public void  getLike(){
        SqlSession getsqlsession = MybatisUtlis.getsqlsession();
        UserMapper mapper = getsqlsession.getMapper(UserMapper.class);
        List<user> userList = mapper.getUserlike("%张%");
        for (user user : userList) {
            System.out.println(user);
        }
        getsqlsession.close();
    }


  1. 在sql拼接中使用通配符(但是注入)
<select id="getUserlike" resultType="com.hyc.pojo.user">
      select * from user where name like “%”#{value}“%”;
</select>


4 、配置解析

1、核心配置文件

myBatis-config.xml

Mybatis的配置文件,决定了Mybati的属性

1、配置

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

  • configuration(配置)
  • environment(环境变量)
  • transactionManager(事务管理器)
  • dataSource(数据源)

2、environments(环境配置)

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。

我们只需要更改environments 的default的属性来选择不同的环境

在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]"):

  • JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
  • MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。

学会配置多套的环境配置

MyBatis默认的事务管理器是JDBC,连接池:pooled,

3、属性(properties)

我们可以通过过properties属性来实现引用配置文件

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。【db.properties】

学会编写一个配置文件

driver = com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis
username=root
password=root

在核心配置文件中引入

<!--    外部配置文件-->
    <properties resource="com/hyc/dao/db.properties"/>
  • 可以直接引入外部文件
  • 可以在其中增加一些属性配置
  • 如果两个文件有同一个字段,那么优先使用外部配置文件的

4、类型别名(typeAliases)

  • 类型别名可为 Java 类型设置一个缩写名字。
  • 它仅用于 XML 配置,意在降低冗余的全限定类名书写
<typeAliases>
        <typeAlias type="com.hyc.pojo.user" alias="user"/>
    </typeAliases>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean

扫描实体类的包,它的默认别名就为这个类的类名就是首字母小写

<typeAliases>
<!--        <typeAlias type="com.hyc.pojo.user" alias="user"/>-->
<package name="com.hyc.pojo"/>
    </typeAliases>

使用环境

在实体类比较少的时候可以使用第一种方式

如果实体类十分多,可以使用第二个

第一种可以在配置文件diy名字,第二种想要自定义必须要使用@Alias注解

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

基本类型需要使用__来使用 例如 int : _int

5、设置

这是Mybatis中机器重要的调整设置,他们会改变Mybatis的运行行为

6、其他配置


MyBatis Generator Core


MyBatis Plus

基友搭配,效率翻倍

7、映射器

MapperRegistry:注册绑定mapper文件

方式一:推荐使用

<mappers>
        <mapper resource="com/hyc/dao/userMapper.xml"/>
    </mappers>

方式二:使用class文件绑定注册

<mappers>
  <mapper class="com/hyc/dao/UserMapper"/>
</mappers>

注意点:

  • 接口和她的Mapper配置文件必须同名
  • 接口和她的Mapper配置文件必须在同一个包下

方式三:使用扫描包的进行注入绑定

<mappers>
<!--        <mapper resource="com/hyc/dao/userMapper.xml"/>-->
    <package name="com.hyc.dao"/>
    </mappers>

注意点和方式二一样

需要掌握的知识

  1. 将数据库配置文件外部引用
  2. 实体类别名
  3. 保证usermapper和usermapper.xml改为一致并且放在同一个包下

8、生命周期和作用域

作用域 和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

SqlSessionFactoryBuilder:

  • 一旦创建了 SqlSessionFactory,就不再需要它了
  • 局部变量

SqlSessionFactory

  • 可以想象为:数据库连接池
  • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,直到程序结束,没有任何理由丢弃它或重新创建另一个实例
  • 因此 SqlSessionFactory 的最佳作用域是应用作用域(全局)
  • 最简单的就是使用单例模式或者静态单例模式

SqlSession

  • 连接到连接池的一个请求,
  • 关闭请求
  • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
  • 用完之后需要关闭,否则资源会被占用
  • 关闭操作十分重要

这里面每一个Mapper,就代表一个具体的业务

5、ResultMap,解决属性名和字段名不一致的问题

5.1问题

新建一个项目,拷贝之前项目,测试实体类与数据库不同的情况

5.2解决属性名和字段名不一致的问题

解决方案:

方法一:起别名

5.3resultMap

结果集映射

id name pwd
id name password

新标签

<resultMap id="usermap" type="user">
<!--        column 数据库中的字段  property实体类中的属性-->
        <result column="pwd" property="password"/>
    </resultMap>
    <select id="getuserByid" resultMap="usermap">
    select * from user where id = #{id};
    </select>
  • resultMap 元素是 MyBatis 中最重要最强大的元素
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
  • 这就是 ResultMap 的优秀之处——你完全可以不用显式地配置它们。 虽然上面的例子不用显式配置 ResultMap。 但为了讲解,我们来看看如果在刚刚的示例中,显式使用外部的 resultMap 会怎样,这也是解决列名不匹配的另外一种方式。
  • 妈个鸡

6.日志

6.1日志工厂

如果一个数据库操作,出现了异常,我们需要排错,日志就是最好的帮手

曾经:输出语句,debug

现在:日志工厂

  • SLF4J
  • LOG4J【掌握】
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING
  • NO_LOGGING

在mybatis中具体使用哪一个日志实现,,在设置中设定

在mybatis核心文件中配置

<settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

log4j配置代码

#将等级为DEBuG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/hyc.log
log4j.appender.file.MaxFileSize=1mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
1og4j.1ogger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
1og4j.1ogger.java.sql.statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.1ogger.java.sql.PreparedStatement=DEBUG

6.2 LOG4J

什么是log4j

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件

通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

  1. 使用一个外部类需要先倒入包
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2.解决idea下resource无法使用的新maven配置文件代码

<resource>
                <directory>${basedir}/src/main/webapp</directory>
            </resource>
            <resource>
                <directory>${basedir}/src/main/resources</directory>
            </resource>
            <resource>
                <directory>${basedir}/src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>

简单使用

  1. 要在使用log4j的类中,导入包,
  2. 日志对象加载参数为当前类的class
static Logger logger = Logger.getLogger(Test.class);


  1. 日志级别
@org.junit.Test
    public void  testlog4j(){
    logger.info("进入了testLog4j");
    logger.debug("进入了debug");
    logger.error("error:进入了异常");
    }
}


MyBatis 优秀的持久层框架(二)https://developer.aliyun.com/article/1469534

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
Java 数据库连接 Maven
后端框架学习-----mybatis(使用mybatis框架遇到的问题)
这篇文章总结了在使用MyBatis框架时可能遇到的几个常见问题及其解决方法,包括配置文件注册、接口绑定、方法名匹配、返回类型匹配、Maven资源导出、时区设置和字符编码问题。
|
9天前
|
缓存 Cloud Native 安全
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
16 0
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
Java 数据库连接 mybatis
mybatis框架图
文章介绍了MyBatis框架的起源、发展和其作为持久层框架的功能,提供了MyBatis的框架图以帮助理解其结构和组件。
mybatis框架图
|
3月前
|
安全 Java 数据库连接
后端框架的学习----mybatis框架(3、配置解析)
这篇文章详细介绍了MyBatis框架的核心配置文件解析,包括环境配置、属性配置、类型别名设置、映射器注册以及SqlSessionFactory和SqlSession的生命周期和作用域管理。
后端框架的学习----mybatis框架(3、配置解析)
|
3月前
|
Java 数据库连接 mybatis
后端框架的学习----mybatis框架(9、多对一处理和一对多处理)
这篇文章介绍了在MyBatis框架中如何处理多对一和一对多的关联查询,通过定义`<resultMap>`和使用`<association>`与`<collection>`元素来实现对象间的关联映射。
|
3月前
|
Java 数据库连接 测试技术
后端框架的学习----mybatis框架(8、lombok)
这篇文章介绍了如何在MyBatis框架中使用lombok库来简化Java实体类的编写,包括在IDEA中安装Lombok插件、在项目中导入lombok依赖以及在实体类上使用Lombok提供的注解。
|
3月前
|
Java 数据库连接 数据库
后端框架的学习----mybatis框架(6、日志)
这篇文章介绍了如何在MyBatis框架中使用日志功能,包括配置MyBatis的日志实现、使用log4j作为日志工具,以及如何通过配置文件控制日志级别和输出格式。
|
4月前
|
Java 数据库连接 Spring
搭建 spring boot + mybatis plus 项目框架并进行调试
搭建 spring boot + mybatis plus 项目框架并进行调试
79 4
|
3月前
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
31 0