mybatis

文章目录

  • 一、mybatis简介
    • 1、mybatis的特性
  • 二、搭建mybatis
    • 1、创建Maven工程
      • ①、配置pom.xml文件
      • ②、创建mybatis的核心配置文件
      • ③、创建mapper接口
      • ④、创建mybatis的映射文件
      • ⑤、测试
      • ⑥、加入log4j日志功能
    • 2、核心配置文件详解
    • 3、mybatis的增删改查
      • ①、添加数据
      • ②、删除数据
      • ③、修改数据
      • ④、查询单行数据
      • ⑤、查询多行数据
      • ⑥、用map查询多行数据
    • 3、特殊的sql语句
      • ①、模糊查询(like)
      • ②、动态设置表名
      • ③、获取自增的主键
    • 4、自定义映射(resultMap)
      • ①、说明
      • ②、查询单个字段
    • 5、两种获取值的方式
      • ①、单个字面量类型的参数
      • ②、多个字面量类型的参数
      • ③、map集合类型的参数
      • ④、实体类类型的参数
      • ⑤、使用@Param标识参数
    • 6、多对一映射
      • ①、级联方式处理映射关系
      • ②、使用association处理映射关系
      • 3、分步查询
    • 7、mybatis缓存
      • ①、一级缓存
      • ②、二级缓存
      • ③、二级缓存的相关配置
      • ④、mybatis缓存查询的顺序
      • ⑤、整合第三方缓存EHCache
      • ⑥、mybatis逆向工程

一、mybatis简介

1、mybatis的特性

  • ①、mybatis是支持定制化的SQL,存储过程以及高级映射的优秀的持久层框架
  • ②、mybatis避免了几乎所有的jdbc代码和手动设置参数以及获取结果集
  • ③、mybatis开呀使用简单的xml或注解用于配置和原始映射,将接口和加吧的pojo映射成数据库中的记录

二、搭建mybatis

IDEA:2023版

MySQL:8.0.33

mybatis:3.5.7

1、创建Maven工程

①、配置pom.xml文件



    4.0.0

    xyz.zzj
    ssm
    1.0-SNAPSHOT    
    jar

    
        8
        8
        UTF-8
    

    
    
    
        org.mybatis
        mybatis
        3.5.7
    
    
    
    junit
        junit
        4.12
        test
    
        
        
            mysql
            mysql-connector-java
            8.0.33
        
    

②、创建mybatis的核心配置文件

  • 习惯上命名为mybatis-config.xml,这个文件名仅仅只是建议,并非强制要求。将来整合Spring
    之后,这个配置文件可以省略,所以大家操作时可以直接复制、粘贴。
    核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息
    核心配置文件存放的位置是src/main/resources目录下

    
    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.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/ssm?
    serverTimezone=UTC"/>
                    <property name="username" value="root"/>
                    <property name="password" value="zzj0806"/>
                dataSource>
            environment>
        environments>
        
        <mappers>
            <mapper resource="mappers/UserMapper.xml"/>
        mappers>
    configuration>
    

③、创建mapper接口

public interface UserMapper {
/**
* 添加用户信息
*/
int insertUser();
}

④、创建mybatis的映射文件

1、映射文件的命名规则:
表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
因此一个映射文件对应一个实体类,对应一张表的操作
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
MyBatis映射文件存放的位置是src/main/resources/mappers目录下
2、 MyBatis中可以面向接口操作数据,要保证两个一致:
a>mapper接口的全类名和映射文件的命名空间(namespace)保持一致
b>mapper接口中方法的方法名和映射文件中编写SQL的标签的id属性保持一致


DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.mapper.UserMapper">

    <insert id="insertUser">
    insert into t_user values(null,'admin','123456',23,'男','[email protected]')
    insert>
mapper>

⑤、测试

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.Test;
import xyz.zzj.mybatis.mapper.UserMapper;

import java.io.IOException;
import java.io.InputStream;


public class MybatisTest {

