最新Mybatis快速上手(详解)

Posted Mest514

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最新Mybatis快速上手(详解)相关的知识,希望对你有一定的参考价值。

前言

Mybatis快速学习,最全最详细,入坑狂神,ssm框架必备资源,文档笔记来源:kuangshenstudy,结合视频资源食用更佳,相关资源在文末,有需要自取。

一、Mybatis简介?

MyBatis 本是 Apache 的一个开源项目 iBatis ,2010年这个项目由 Apache Software Foundation 迁移到了 Google Code ,并且改名为 MyBatis。 MyBatis 是一个基于 Java 的持久层框架。 MyBatis 提供的持久层框架包括 sQL Maps 和 Data Access Objects ( DAO ),它消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。 MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs ( Plain Old Java Objects ,普通的 Java 对象)映射成数据库中的记录。

目前, Java 的持久层框架产品有许多,常见的有 Hibernate 和 MyBatis 。 MyBatis 是一个半自动映射的框架,因为 MyBatis 需要手动匹配PoJ0、 sQL 和映射关系;而 Hibernate 是一个全表映射的框架,只需提供POJ0和映射关系即可。 MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架; Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。两个持久层框架各有优缺点,开发者应根据实际应用选择它们。

二、Mybatis的工作原理

  1. 读取Mybatis配置文件:(例如数据库连接信息)
  2. 加载映射文件:(即sql映射文件,该文件中配置了操作数据库的sql语句,mybatis-config.xml文件可以加载多个映射文件,每个文件对应数据库中的一张表)
  3. 构造会话工厂:(通过Mybatis的环境配置信息构造会话工厂SqlSessionFactory)
  4. 创建会话对象:由会话对象创建SqlSession对象,该对象中包含了执行sql语句的所有方法。
  5. Executor执行器: MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 sql 语句,同时负责查询缓存的维护。
  6. MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 sql 语句的 id 、参数等信息。
  7. 输入参数映射:输入参数类型可以是 Map 、 List 等集合类型,也可以是基本数据类型和pojo类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。
  8. 输出结果映射:输出结果类型可以是 Map 、 List 等集合类型,也可以是基本数据类型和pojo类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

mybatis框架的执行流程图:

MyBatis的优点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件就可以了,易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供xml标签,支持编写动态sql
  • 最重要的一点,使用的人多!公司需要!

三、MyBatis第一个程序

思路流程:搭建环境–>导入Mybatis—>编写代码—>测试

1、搭建实验数据库

2、导入MyBatis相关 jar 包

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.5.2</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.47</version>
</dependency>

3、编写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=utf8"/>
               <property name="username" value="root"/>
               <property name="password" value="123456"/>
           </dataSource>
       </environment>
   </environments>
   <mappers>
       <mapper resource="com/mest/dao/userMapper.xml"/>
   </mappers>
</configuration>

4、编写MyBatis工具类

package com.mest.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;

//工具类
public class MybatisUtils 
    private static SqlSessionFactory sqlSessionFactory;
    static 

        try 
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
//            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
         catch (IOException e) 
            e.printStackTrace();
        
    
    public static SqlSession getSqlSession()
      return sqlSessionFactory.openSession();

    




5、创建实体类

public class User 
   
   private int id;  //id
   private String name;   //姓名
   private String pwd;   //密码
   
   //构造,有参,无参
   //set/get
   //toString()
   //可用注解
   

6、编写Mapper接口类

import com.kuang.pojo.User;
import java.util.List;

public interface UserMapper 
   List<User> selectUser();

7、编写Mapper.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="com.kuang.dao.UserMapper">
 <select id="selectUser" resultType="com.mest.pojo.User">
  select * from user
 </select>
</mapper>

注意:namespace的路径不可出错

8、编写测试类

