Mybits学习

本文详细介绍了 MyBatis 框架的使用,包括环境搭建、配置解析、CRUD 操作、日志配置、分页实现、动态 SQL 和缓存机制。通过案例展示了如何创建实体类、Mapper 接口和 XML 映射文件,以及如何进行事务管理和日志输出。此外,还探讨了 MyBatis 中的注解开发、多对一关系映射和动态 SQL 片段的使用,最后提到了 MyBatis 的二级缓存配置以及 Ehcache 的集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境

JDK1.8

Mysql5.7

meaven3.6.1

什么是 MyBatis?

MyBatis 是一款优秀的持久层框架

,它支持自定义 SQL、存储过程以及高级映射

。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github

github地址:Releases · mybatis/mybatis-3 · GitHubMyBatis SQL mapper framework for Java. Contribute to mybatis/mybatis-3 development by creating an account on GitHub.https://github.com/mybatis/mybatis-3/releases

 中文文档:

mybatis – MyBatis 3 | 简介https://mybatis.org/mybatis-3/zh/index.htmlmeaven仓库

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.2</version>
</dependency>

 

 

 环境搭建

搭建数据库

CREATE DATABASE `mybatis`;
USE `mybatis`;

CREATE TABLE `user`(
	id INT PRIMARY KEY AUTO_INCREMENT,
	`name` VARCHAR(40) DEFAULT NULL,
	`password` VARCHAR(40) DEFAULT NULL
	
)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `user`(id,`name`,`password`)VALUE(1,'张三','123456'),(2,'李四','123456'),(3,'王五','123456');

新建项目

<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
    <!--父工程    -->
    <groupId>org.example</groupId>
    <artifactId>mybatis-study</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
<!--        mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
<!--        mybatis驱动-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>

</project>

创建一个模块

编写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核心配置文件-->
<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>
<!--    每一个Mapper.xml都需要在Mybaits核心配置文件中注册-->
    <mappers>
        <mapper resource="com/qi/dao/UserMapper.xml"/>
    </mappers>

</configuration>

编写mybatis工具类

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

//工具类
//sqlSessionFactory --> sqlSession
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            //使用mybatis的第一步,获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream 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();
    }

}

编写代码

实体类

package com.qi.entity;
//实体类
public class User {
    private int id;
    private String name;
    private String password;

    public User() {
    }

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

    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 getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

Dao接口

package com.qi.dao;

import com.qi.entity.User;

import java.util.List;

public interface UserDao {
    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">

<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.qi.dao.UserDao">

<!--    查询语句-->
    <select id="getUserList" resultType="com.qi.entity.User">
        select * from mybatis.user
    </select>
</mapper>

测试jutil


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

MapperRegistry?是什么

meaven资源失效

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
————————————————
版权声明:本文为优快云博主「zerozero121」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_45540125/article/details/115471705
package com.qi.dao;

import com.qi.entity.User;
import com.qi.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest {


    @Test
    public void test(){
        //第一步获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行SQL 方式一getMapper
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> userList = userDao.getUserList();

        for (User user : userList) {
            System.out.println(user);
        }

        //关闭SqlSession
        sqlSession.close();
    }
}

 七步

 CRUD

1nameSpace

nameSpace里面的包名要与Dao/Mapper接口包名一致

 Mapper

package com.qi.dao;

import com.qi.entity.User;

import java.util.List;

public interface UserMapper {
    //获取全部用户
    List<User> getUserList();

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

    //增加用户
    int addUser(User user);

    //修改事务
    int updateUser(User user);

    //删除一个用户
    int deleteUser(int id);
}

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

<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.qi.dao.UserMapper">

<!--    查询语句-->
    <select id="getUserList" resultType="com.qi.entity.User">
        select * from mybatis.user
    </select>

<!--    实现第二个-->
    <select id="getUserById" resultType="com.qi.entity.User" parameterType="int">
        select * from mybatis.user where id = #{id}
    </select>

<!--    实现第三个  对象中的属性可以直接取出来-->
    <insert id="addUser" parameterType="com.qi.entity.User">
        insert into mybatis.user(id,name,password)value (#{id},#{name},#{password});
    </insert>
<!--    实现第四个-->
    <update id="updateUser" parameterType="com.qi.entity.User">
        update mybatis.user
        set name = #{name},password = #{password}
        where id = #{id};
    </update>

<!--    实现第五个-->
    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id};
    </delete>
</mapper>

Test

package com.qi.dao;

import com.qi.entity.User;
import com.qi.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import javax.jws.soap.SOAPBinding;
import java.util.List;

public class UserDaoTest {


