Mybatis学习笔记

Mybaits3

写在文章前面

根据B站大佬狂神说的视频学习的Mybatis,然后整理的笔记。

  • 视频合集地址:狂神说Java-Mybatis教程
  • jdk:1.8
  • Maven:3.6.1
  • mysql:5.7.36
  • 开发工具:IDEA 2022
  • mybaits3中文官网:https://mybatis.org/mybatis-3/zh/index.html
  • github地址:https://github.com/mybatis/mybatis-3
  • 本笔记中源代码下载:https://download.csdn.net/download/u011301348/87774404

1、简介

1、1 什么是Mybatis

  • 是一款优秀的持久层框架。
  • 是一个开源、轻量级的,JDBC的替代方案。
  • 支持自定义 SQL、存储过程以及高级映射。
  • 免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。
  • 可以通过简单的XML或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • 内部封装了JDBC,简化了加载驱动、创建连接、创建 statement 等繁杂的过程,开发者只需要关注 SQL 语句本身。
  • 是一个半自动化的ORM框架 (Object Relationship Mapping) —>对象关系映射

1、2 MyBatis历史

  • MyBatis本是apache的一个开源项目iBatis,2002 年由 Clinton Begin 发布。
  • 2010 年从 Apache 迁移到 Google,并改名为 MyBatis。
  • 2013 年又迁移到了 Github。

1、3 MyBatis优点

  • 是免费且开源的。
  • 与 JDBC 相比,减少了 50% 以上的代码量。
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。
  • 灵活:不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 提供 XML 标签,支持编写动态 SQL 语句。
  • 提供映射标签,支持对象与数据库的 ORM 字段关系映射。
  • 使用的人多!公司需要!随大流!

1、4 MyBatis缺点

  • 编写 SQL 语句工作量较大,对开发人员编写 SQL 语句的功底有一定要求。
  • SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

2、Mybatis第一个程序

2、1 创建数据库、表

CREATE DATABASE `mybatis`;
USE `mybatis`;

CREATE TABLE `user`(
  `id` INT NOT NULL PRIMARY KEY,
  `name` VARCHAR(30) DEFAULT NULL,
  `pwd` VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `user`(`id`,`name`,`pwd`) VALUES (1,'狂神','123456'),(2,'张三','123456'),(3,'李四','123890')

2、2 导入mybatis、mysql、junit依赖


<dependency>
    <groupId>org.mybatisgroupId>
    <artifactId>mybatisartifactId>
    <version>3.5.5version>
dependency>

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>8.0.29version>
dependency>

<dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
dependency>

2、3 编写配置文件,文件位置一般放在resources目录中

  1. 数据库配置文件,db.properties
Driver=com.mysql.jdbc.Driver
Url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&userUnicode=true&characterEncoding=utf-8
UserName=root
PassWord=123456
  1. Mybatis核心配置文件,mybaits-config.xml

DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <properties resource="db.properties">properties>
    
	
    <typeAliases>
        
        <typeAlias type="com.liushq.pojo.User" alias="user" />

        
        <package name="com.liushq.pojo" />
    typeAliases>
    
    
    <environments default="development">
        <environment id="development">
            
            <transactionManager type="JDBC">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>
    
    <mappers>
        <mapper resource="com/liushq/mapper/UserMapper.xml" />
    mappers>
configuration>

2、4 创建项目

  1. 创建一个普通maven项目mybatis-study,并删除src文件夹。
    Mybatis学习笔记_第1张图片
    完整的pom.xml文件内容

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <groupId>com.liushqgroupId>
    <artifactId>mybatis-studyartifactId>
    <packaging>pompackaging>
    <version>1.0-SNAPSHOTversion>

    <properties>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.5version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.29version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>
    dependencies>

    <build>
        
        <resources>
            
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
            <resource>
                <directory>src/main/resourcesdirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
        resources>
    build>
project>
  1. 在项目下新建模块mybatis-01,并完善项目结构及配置。
    Mybatis学习笔记_第2张图片
  2. 在utils包下,编写MyBatis工具类,MyBaitsUtils
package com.liushq.utils;

public class MyBaitsUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}
  1. 在pojo包下,编写User实体类
package com.liushq.pojo;

public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    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 getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
  1. 在mapper包下,编写UserMapper接口
package com.liushq.mapper;

public interface UserMapper {
    List<User> getUserList();

    List<User> getUserListByMap(Map<String,Object> map);