    @Test
    public void test1() throws IOException {
        //读取MyBatis的核心配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new
                SqlSessionFactoryBuilder();
        //通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
        //创建SqlSession对象,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务
        //SqlSession sqlSession = sqlSessionFactory.openSession();
        //创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //通过代理模式创建UserMapper接口的代理实现类对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //调用UserMapper接口中的方法,就可以根据UserMapper的全类名匹配元素文件,通过调用的方法名匹配
        //映射文件中的SQL标签,并执行标签中的SQL语句
        int result = userMapper.insertUser();
        //sqlSession.commit();
        System.out.println("结果:"+result);
    }
}
  • SqlSession:代表Java程序和数据库之间的会话。(HttpSession是Java程序和浏览器之间的会话)
  • SqlSessionFactory:是“生产”SqlSession的“工厂”。
  • 工厂模式:如果创建某一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。

⑥、加入log4j日志功能

  • 1、依赖

    
    <dependency>
        <groupId>log4jgroupId>
        <artifactId>log4jartifactId>
        <version>1.2.17version>
    dependency>
    
  • 2、加入配置文件

    log4j的配置文件名为log4j.xml,存放的位置是src/main/resources目录下

    
    DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
        <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
            <param name="Encoding" value="UTF-8" />
            <layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}%m (%F:%L) \n" />
            layout>
        appender>
        <logger name="java.sql">
            <level value="debug" />
        logger>
        <logger name="org.apache.ibatis">
            <level value="info" />
        logger>
        <root>
            <level value="debug" />
            <appender-ref ref="STDOUT" />
        root>
    log4j:configuration>
    

2、核心配置文件详解

mybatis_第1张图片

3、mybatis的增删改查

①、添加数据

    
    <insert id="insertUser">
        insert into t_user values(null,'admin','123456',23,'男','[email protected]')
    insert>

②、删除数据



    <delete id="deleteUser">
        delete from t_user where id = #{id}  

    delete>

③、修改数据


    <update id="updateUser">
        update t_user set age = 17,username = 'yy' where id = #{id}
    update>

④、查询单行数据


    <select id="selectUser" resultType="xyz.zzj.mybatis.pojo.User">
        select * from t_user where id = #{id}
    select>

⑤、查询多行数据


    <select id="selectUsers" resultType="xyz.zzj.mybatis.pojo.User">
        select * from t_user
    select>

⑥、用map查询多行数据


    <select id="selectUserMap" resultType="java.util.Map">
        select * from t_user
    select>
 maps.forEach(System.out::println);  //foreach来遍历数据

3、特殊的sql语句

①、模糊查询(like)

/**
* 测试模糊查询
* @param mohu
* @return
*/
List<User> testMohu(@Param("mohu") String mohu);

<select id="testMohu" resultType="User">


select * from t_user where username like "%"#{mohu}"%"
select>

②、动态设置表名

/**
* 动态设置表名,查询所有的用户信息
* @param tableName
* @return
*/
List<User> getAllUser(@Param("tableName") String tableName);

<select id="getAllUser" resultType="User">
select * from ${tableName}
select>

③、获取自增的主键

/**
* 添加用户信息
* @param user
* @return
* useGeneratedKeys:设置使用自增的主键
* keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参
数user对象的某个属性中
*/
int insertUser(User user);

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert

4、自定义映射(resultMap)

①、说明

<resultMap id="userMap" type="User">
    <id property="id" column="id">id>
    <result property="userName" column="user_name">result>
    <result property="password" column="password">result>
    <result property="age" column="age">result>
    <result property="sex" column="sex">result>
resultMap>

<select id="testMohu" resultMap="userMap">
    
    select id,user_name,password,age,sex from t_user where user_name like
    concat('%',#{mohu},'%')
select>

若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)
此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系
a>可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
b>可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰
例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName

②、查询单个字段

    
<resultMap id="userMap1" type="java.util.HashMap">
    <result property="userName" column="username">result>
resultMap>
<select id="selectUser2" resultMap="userMap1">
    select username from t_user
select>

5、两种获取值的方式

①、单个字面量类型的参数

  • 若mapper接口中的方法参数为单个的字面量类型
  • 此时可以使用KaTeX parse error: Expected 'EOF', got '#' at position 4: {}和#̲{}以任意的名称获取参数的值,…{}需要手动加单引号