    @Test
    public void test(){
        //第一步获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        try {
                //执行SQL 方式一getMapper
                UserMapper userDao = sqlSession.getMapper(UserMapper.class);
                List<User> userList = userDao.getUserList();

                for (User user : userList) {
                    System.out.println(user);
                }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭SqlSession
            sqlSession.close();
        }

    }
    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User userById = mapper.getUserById(1);

        System.out.println(userById);

        sqlSession.close();
    }

    //增删改需要提交事务
    @Test
    public void addUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int res = mapper.addUser(new User(4, "爱的看哈", "123456"));
        if (res>0){
            System.out.println("success");
        }
        //提交事务
        sqlSession.commit();

        sqlSession.close();
    }

    @Test
    public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.updateUser(new User(4,"安静","11111"));

        sqlSession.commit();


        sqlSession.close();

    }

    @Test
    public void delectUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.deleteUser(4);

        sqlSession.commit();

        sqlSession.close();
    }

}

Map

  //map万能使用
    int addUser2(Map<String,Object> map);




<!--    万能的map查
        传递的是map 的key
-->
    <insert id="addUser" parameterType="map">
        insert into mybatis.user(id,name,password)value (#{userid},#{username},#{passWord});
    </insert>

    @Test
    public void addUser2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("userid",7);
        map.put("username","阿大赛");
        map.put("passWord","713212313");
        mapper.addUser2(map);

        sqlSession.close();
    }
}

 配置解析

CRUD

package com.qi.dao;

import com.qi.entity.User;


import java.util.List;
import java.util.Map;

public interface UserMapper {


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

    //获取全部用户
    List<User> getUserList();

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

    //map万能使用
    int addUser2(Map<String,Object> map);

    //增加用户
    int addUser(User user);

    //修改事务
    int updateUser(User user);

    //删除一个用户
    int deleteUser(int id);
}
<?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.qi.dao.UserMapper">

    <select id="getUserList" resultType="com.qi.entity.User">
        select * from mybatis.user
    </select>

    <select id="getUserById" resultType="com.qi.entity.User" parameterType="int">
        select * from mybatis.user where id = #{id}
    </select>

    <insert id="addUser" parameterType="com.qi.entity.User">
        insert into mybatis.user(id,name,password)values (#{id},#{name},#{password});
    </insert>

    <update id="updateUser" parameterType="com.qi.entity.User">
        update mybatis.user
        set name = #{name},password = #{password}
        where id = #{id};
    </update>

    <insert id="addUser2" parameterType="map">
        insert into mybatis.user(id,name,password)values (#{userid},#{username},#{passWord});
    </insert>

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

    <select id="getUserLike" resultType="com.qi.entity.User">
        select * from mybatis.user where name like #{value}
    </select>
</mapper>
package com.qi.dao;

import com.qi.entity.User;
import com.qi.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import javax.jws.soap.SOAPBinding;
import java.util.HashMap;
import java.util.List;

public class UserDaoTest {


    @Test
    public void test(){

        SqlSession sqlSession = MybatisUtils.getSqlSession();

        try {

                UserMapper userDao = sqlSession.getMapper(UserMapper.class);
                List<User> userList = userDao.getUserList();

                for (User user : userList) {
                    System.out.println(user);
                }
        }catch (Exception e){
            e.printStackTrace();
        }finally {

            sqlSession.close();
        }

    }
    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User userById = mapper.getUserById(1);

        System.out.println(userById);

        sqlSession.close();
    }

    @Test
    public void addUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int res = mapper.addUser(new User(4, "爱的看哈", "123456"));
        if (res>0){
            System.out.println("success");
        }

        sqlSession.commit();

        sqlSession.close();
    }

    @Test
    public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.updateUser(new User(4,"安静","11111"));

        sqlSession.commit();


        sqlSession.close();

    }

    @Test
    public void delectUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.deleteUser(4);

        sqlSession.commit();

        sqlSession.close();
    }

    @Test
    public void addUser2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("userid",7);
        map.put("username","阿大赛");
        map.put("passWord","713212313");
        mapper.addUser2(map);

        sqlSession.close();
    }

    @Test
    public void getUserLike(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        List<User> userList = mapper.getUserLike("%李%");
        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }
}