public class MyTest 
   @Test
   public void selectUser() 
       SqlSession session = MybatisUtils.getSession();
       //方法一:
       //List<User> users = session.selectList("com.kuang.mapper.UserMapper.selectUser");
       //方法二:
       UserMapper mapper = session.getMapper(UserMapper.class);
       List<User> users = mapper.selectUser();

       for (User user: users)
           System.out.println(user);
      
       session.close();
  

Maven静态资源过滤问题:在pom.xml中导入

<resources>
   <resource>
       <directory>src/main/java</directory>
       <includes>
           <include>**/*.properties</include>
           <include>**/*.xml</include>
       </includes>
       <filtering>false</filtering>
   </resource>
   <resource>
       <directory>src/main/resources</directory>
       <includes>
           <include>**/*.properties</include>
           <include>**/*.xml</include>
       </includes>
       <filtering>false</filtering>
   </resource>
</resources>

9、运行测试

成功,所有user信息被打印

四、CURD操作

基于上例,进阶CURD操作

将上面案例中的UserMapper接口改名为 UserDao;

将UserMapper.xml中的namespace改为为UserDao的路径 ;

再次测试.

结论:
配置文件中namespace中的名称为对应Mapper接口或者Dao接口的完整包名,必须一致!

1、select

  • select标签是mybatis中最常用的标签之一
  • select语句有很多属性可以详细配置每一条SQL语句
    • SQL语句返回值类型。【完整的类名或者别名】
    • 传入SQL语句的参数类型 。【万能的Map,可以多尝试使用】
    • 命名空间中唯一的标识符
    • 接口中的方法名与映射文件中的SQL语句ID 一一对应
    • id
    • parameterType
    • resultType

需求:根据id查询用户

1、在UserMapper中添加对应方法

public interface UserMapper 
//获取查询全部用户
    List<User> getuerlist();

    //根据id查询用户
    User getUserById(int id);

2、在UserMapper.xml中添加Select语句

    <select id="getUserById" parameterType="int" resultType="com.mest.pojo.User">
        select * from mybatis.user where id=#id
    </select>

3、测试类中测试

    @Test
    public void getUserById()
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User userById = mapper.getUserById(2);
        System.out.println(userById);
        sqlSession.close();
    

1.1万能查询Map和传参查询

思路一:使用万能的Map
1、在接口方法中,参数直接传递Map;

    //万能map
    Integer addUser2(Map<String,Object> map);

2、编写sql语句的时候,需要传递参数类型,参数类型为map

    <select id="getUserById2" parameterType="map" resultType="com.mest.pojo.User">
        select * from mybatis.user where id=#id and name=#name
    </select>

3、在使用方法的时候,Map的 key 为 sql中取的值即可,没有顺序要求!

    @Test
    public void getUserById2()
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map<String,Object> map=new HashMap<String, Object>();
        System.out.println(map.get(2));
        sqlSession.close();
    

思路二:直接在方法中传递参数

1、在接口方法的参数前加 @Param属性

2、Sql语句编写的时候,直接取@Param中设置的值即可,不需要单独设置参数类型

//通过密码和名字查询用户
User selectUserByNP(@Param("username") String username,@Param("pwd") String pwd);

/*
   <select id="selectUserByNP" resultType="com.kuang.pojo.User">
     select * from user where name = #username and pwd = #pwd
   </select>
*/

1.2思考:模糊查询

    //模糊查询用户
    List<User> getUserLike(String value);

    <select id="getUserLike" resultType="com.mest.pojo.User">
        select * from mybatis.user where name like #value ;
    </select>
    @Test
    public void getUserLike()
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserLike("%西%");
        for (User user : userList) 
            System.out.println(user);
        
        sqlSession.close();
    

2、insert

需求:给数据库增加一个用户

1、在UserMapper接口中添加对应的方法

    //insert用户
    Integer addUser(User user);

2、在UserMapper.xml中添加insert语句

    <insert id="addUser" parameterType="com.mest.pojo.User">
        insert into mybatis.user (id,name,pwd) values($id,#name,#pwd);
    </insert>

3、测试

    @Test
    public void addUser()
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);

        int res = mapper.addUser(new User(10, "fake", "123456"));
        if(res>0)
            System.out.println("添加成功");
        
        //提交事物
        sqlSession.commit();
        //关闭sqlSession
        sqlSession.close();
    