②、多个字面量类型的参数

  • 若mapper接口中的方法参数为多个时,此时MyBatis会自动将这些参数放在一个map集合中,以arg0,arg1…为键,以参数为值;以
  • param1,param2…为键,以参数为值;因此只需要通过KaTeX parse error: Expected 'EOF', got '#' at position 4: {}和#̲{}访问map集合的键就可以获…{}需要手动加单引号

③、map集合类型的参数

  • 若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中

  • 只需要通过KaTeX parse error: Expected 'EOF', got '#' at position 4: {}和#̲{}访问map集合的键就可以获…{}需要手动加单引号

④、实体类类型的参数

  • 若mapper接口中的方法参数为实体类对象时此时可以使用KaTeX parse error: Expected 'EOF', got '#' at position 4: {}和#̲{},通过访问实体类对象中的属…{}需要手动加单引号

⑤、使用@Param标识参数

  • 可以通过@Param注解标识mapper接口中的方法参数
  • 此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;以param1,param2…为键,以参数为值;只需要通过${}和#{}访问map集合的键就可以获取相对应
    的值,
  • {注意${}需要手动加单引号

6、多对一映射

①、级联方式处理映射关系

  • 场景模拟:
    查询员工信息以及员工所对应的部门信息

<resultMap id="empDeptMap" type="Emp">
    <id column="eid" property="eid">id>
    <result column="ename" property="ename">result>
    <result column="age" property="age">result>
    <result column="sex" property="sex">result>
    <result column="did" property="dept.did">result>
    <result column="dname" property="dept.dname">result>
resultMap>

<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
    select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did =dept.did where emp.eid = #{eid}
select>

②、使用association处理映射关系

<resultMap id="empDeptMap" type="Emp">
    <id column="eid" property="eid">id>
    <result column="ename" property="ename">result>
    <result column="age" property="age">result>
    <result column="sex" property="sex">result>
<association property="dept" javaType="Dept">
    <id column="did" property="did">id>
    <result column="dname" property="dname">result>
association>
resultMap>

<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
    select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did =
    dept.did where emp.eid = #{eid}
select>

3、分步查询


7、mybatis缓存

①、一级缓存

1、一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问。

2、一级缓存是自动生效的,哪怕只建立了一个mybatis的框架。

  • 使一级缓存失效的四种情况:
    • 不同的SqlSession对应不同的一级缓存
    • 同一个SqlSession但是查询条件不同
    • 同一个SqlSession两次查询期间执行了任何一次增删改操作
    • 同一个SqlSession两次查询期间手动清空了缓存

②、二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取

  • 二级缓存开启的条件:
    • 在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
    • 在映射文件中设置标签
    • 二级缓存必须在SqlSession关闭或提交之后有效
    • 查询的数据所转换的实体类类型必须实现序列化的接口
  • 使二级缓存失效的情况:
    • 两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

③、二级缓存的相关配置

在mapper配置文件中添加的cache标签可以设置一些属性:

  • 1、eviction属性:缓存回收策略,默认的是 LRU。
    • LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。
    • FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。
    • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
  • 2、flushInterval属性:刷新间隔,单位毫秒
    • 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
  • 3、size属性:引用数目,正整数
    • 代表缓存最多可以存储多少个对象,太大容易导致内存溢出
  • 4、readOnly属性:只读, true/false
    • true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了 很重要的性能优势。
    • false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。

④、mybatis缓存查询的顺序

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
如果二级缓存没有命中,再查询一级缓存
如果一级缓存也没有命中,则查询数据库
SqlSession关闭之后,一级缓存中的数据会写入二级缓存

⑤、整合第三方缓存EHCache

  • 添加依赖


<dependency>
    <groupId>org.mybatis.cachesgroupId>
    <artifactId>mybatis-ehcacheartifactId>
    <version>1.2.1version>
dependency>

<dependency>
    <groupId>ch.qos.logbackgroupId>
    <artifactId>logback-classicartifactId>
    <version>1.2.3version>
dependency>
  • 各jar包功能

jar包名称 作用
mybatis-ehcache mybatis和EHCache的整合包
ehcache EHCache核心包
slf4j-api slf4j日志包
logback-classic 支持slf4j门面接口的一个具体实现
  • 创建EHCache的配置文件ehcache.xml


<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

<diskStore path="D:\atguigu\ehcache"/>
    <defaultCache
        maxElementsInMemory="1000"
        maxElementsOnDisk="10000000"
        eternal="false"
        overflowToDisk="true"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    defaultCache>
ehcache>
  • 设置二级缓存的类型

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
  • 加入logback日志

    ---- 存在SLF4J时,作为简易日志的log4j将失效,此时我们需要借助SLF4J的具体实现logback来打印日志。 创建logback的配置文件logback.xml


<configuration debug="true">
    
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
         
         
            <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger]
                [%msg]%npattern>
        encoder>
    appender>
    
    
    <root level="DEBUG">
        
        <appender-ref ref="STDOUT" />
    root>
    
    <logger name="xyz.zzj.mybatis.mapper" level="DEBUG"/>