配置解析

 环境配置(environments)

        MyBatis 可以配置成适应多种环境

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

myBatis默认的事务管理器就是JDBC,连接池POOLED

 属性(properties)

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

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

1编写一个配置文件

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

 

 2在核心配置文件中引入

   <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>

1可以直接引入外部文件

2可以在其中增加一些属性配置

3两个文件中有同一个字段优先外部默认

类型别名(typeAliases)

意在降低冗余的全限定类名书写

 
    <typeAliases>
        <typeAlias type="com.qi.entity.User" alias="User"/>
    </typeAliases>

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

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

   <typeAliases>
<!--        <typeAlias type="com.qi.entity.User" alias="User"/>-->
        <package name="com.qi.entity"/>
    </typeAliases>

实体类少第一种,多就第二种,第一种可以自定义,第二种则需要通过注解自定义

@Alias("hello")

设置

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

 ​​​​​

 映射器(mappers)

 方式二 方式三

 作用域(Scope)和生命周期

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

SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了

局部变量

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。

 局部变量

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。想像为数据库连接池

。因此 SqlSessionFactory 的最佳作用域是应用作用域。

最简单的就是使用单例模式或者静态单例模式。

SqlSession

链接到连接池的一个请求

SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域

用完关闭

 每一个Mapper都代表一个 具体的业务

 解决属性名与字段名不一致问题

 

 

 解决方法其别名

resultMap

结果集映射

id name pwd

id name password

  

 <resultMap id="UserMap" type="User">
       <!--column数据库中的元素,property实体类中的字段-->
        <result column="id" property="id"></result>
        <result column="name" property="name"></result>
        <result column="password" property="pwd"></result>
    </resultMap>

    <select id="getUserById" resultMap="UserMap" >
        select * from mybatis.user where id = #{id}
    </select>

resultMap 元素是 MyBatis 中最重要最强大的元素。

ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

这就是 ResultMap 的优秀之处——你完全可以不用显式地配置它们

日志

日志工厂

如果数据库出现异常,我们排错,日志就是最好的助手

曾经的 sout debug

现在日志工厂

 

 具体使用日志在设置中设定

STDOUT_LOGGING标准日志输出

在mybatis核心配置文件中,配置我们的日志

 Log4j

1导入log4j的包

    <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

2log4j的properties文件

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

3配置log4为日志的实现

 <settings>
<!--        <setting name="logImpl" value="STDOUT_LOGGING"/>-->
        <setting name="logImpl" value="LOG4J"/>
    </settings>

4log4j 的使用

 简单使用

1,在使用的 Log4j 的类中导包

import org.apache.log4j.Logger;
package com.qi;

import com.qi.dao.UserMapper;
import com.qi.entity.User;
import com.qi.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;



public class UserDaoTest {

   static Logger logger = Logger.getLogger(UserDaoTest.class);

    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User userById = mapper.getUserById(1);

        System.out.println(userById);

        sqlSession.close();
    }

    @Test
    public void testLog4j(){
        logger.info("info:进入了testLog4j");
        logger.debug("debug:进入了testLog4j");
        logger.error("error:进入了testLog4j");
    }


}

-----------------------------------------
C:\Users\V556U\.jdks\corretto-1.8.0_302\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar=60143:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1\plugins\junit\lib\junit-rt.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\charsets.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\access-bridge-64.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\cldrdata.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\dnsns.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\jaccess.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\jfxrt.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\localedata.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\nashorn.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\sunec.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\sunjce_provider.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\sunmscapi.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\sunpkcs11.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\ext\zipfs.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\jce.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\jfr.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\jfxswt.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\jsse.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\management-agent.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\resources.jar;C:\Users\V556U\.jdks\corretto-1.8.0_302\jre\lib\rt.jar;C:\Users\V556U\Desktop\springboot\mybatis-study\mybatis-03\target\test-classes;C:\Users\V556U\Desktop\springboot\mybatis-study\mybatis-03\target\classes;C:\Users\V556U\.m2\repository\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar;C:\Users\V556U\.m2\repository\org\mybatis\mybatis\3.5.2\mybatis-3.5.2.jar;C:\Users\V556U\.m2\repository\junit\junit\4.11\junit-4.11.jar;C:\Users\V556U\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\V556U\.m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.qi.UserDaoTest,testLog4j
[INFO ] 2021-09-25 09:55:58,932 method:com.qi.UserDaoTest.testLog4j(UserDaoTest.java:31)
info:进入了testLog4j
[DEBUG] 2021-09-25 09:55:58,938 method:com.qi.UserDaoTest.testLog4j(UserDaoTest.java:32)
debug:进入了testLog4j
[ERROR] 2021-09-25 09:55:58,938 method:com.qi.UserDaoTest.testLog4j(UserDaoTest.java:33)
error:进入了testLog4j