    User getUserInfo(int id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUser(int id);
}
  1. 在resourses下,新建mapper文件夹,并在该文件夹下编写UserMapper.xml配置文件

DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.liushq.mapper.UserMapper">
    <select id="getUserList" resultType="com.liushq.pojo.User">
        select * from user;
    select>

    <select id="getUserListByMap" parameterType="map" resultType="com.liushq.pojo.User">
        select * from mybatis.user where name like '%${name}%';
    select>

    <select id="getUserInfo" parameterType="int" resultType="com.liushq.pojo.User">
        select * from mybatis.user where id=#{id};
    select>

    <insert id="addUser" parameterType="com.liushq.pojo.User">
        insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd})
    insert>

    <update id="updateUser" parameterType="com.liushq.pojo.User">
        update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
    update>

    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id=#{id}
    delete>
mapper>
  1. 在service包下,编写UserService接口及实现类
package com.liushq.service;

public interface UserService {
    List<User> getUserList();

    List<User> getUserListByMap(String name);

    User getUserInfo(int id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUser(int id);
}
package com.liushq.service.Impl;

public class UserServiceImpl implements UserService {
    private SqlSession sqlSession = MyBaitsUtils.getSqlSession();
    private UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    @Override
    public List<User> getUserList() {
        List<User> list=mapper.getUserList();
        sqlSession.close();
        return list;
    }

    @Override
    public List<User> getUserListByMap(String name) {
        Map<String,Object> map=new HashMap<>();
        map.put("name",name);
        List<User> list=mapper.getUserListByMap(map);
        sqlSession.close();
        return list;
    }

    @Override
    public User getUserInfo(int id) {
        User user=mapper.getUserInfo(id);
        sqlSession.close();
        return user;
    }

    @Override
    public int addUser(User user) {
        int res=mapper.addUser(user);
        sqlSession.commit();
        sqlSession.close();
        return res;
    }

    @Override
    public int updateUser(User user) {
        int res=mapper.updateUser(user);
        sqlSession.commit();
        sqlSession.close();
        return res;
    }

    @Override
    public int deleteUser(int id) {
        int res=mapper.deleteUser(id);
        sqlSession.commit();
        sqlSession.close();
        return res;
    }
}
  1. 编写测试类
package com.liushq.service;

import com.alibaba.fastjson.JSONObject;

public class UserServiceTest {
   private UserService service=new UserServiceImpl();

    @Test
    public void getUserList(){
        List<User> userList = service.getUserList();
        for (User user : userList) {
            System.out.println(JSONObject.toJSONString(user));
        }
    }

    @Test
    public void getUserListByMap(){
        List<User> userList = service.getUserListByMap("i");
        for (User user : userList) {
            System.out.println(user);
        }
    }

    @Test
    public void getUserInfo(){
        User user = service.getUserInfo(1);
        System.out.println(user);
    }

    @Test
    public void addUser(){
        User user=new User(5,"xiaoma1","123123");
        int res= service.addUser(user);
        System.out.println(res>0?"添加成功":"添加失败");
    }

    @Test
    public void updateUser(){
        User user=new User(5,"xiaoma1111","123123111");
        int res= service.updateUser(user);
        System.out.println(res>0?"修改成功":"修改失败");
    }

    @Test
    public void deleteUser(){
        int res= service.deleteUser(4);
        System.out.println(res>0?"删除成功":"删除失败");
    }
}
  1. json处理,需要在mybatis-01的pom.xml中添加json依赖,这里用的是com.alibaba.fastjson
<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>fastjsonartifactId>
    <version>1.2.83version>
    <scope>testscope>
dependency>
  1. 测试结果,getUserList方法
    Mybatis学习笔记_第3张图片
  2. 完整项目结构图
    Mybatis学习笔记_第4张图片

3、XML映射器(Mapper.xml)及CRUD操作


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liushq.mapper.UserMapper">
mapper>
  • namespace:命名空间
    • 绑定DAO接口,必须跟某个接口同名。
    • 相当于通过xml配置文件,实现了mapper接口。
  • select:查询标签,对应sql中的select查询语句。
    • id:对应mapp接口中的接口名称。
    • parameterType:接口的参数类型。
    • resultType:接口的返回结果类型。
    • resultMap:返回外部 resultMap 的命名引用。
<select id="getUserInfo" parameterType="int" resultType="com.liushq.pojo.User">
    select * from mybatis.user where id=#{id};
select>
  • insert:插入数据标签,对应sql中的insert语句。
<insert id="addUser" parameterType="com.liushq.pojo.User">
   insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd})
insert>
  • update:更新数据标签,对应sql中的update语句。
<update id="updateUser" parameterType="com.liushq.pojo.User">
    update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