3、update

需求:修改用户的信息

1、同理,编写接口方法

    //update
    Integer upDateUser(User user);

2、编写对应的配置文件SQL

    <update id="upDateUser" parameterType="com.mest.pojo.User">
        update  mybatis.user set name=#name,pwd=#pwd where id=#id;
    </update>

3、测试

    @Test
    public void upDateUser()
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Integer res = mapper.upDateUser(new User(4, "赛赛", "520"));
        if(res>0)
            System.out.println("修改成功");
        
        //提交事物
        sqlSession.commit();//提交事务,重点!不写的话不会提交到数据库
        //关闭sqlSession
        sqlSession.close();
    

4、delete

需求:根据id删除一个用户

1、同理,编写接口方法

    //delete
    Integer deleteUser(int id);

2、编写对应的配置文件SQL

    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id=#id;
    </delete>

3、测试

    @Test
    public void deleteUser()
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Integer res = mapper.deleteUser(1);

        if(res>0)
            System.out.println("删除成功");
        
        //提交事物
        sqlSession.commit();
        //关闭sqlSession
        sqlSession.close();
    

5、配置解析

5.1 核心配置文件

  • mybatis-config.xml 系统核心配置文件
  • MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
  • 能配置的内容如下:
  • configuration(配置)
  • properties(属性)
  • settings(设置)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境配置)
  • environment(环境变量)
  • transactionManager(事务管理器)
  • dataSource(数据源)
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器)

5.2 environments元素

<environments default="development">
 <environment id="development">
   <transactionManager type="JDBC">
     <property name="..." value="..."/>
   </transactionManager>
   <dataSource type="POOLED">
     <property name="driver" value="$driver"/>
     <property name="url" value="$url"/>
     <property name="username" value="$username"/>
     <property name="password" value="$password"/>
   </dataSource>
 </environment>
</environments>
  • 配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定)
  • 子元素节点:environment
    • dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。

    • 数据源是必须配置的。

    • 有三种内建的数据源类型

      type="[UNPOOLED|POOLED|JNDI]")

    • unpooled:这个数据源的实现只是每次被请求时打开和关闭连接。

    • pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web
      应用快速响应请求的流行处理方式。

    • jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI
      上下文的引用。

    • 数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等…

    • 详情:点击查看官方文档

    • 这两种事务管理器类型都不需要设置任何属性。

    • 具体的一套环境,通过设置id进行区别,id保证唯一!

    • 子元素节点:transactionManager - [ 事务管理器 ]

    • 子元素节点:数据源(dataSource)

5.3 mappers元素

  • 映射器 : 定义映射SQL语句文件
  • 既然 MyBatis 的行为其他元素已经配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的URL),或类名和包名等。映射器是MyBatis中最核心的组件之一,在MyBatis 3之前,只支持xml映射器,即:所有的SQL语句都必须在xml文件中配置。而从MyBatis 3开始,还支持接口映射器,这种映射器方式允许以Java代码的方式注解定义SQL语句,非常简洁。

引入资源方式

<!-- 使用相对于类路径的资源引用 -->
<mappers>
 <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
 <mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
<!--
使用映射器接口实现类的完全限定类名
需要配置文件名称和接口名称一致,并且位于同一目录下
-->
<mappers>
 <mapper class="org.mybatis.builder.AuthorMapper"/>
</mappers>
<!--
将包内的映射器接口实现全部注册为映射器
但是需要配置文件名称和接口名称一致,并且位于同一目录下
-->
<mappers>
 <package name="org.mybatis.builder"/>
</mappers>

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">
<mapper namespace="com.kuang.mapper.UserMapper">
   
</mapper>