Process finished with exit code 0

分页

减少数据的处理量

使用limit分页

语法        

select * from user limit startIndex,pageSize;
select * from user limit 2,2;

使用Mybatis实现分页,核心SQL

1接口

  List<User> getUserByLimit(Map<String,Integer> map);

2Mapper.XML

 <select id="getUserByLimit" parameterType="map" resultType="user">
        select * from mybatis.user limit #{startIndex},#{pageSize}
    </select>

3测试

    @Test
    public void getUserByLimit(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Integer> map = new HashMap<>();
        map.put("startIndex",0);
        map.put("pageSize",2);

        List<User> userList = mapper.getUserByLimit(map);
        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }

Mybatis分页插件

PageHelpe 可以查看官方的文档进行使用

使用注解开发

 

 

 使用注解开发

对于像 BlogMapper 这样的映射器类来说,还有另一种方法来完成语句映射。 它们映射的语句可以不用 XML 来配置,而可以使用 Java 注解来配置。

 本质反射机制

底层:动态代理

 CRUD

我们可以在工具类创建时自动提交事务

1openSession设置为true

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

//工具类
//sqlSessionFactory --> sqlSession
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            //使用mybatis的第一步,获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream 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(true);
    }

}

2接口加注解

package com.qi.dao;


import com.qi.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface UserMapper {

    @Select("select * from mybatis.user")
    List<User> getUser();

    //方法存在多个参数,所有参数前面必须加上注解@Param(“”)注解
    @Select("select * from user where id = #{id}")
    User getUserById(@Param("id") int id);

    @Insert("insert into user(id,name,password) values (#{id},#{name},#{password})")
    int addUser(User user);

    @Update("update user set name=#{name},password=#{password} where id =#{id}")
    int updateUser(User user);

    @Delete("delete from user where id =#{id}")
    int deleteUser(@Param("id") int id);
}

测试类

【注意我们必须将我们的接口绑定到核心配置文件中】

import com.qi.dao.UserMapper;
import com.qi.entity.User;
import com.qi.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserMapperTest {
    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

//        List<User> userList = mapper.getUser();
//
//        for (User user : userList) {
//            System.out.println(user);
//
//        }
//
//        User userById = mapper.getUserById(1);
//        System.out.println(userById);

//        mapper.addUser(new User(5,"理解啊的啦","211345"));

//        mapper.updateUser(new User(5,"ss","214222"));
        mapper.deleteUser(5);
        sqlSession.close();
    }
}

关于@Param()注解

 lombok

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>
    </dependencies>

 

@Data
@AllArgsConstructor
@NoArgsConstructor

 多对一

 

 SQl

CREATE TABLE `teacher`(
`id` INT(10) NOT NULL,
`name` VARCHAR(40) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`,`name`) VALUES (1,'杜老师');

CREATE TABLE `student`(
	id INT(10) NOT NULL,
	`name` VARCHAR(40) DEFAULT NULL,
	`tid` INT(10) DEFAULT NULL,
	PRIMARY KEY (`id`),
	KEY `fktid` (`tid`),
	CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher`(`id`)
	
)ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO student(`id`,`name`,`tid`) VALUES (1,'小明',1);
INSERT INTO student(`id`,`name`,`tid`) VALUES (2,'小红',1);
INSERT INTO student(`id`,`name`,`tid`) VALUES (3,'小张',1);
INSERT INTO student(`id`,`name`,`tid`) VALUES (4,'小李',1);
INSERT INTO student(`id`,`name`,`tid`) VALUES (5,'小王',1);

 环境搭建

1导入lombok

2新建实体类Teacher Student

3建立Mapper接口

4建立Mapper.xml文件

5在核心配置文件中绑定注册我们的Mapper接口或者文件