update>
  • delete:删除标签,对应sql中的delete语句。
<delete id="deleteUser" parameterType="int">
    delete from mybatis.user where id=#{id}
delete>

注意点:增、删、改操作需要提交事务!

4、Mybatis-config.xml配置解析

mybatis中可以配置的内容如下:


configuration(配置)
	properties(属性)
	settings(设置)
	typeAliases(类型别名)
	typeHandlers(类型处理器)     
	objectFactory(对象工厂)      
	plugins(插件)                
	environments(环境配置)
		environment(环境变量)
		transactionManager(事务管理器)
		dataSource(数据源)
	databaseIdProvider(数据库厂商标识)
	mappers(映射器)

4、1 properties(属性)

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


<properties resource="db.properties">properties>


<properties resource="db.properties">
  <property name="UserName" value="root"/>
  <property name="PassWord" value="123456"/>
properties>

如果一个属性在不只一个地方进行了配置,比如:UserName跟PassWord,在db.properties配置文件里有,在properties标签中也有,那么,MyBatis 将按照下面的顺序来加载:

  • 首先读取在 properties 标签元素体内指定的属性。
  • 然后根据 properties 元素中的 resource 属性读取引用的配置文件,并覆盖之前读取过的同名属性。
  • 最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
  • 意思就是在properties标签中设置的属性,会被在db.properties配置文件中的同名属性所覆盖。

设置好的属性后,就可以在整个配置文件中用来替换需要动态配置的属性值。例如:

<dataSource type="POOLED">
   
   <property name="driver" value="${Driver}"/>
   
   <property name="url" value="${Url}" />
   <property name="username" value="${UserName}" />
   <property name="password" value="${PassWord}" />
dataSource>

4、2 settings(设置)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。这里只罗列一些常用的、比较重要的,其他的可以自行看官网文档。

设置名 描述 有效值 默认值
cacheEnabled 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true或false true
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 true或false false
mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。 true或false false
logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 SLF4J、LOG4J(3.5.9 起废弃)、LOG4J2、 JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING 未设置

一个配置完整的 settings 元素的示例如下:

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="aggressiveLazyLoading" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="safeResultHandlerEnabled" value="true"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
  <setting name="defaultScriptingLanguage" value="org.apache.ibatis.scripting.xmltags.XMLLanguageDriver"/>
  <setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumTypeHandler"/>
  <setting name="callSettersOnNulls" value="false"/>
  <setting name="returnInstanceForEmptyRow" value="false"/>
  <setting name="logPrefix" value="exampleLogPreFix_"/>
  <setting name="logImpl" value="SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING"/>
  <setting name="proxyFactory" value="CGLIB | JAVASSIST"/>
  <setting name="vfsImpl" value="org.mybatis.example.YourselfVfsImpl"/>
  <setting name="useActualParamName" value="true"/>
  <setting name="configurationFactory" value="org.mybatis.example.ConfigurationFactory"/>
settings>

4、3 类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:


<typeAliases>
    <typeAlias type="com.liushq.pojo.User" alias="User" />
typeAliases>


<typeAliases>
  <package name=""com.liushq.pojo"/>
typeAliases>

在UserMapper.xml中,没设置别名前

<select id="getUserList" resultType="com.liushq.pojo.User">
    select * from user;
select>

设置别名后,resultType中的类名可以直接使用别名

<select id="getUserList" resultType="User">
    select * from user;
select>

官网中有详细的别名介绍,可以自行查看。

4、4 环境配置(environments)

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中,尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。


<environments default="development">
	
    <environment id="development">
        
        <transactionManager type="JDBC">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>
    
    
    <environment id="test">
    	...
    environment>
environments>
  • environment:配置具体环境,可以有多个,id必须唯一。
  • transactionManager:事务管理器,有JDBC、MANAGED 2种可选。
    • JDBC:这个配置直接使用了 JDBC 的提交和回滚功能,它依赖从数据源获得的连接来管理事务作用域。
    • MANAGED:这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。
  • dataSource:数据源,有UNPOOLED、POOLED、JNDI 3种可选。
    • UNPOOLED:这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择。
    • POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。
    • JNDI:这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。

4、5 映射器(mappers)

既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。

<mappers>
  
  <mapper resource="mapper/UserMapper.xml"/>
  
  <mapper class="com.liushq.mapper.UserMapper"/>
  
  <package name="com.liushq.mapper"/>
mappers>

5、ResultMap用法

更新中。。。

你可能感兴趣的:(MyBatis,mybatis,java,狂神说)