configuration>
  • EHCache配置文件说明

mybatis_第2张图片

⑥、mybatis逆向工程

正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向工程的。

  • 逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:

    • Java实体类

    • Mapper接口

    • Mapper映射文件

  • 添加依赖和插件
<dependencies>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.5.7version>
        dependency>
        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
            <scope>testscope>
        dependency>
        
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.17version>
        dependency>

        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.33version>
        dependency>
    dependencies>

    
<build>
    
    <plugins>
        
        <plugin>
            <groupId>org.mybatis.generatorgroupId>
            <artifactId>mybatis-generator-maven-pluginartifactId>
            <version>1.3.0version>
            
            <dependencies>
                
                <dependency>
                    <groupId>org.mybatis.generatorgroupId>
                    <artifactId>mybatis-generator-coreartifactId>
                    <version>1.3.2version>
                dependency>
                
                <dependency>
                    <groupId>mysqlgroupId>
                    <artifactId>mysql-connector-javaartifactId>
                    <version>8.0.33version>
                dependency>
            dependencies>
        plugin>
    plugins>
build>
  • 创建mybatis的核心配置,并补全详细信息
  • 创建逆向工程的核心配置文件

DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    
    <context id="DB2Tables" targetRuntime="MyBatis3">
        
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"
                        userId="root"
                        password="zzj0806">
        jdbcConnection>
        
        <javaModelGenerator targetPackage="xyz.zzj.mybatis.pojo" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />

        javaModelGenerator>
        
        <sqlMapGenerator targetPackage="xyz.zzj.mybatis.mapper" targetProject=".\src\main\resources">
            <property name="enableSubPackages" value="true" />
        sqlMapGenerator>
        
        <javaClientGenerator type="XMLMAPPER" targetPackage="xyz.zzj.mybatis.mapper" targetProject=".\src\main\java">
            <property name="enableSubPackages" value="true" />
        javaClientGenerator>
        
        
        
        <table tableName="t_emp" domainObjectName="Emp"/>
        <table tableName="t_dept" domainObjectName="Dept"/>
    context>
generatorConfiguration>
  • 执行插件

mybatis_第3张图片

  • 测试逆向工程生成的代码是否有用
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.Test;
import xyz.zzj.mybatis.mapper.DeptMapper;
import xyz.zzj.mybatis.pojo.Dept;

import java.io.IOException;
import java.io.InputStream;

public class test1 {

    @Test
    public void test1() throws IOException {
        //读取MyBatis的核心配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象
        SqlSessionFactory build = sqlSessionFactoryBuilder.build(is);
        //对事务进行提交
        SqlSession sqlSession = build.openSession(true);
        //通过代理模式创建UserMapper接口的代理实现类对象
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Dept dept = new Dept();
        dept.setDeptName("zzj");
        dept.setDeptId(7);
        int insert = mapper.insertSelective(dept);
        System.out.println(insert);
        sqlSession.close();
    }

}

你可能感兴趣的:(mybatis)