6测试查询是否能够成功

 按照查询嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.qi.dao.StudentMapper">

    
    <select id="getStudent" resultMap="StudentTeacher">
            select * from student;
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
<!--        <collection property=""/>-->
    </resultMap>
    

    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id = #{id};
    </select>
</mapper>

 按照结果嵌套处理


    <select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid,s.name sname,t.name tname
        from student s,teacher t
        where s.tid = t.id;
    </select>
    
    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="sid" />
        <result property="name" column="sname" />
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>
    

 一对多

一个老师对应多个学生

对于老师而言就是一对多的关系

package com.qi.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int id;
    private String name;
    //关联一个老师
    private int tid;
}

package com.qi.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;
    //一个老师多个学生
    private List<Student> students;
}

 按照结果嵌套处理

 <select id="getTeacher" resultMap="TeacherStudent">
        select s.id sid,s.name sanme,t.name tname,t.id tid
        from student s,teacher t
        where s.tid = t.id and t.id = #{tid};
    </select>

    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

按照查询嵌套处理

<select id="getTeacher2" resultMap="TeacherStudent2">
        select * from mybatis.teacher where id = #{tid};
    </select>
    <resultMap id="TeacherStudent2" type="Teacher">
        <result property="id" column="id"/>
        <collection property="students"  javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
    </resultMap>

    <select id="getStudentByTeacherId" resultType="Student">
        select * from student where tid =#{tid}
    </select>

 

 

 动态SQL

什么动态SQL,不同的需求不同的sql

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

 搭建环境

CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(100) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8

创建一个基础工程

package com.qi.entity;

import lombok.Data;

import java.util.Date;

@Data
public class Blog {
    private int id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

 IF

 <select id="queryBlogIF" parameterType="Blog" resultType="blog">
        select * from mybatis.blog where 1=1
        <if test="title != null">
            and title =#{title}
        </if>
        <if test="author != NULL">
            and author = #{author}
        </if>
    </select>

choose (when, otherwise)

trim (where, set)

 <select id="queryBlogIF" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <where>
            <if test="title != null">
                and title =#{title}
            </if>
            <if test="author != NULL">
                and author = #{author}
            </if>
        </where>

    </select>

    <update id="updateBlog" parameterType="map">
        update mybatis.blog
        <set>
            <if test="title != null">
                title = #{title},
            </if>
            <if test="author != null">
                author = #{author}
            </if>
        </set>
        where id =#{id}
    </update>

动态sql本质sql ,只是在SQL层面上去执行一个逻辑代码

sql片段

有时候我们会将一些SQL片段提取出来

1将固定的用sql抽取出来

2使用的地方用include调用


    <sql id="if-title-author">
        <if test="title != null">
            and title =#{title}
        </if>
        <if test="author != NULL">
            and author = #{author}
        </if>
    </sql>
<include refid="if-title-author"></include>

Foreach

  <select id="queryBlogForeach" parameterType="map" resultType="blog">

        select * from mybatis.blog
        <where>
            <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                id =#{id}
            </foreach>
        </where>

    </select>

缓存

1查询        链接数据库        耗资源

                一次查询的结果暂存在一个可以直接查询到的地方------》内存 :缓存

再次查询出来直接走缓存,不用走数据库

 

 

 

 

 

 1.开启全局缓存

 <setting name="cacheEnabled" value="true"/>

2在要使用二级缓存Mapper中开启

 <cache eviction="FIFO"
           flushInterval="60000"
           size="512"
           readOnly="true"/>

 

 

 自定义缓存-ehcache

 要在程序中使用

1导包

   <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.1.0</version>
        </dependency>

定义

   <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

 ehcache。xml的创建

 xml文件内容

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!-- 磁盘保存路径 -->
    <diskStore path="C:\Users\V556U\Desktop\springboot"/>

    <defaultCache
            maxElementsInMemory="1"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

        <!--
        属性说明:
        l diskStore:当内存中不够存储时,存储到指定数据在磁盘中的存储位置。
        l defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略

        以下属性是必须的:
        l maxElementsInMemory - 在内存中缓存的element的最大数目
        l maxElementsOnDisk - 在磁盘上缓存的element的最大数目,若是0表示无穷大
        l eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
        l overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上

        以下属性是可选的:
        l timeToIdleSeconds - 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
        l timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
         diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
        l diskPersistent - 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
        l diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
        l memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
        -->

mybatis流程图

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值