namespace中文意思:命名空间,作用如下:

  • namespace的命名必须跟某个接口同名
  • 接口中的方法与映射文件中sql语句id应该一一对应
  • namespace和子元素的id联合保证唯一 , 区别不同的mapper
  • 绑定DAO接口
  • namespace命名规则 : 包名+类名

5.4 Properties优化

数据库这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。具体的官方文档

我们来优化我们的配置文件

第一步 ; 在资源目录下新建一个db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=123456

第二步 : 将文件导入properties 配置文件

<configuration>
   <!--导入properties文件-->
   <properties resource="db.properties"/>

   <environments default="development">
       <environment id="development">
           <transactionManager type="JDBC"/>
           <dataSource type="POOLED">
               <property name="driver" value="$driver"/>
               <property name="url" value="$url"/>
               <property name="username" value="$username"/>
               <property name="password" value="$password"MyBatis-Plus 是一个 MyBatis 的增强工具;

先构建一个 spring boot 项目

1. 添加依赖

        <!-- 数据库 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <!-- 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
        <!-- 代码生成器 如不使用可以不加 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!-- Druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.22</version>
        </dependency>
        <!-- 模板引擎 和代码生成器搭配使用,如不使用可以不加 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

2.配置

如果是 .yml 文件 ↓

spring:
  datasource: 
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource    # 数据源类型
    url: jdbc:h2:mem:test
    username: root
    password: test
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志

如果是 .properties文件 ↓

spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.url = jdbc:h2:mem:test
spring.datasource.username = root
spring.datasource.password = test
mybatis-plus.configuration.log-impl= org.apache.ibatis.logging.stdout.StdOutImpl #日志

更多 dataSource 配置 :https://www.cnblogs.com/toughzcf/p/9835867.html

在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = {"com.example.*"})
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

 

3. 生成 @Data,mapper 文件(此处我是用代码生成器直接生成的

代码生成器代码↓

// 代码生成器
    @Test
    void generator() {
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
        globalConfig.setAuthor("author");         // 作者名
        globalConfig.setOpen(false);

        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl(jdbcUrl);         // 数据库连接地址
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setUsername("root");     // 数据库用户名
        dataSourceConfig.setPassword("3wHNY2Bq"); // 数据库密码

        //3、策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true)      // 开启全局大写命名
//                .setDbColumnUnderline(true)    // 表名字段名使用下划线
                .setNaming(NamingStrategy.underline_to_camel)//下划线转驼峰的命名方式
                .setTablePrefix("xxxx_")         // 表名前缀
                .setEntityLombokModel(true)      // 使用lombok
                .setInclude("xxxx_sms");         // 逆向工程使用的表
        //4、包名策略配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig
                .setParent("com.example.demo")  // 设置包名的parent
                .setMapper("dao.xxxx")
//                .setService("service")        // service 文件目录
//                .setController("controller")  // controller 文件目录
                .setEntity("entity.xxxx")       // data文件目录
                .setXml("mapper/xxxx");         // 设置xml文件的目录  (暂没有找到xml文件直接存到 resource 目录下的方法,由于resource目录和java目录同级)

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        //控制 不生成 controller,server,impl 文件
        templateConfig.setController("").setService("").setServiceImpl("");

        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(globalConfig)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                .setTemplate(templateConfig);

        //6、执行
        autoGenerator.execute();
    }

4. 现在就可以直接使用增删改查了

@Service
public class HomeImpl implements HomeService {
    @Autowired
    private SmsMapper smsMapper;

    @Override
    public List sms(String phone) {
        QueryWrapper<Sms> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        return smsMapper.selectList(queryWrapper);
    }
}

 

以上是关于最新Mybatis快速上手(详解)的主要内容,如果未能解决你的问题,请参考以下文章

mybatis plus 快速上手

mybatis plus 快速上手

mybatis 注解快速上手

Spring MVC Spring MyBatis 整合 - 快速上手

Spring MVC Spring MyBatis 整合 - 快速上手

Mybatis-Plus01 快速上手