栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis入门到入坟 一站式基础及进阶——囊括面试点与初学基础、框架分析——从0到1 不会私我 我手把手教你

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis入门到入坟 一站式基础及进阶——囊括面试点与初学基础、框架分析——从0到1 不会私我 我手把手教你

本篇内容:Mybatis入门到入坟一站式基础——囊括面试点与初学基础、框架分析

 最近更新:2022年1月11日 MySQL的最全常用SQL语句 —— 一文可以快速熟悉、回忆sql语句

个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)

 点赞  收藏 ⭐留言  一键三连 关爱程序猿,从你我做起

本文目录

Mybatis入门到入坟一站式基础

写在前面1、什么是Mybatis

Mybatis介绍ORM是什么?Mybatis的优缺点Hibernate 和 MyBatis 的区别 2、快速入门使用Mybatis

步骤1:搭建Mybatis的环境步骤2:快速创建一个数据库并且包含一张表作为测试步骤3:创建配置文件 mybatis-config.xml进行配置步骤4:创建一个MybatisUtils工具类 获取SqlSession步骤5:创建实体类与接口类步骤6:测试 3、Mybatis实现CRUD操作——以及简单操作

步骤1:需要合理设计好对应了映射类,属性命名最好=列名步骤2:在Mapper接口中,定义对应的方法,增删改的返回值为int(代表的是操作修改的行),而查询则对应返回类型即可。步骤3:当在Mapper接口中,创建好方法后,就要去Mapper的配置文件当中设置对应方法的SQL语句了。步骤4:连接数据库进行测试CRUD中的注意事项:CRUD中多个参数数据的处理不同线程下的处理优化SqlSession工具类进阶自增主键的操作log4j显示sql的执行语句 4、Mybatis 进阶 复杂查询操作

1、Mybatis中 如何使用in查询2、Mybatis中 如何使用模糊查询3、Mybatis中 如何进行区间查询 5、Mybatis 进阶 多表之间复杂操作 以及 进阶使用

1、处理单个表中的关系2、处理多个表之间的关系3、数据库中的分页查询

1、Mybatis自带的接口方法2、通过插件来实现分页操作 4、Mybatis 缓存使用 6、Mybatis的配置文件以及配置优化

1、环境配置 environments2、属性配置properties3、类型别名配置 typeAliases4、设置配置 setting5、映射器 Mapper 7、Mybatis工作原理及其进阶

Mybatis的编程流程 8、Mybatis中日志进阶使用

1、 日志工厂

1、标准控制台输出 STDOUT_LOGGING2、LOG4J输出日志 9、基于注解开发写在最后

Mybatis入门到入坟一站式基础 写在前面

哇咔咔,小付又来了哦~今天给大家整理的是关于SSM中Mybatis框架的入门到入坟的基础夯实学习资料, 这次是小付二刷的经历过往,耗时也不算太多,更加坚固了基础知识的掌握的同时,也深刻理解了,Mybatis部分底层源码实现的工作流程,感谢各位支持,但我希望这篇文章能带给你们更多的是知识的查缺补漏,以及对框架的熟练掌握,加油xdm,冲冲冲~!

1、什么是Mybatis Mybatis介绍

Mybatis介绍

Mybatis是一款优秀的持久化框架:

它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。 ORM是什么?

orm是什么?

ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。

Mybatis的优缺点

优点:

基于SQL语句进行编程,较为灵活,可以定制化SQL语句。因为SQL写在了xml文件当中,解除了数据持久化与代码程序的耦合性,便于管理相较于JDBC降低了代码冗余的同时,也不用手动关闭连接,从而浪费资源提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护能够与Spring很好的集成,都属于非侵入式框架。

缺点:

SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求,你会体验到写高中作文的感受。SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。 Hibernate 和 MyBatis 的区别

共同点:

都对JDBC进行了封装,同时都是持久化层开发的框架,都用于DAO层的开发。

不同点:

映射关系

MyBatis 是一个半自动映射的框架,配置Java对象与sql语句执行结果的对应关系,多表关联关系配置简单Hibernate 是一个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂 开发难易程度以及使用场景

Hibernate是重量级框架,学习起来较为困难,适合于需求相对稳定的中小型项目,办公等小型系统。Mybatis是轻量级的框架,学习起来较为轻松,适合于需求变化频繁,大型项目,例如电子商务系统。 2、快速入门使用Mybatis 步骤1:搭建Mybatis的环境

步骤1:搭建Mybatis的环境

添加驱动包(mybatis.jar与mysql.jar)

    
        
            org.mybatis
            mybatis
            3.5.7
        
        
        
            mysql
            mysql-connector-java
            8.0.26
        
    
步骤2:快速创建一个数据库并且包含一张表作为测试

步骤2:快速创建一个数据库并且包含一张表作为测试

CREATE DATAbase `mybatis`;

USE `mybatis`;

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

INSERT INTO user(`id`,`username`,`password`) VALUES(101,'Alascanfu','123456'),
(102,'root','root'),
(103,'admin','admin');

步骤3:创建配置文件 mybatis-config.xml进行配置

步骤3:创建配置文件 mybatis-config.xml进行配置

配置文件需要配置:

指定数据库的相关信息(url,username,password,driver)框架可以根据配置文件自动获取连接指定事务管理对象

mybatis-config.xml







    
        
            
            
                
                
                
                
            
        
        
        
            
            
                
                
                
                
            
        
    

    
        
    


步骤4:创建一个MybatisUtils工具类 获取SqlSession

步骤4:创建一个MybatisUtils工具类 获取SqlSession

public class MybatisUtils {
    private static InputStream inputStream;
    private static SqlSessionFactory sqlSessionFactory;
    //利用静态代码块直接在初始化时加载
    static {
        try {
            String resource = "mybatis-config.xml";
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
    
    
    public static void closeSqlSession(){
        try {
            inputStream.close();
            getSqlSession().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

步骤5:创建实体类与接口类

步骤5:创建实体类与接口类

User.java

public class User {
    private int id ;
    private String username;
    private String password;
    
    public User() {
    }
    
    public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
    
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    @Override
    public String toString() {
        return "User{" +
            "id=" + id +
            ", username='" + username + ''' +
            ", password='" + password + ''' +
            '}';
    }
}

接口UserMapper.java

public interface UserMapper {
    List getUserList();
}

编写一个Mapper配置文件,来代替了之前JDBC中的UserDaoImpl的接口实现类

UserMapper.xml





    
        select * from user
    

步骤6:测试

步骤6:测试

UserMapperTest.java

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

        List userList =
            mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
        
        sqlSession.close();
    }
}

运行结果:

User{id=101, username='Alascanfu', password='123456'}
User{id=102, username='root', password='root'}
User{id=103, username='admin', password='admin'}

Process finished with exit code 0

如果测试类进行测试的时候可能会报错

要先进行配置好maven的过滤环境

否则在测试的时候就会找不到咱们设置好的xml文件



    
        mybatis-01-test
        com.alascanfu
        1.0-SNAPSHOT
    
    4.0.0

    spring-02-HelloMybatis
    
        
            junit
            junit
            4.12
            test
        
    

    
    
        
            
                src/main/resources
                
                    ***.xml
                
                true
            
            
                src/main/java
                
                    ***.xml
                
                true
            
        
    


3、Mybatis实现CRUD操作——以及简单操作 步骤1:需要合理设计好对应了映射类,属性命名最好=列名

步骤1:需要合理设计好对应了映射类,属性命名最好=列名

步骤2:在Mapper接口中,定义对应的方法,增删改的返回值为int(代表的是操作修改的行),而查询则对应返回类型即可。

步骤2:在Mapper接口中,定义对应的方法,增删改的返回值为int(代表的是操作修改的行),而查询则对应返回类型即可。

public interface UserMapper {
    //获取表中的所有User
    List getUserList();
    //插入一个用户
    int insertUser(User user);
    //根据id来删除一个用户
    int deleteUserById(int id);
    //根据id来修改用户
    int updateUserById(User user);
    //查询对应id的用户信息
    User queryUserById(int id);
}
步骤3:当在Mapper接口中,创建好方法后,就要去Mapper的配置文件当中设置对应方法的SQL语句了。

步骤3:当在Mapper接口中,创建好方法后,就要去Mapper的配置文件当中设置对应方法的SQL语句了。

其中mapper中对应的标签名称 也就是翻译过来的 SQL映射语句

insert 插入

delete 删除

update 更新

select 查询

标签内的属性:

parameterType:参数的类型resultType:返回值类型






    
        insert into user (id,username,password) values(#{id},#{username},#{password})
    

    
        delete from USER where id = #{id}
    
    
    
    
        update user set username = #{username},password=#{password} where id = #{id}
    


    
        select * from user where id = #{id}
    


注意内容:

#{属性值(参数名称)}

步骤4:连接数据库进行测试

步骤4:连接数据库进行测试

public class Test {
    //用于测试查询所有的用户信息
    @org.junit.Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List userList =
            mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }
    //用于测试插入一个用户
    @org.junit.Test
    public void testInsert(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.insertUser(new User(104,"DBA","DBA"));
        List userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }
    //用于测试删除一个用户
    @org.junit.Test
    public void testDeleteById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.deleteUserById(102);
        List userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }
    //用于测试更新用户信息
    @org.junit.Test
    public void testUpdateById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int row = mapper.updateUserById(new User(103, "root", "123456"));
        List userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
    }
    //用于测试根据id查询用户信息
    @org.junit.Test
    public void testQueryById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryUserById(101);
        System.out.println(user);
    
    }
}

CRUD中的注意事项:

增删改的时候需要提交事务

 session.commit(); 
 session.rollback();    

查询的时候要添加resultType属性

CRUD中多个参数数据的处理

将多个参数封装到map集合当中,再将map集合传递给mapper文件。

获取map中对应的值

#{map的key值}

在Mapper接口中定义方法:

当需要传入多个参数的时候,使用map集合来进行传参

    int insertUsers(Map map);

Mapper配置文件中设置参数为map类型

    
        insert into user (id,username,password) values (#{uId},#{uUsername},#{uPassword});
    

Test.java

@org.junit.Test
    public void testInsertUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map map = new HashMap();
    //重点在下面这三行
        map.put("uId",105);
        map.put("uUsername","DBA");
        map.put("uPassword","123456");
        mapper.insertUsers(map);
        User user = mapper.queryUserById(105);
        System.out.println(user);
    }
不同线程下的处理优化SqlSession工具类进阶

ThreadLocal是什么?

我认为的ThreadLocal自如其名,就是代表的线程的局部变量,就好比一个线程正在运行当中,ThreadLocal的变量只可以被其自身线程调用、访问,别的线程均无法访问,是避免线程竞争的好东西,他不是解决冲突,而是从根本上避免了冲突的发生。使得线程之间独立运行,并发下安全问题的好帮手。

ThreadLocal的功能

为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。

代码测试理解

public class ThreadLocalTest {
    
    public static void main(String[] args) {
        final ThreadLocal threadLocal = new ThreadLocal();
        final List list = new ArrayList();
        new Thread(new Runnable() {
            public void run() {
                System.out.println("A线程开始存入值");
                threadLocal.set("A线程存入的threadLocal变量内容");
                list.add("A线程存入的list内容");
                System.out.println("A====>获取线程的局部变量内容"+ threadLocal.get());
                System.out.println("A====>获取线程的list变量内容"+ list.get(0));
            }
        }).start();
    
        new Thread(new Runnable() {
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("B线程开始取出A线程存入的值");
                System.out.println("B====>获取线程A的局部变量内容"+ threadLocal.get());
                System.out.println("B====>获取线程A存入的list变量内容"+ list.get(0));
            }
        }).start();
    }
}

执行结果:

A线程开始存入值
A====>获取线程的局部变量内容A线程存入的threadLocal变量内容
A====>获取线程的list变量内容A线程存入的list内容
B线程开始取出A线程存入的值
B====>获取线程A的局部变量内容null
B====>获取线程A存入的list变量内容A线程存入的list内容

Process finished with exit code 0

你会发现B线程无法获取A线程设置的局部变量,而可以获得ArrayList中的变量,从侧面也就说明了ArrayList的线程不安全问题。

使用ThreadLocal优化SqlSession

**原理:**在之前已经提到过了SqlSession会在每次用户请求信息时,都会生成一个SqlSession对象实例,在处理数据的过程中也可能会出现多线程的问题。

ThreadLocal的set方法会使用一个map,将当前线程信息作为key,要set的值作为value存储

set()方法的源码:

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

SqlSessionUtils工具类优化


public class SqlSessionUtils {
    private static ThreadLocal threadLocal = new ThreadLocal();
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = threadLocal.get();
        if (sqlSession == null){
            sqlSession = sqlSessionFactory.openSession();
            threadLocal.set(sqlSession);
        }
        return sqlSession;
    }
    
    
    public static void closeSqlSession(){
        SqlSession sqlSession = threadLocal.get();
        if (sqlSession != null){
            sqlSession.close();
            threadLocal.remove();
        }
    }
}
自增主键的操作

用于设置了自增主键的属性上

方便设置




测试用例


        insert into user(username,password) values (#{username},#{password});
    

Test.java

@org.junit.Test
    public void testInsertUserByIncrese(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user1 = new User();
        user1.setUsername("HHXF");
        user1.setPassword("123");
        int i = mapper.insertUserByIncrease(user1);
        System.out.println(mapper.queryUserById(104));
    }
log4j显示sql的执行语句

首先先导入log4j的jar包

		
            org.slf4j
            slf4j-api
            1.7.5
        
        
            org.slf4j
            slf4j-log4j12
            1.7.12
        
        
            log4j
            log4j
            1.2.17
        

然后resources文件夹下创建log4j.properties进行配置数据库的日志

log4j.rootLogger=DEBUG, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n

log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

最后去测试 测试结果

2022-01-10 20:30:42,991 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.insertUsers] - ==>  Preparing: insert into user (id,username,password) values (?,?,?);
2022-01-10 20:30:43,017 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.insertUsers] - ==> Parameters: 105(Integer), DBA(String), 123456(String)
2022-01-10 20:30:43,019 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.insertUsers] - <==    Updates: 1
2022-01-10 20:30:43,020 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.queryUserById] - ==>  Preparing: select * from user where id = ?
2022-01-10 20:30:43,020 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.queryUserById] - ==> Parameters: 105(Integer)
2022-01-10 20:30:43,043 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.queryUserById] - <==      Total: 1
User{id=105, username='DBA', password='123456'}
4、Mybatis 进阶 复杂查询操作 1、Mybatis中 如何使用in查询

Mybatis中 如何使用in查询

这里先用MySQL中来演示在SQL服务器中是如何使用in来进行查询的

in 一般用于 where 的表达式当中,其作用是用来查询某个范围之内的数据

示例:

mysql> show tables;
+-------------------+
| Tables_in_mybatis |
+-------------------+
| department        |
| employee          |
| employeeec        |
| employeeremove    |
| employeetrain     |
| empsalary         |
| hr                |
| hr_role           |
| mail_send_log     |
| user              |
+-------------------+
10 rows in set (0.01 sec)

mysql> desc user;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int         | NO   | PRI | NULL    | auto_increment |
| username | varchar(30) | YES  |     | NULL    |                |
| password | varchar(30) | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.04 sec)

mysql> select * from user;
+-----+-----------+----------+
| id  | username  | password |
+-----+-----------+----------+
| 101 | Alascanfu | 123456   |
| 102 | root      | root     |
| 103 | admin     | admin    |
| 108 | HHXF      | 123      |
+-----+-----------+----------+
4 rows in set (0.04 sec)

mysql> select * from user where id in (101,108);
+-----+-----------+----------+
| id  | username  | password |
+-----+-----------+----------+
| 101 | Alascanfu | 123456   |
| 108 | HHXF      | 123      |
+-----+-----------+----------+
2 rows in set (0.00 sec)

not in 与之相反

需要注意的是:在in之后依然可以跟函数哦~

咱们言归正传——来说说如何在Java中的配置文件中使用呢?

首先啊,你们需要知道 in 后面跟着的是 foreach 这个标签而foreach标签中的属性说明:

item 表示迭代过程中的每个元素的别名index 指定的是一个名字,用于表示在迭代过程中,迭代的位置open表示该语句 以什么开始separator 表示在每次进行迭代之间以什么符号作为分隔符close 表示以什么符号结束

步骤1:在Mapper接口中创建对应的查询方法

public interface UserMapper {
    
    List findInList(List list);
    
    List findInArray(int[] arr);
    
    List findInMap(Map map);
}

步骤2:在Mapper的配置文件中书写复杂查询的SQL语句





    
        select * from user where id in
        
            #{uid}
        
    
    
        select * from user where id in
        
            #{uid}
        
    


步骤3:单元测试 是否满足条件

	@org.junit.Test
    public void testInList(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        ArrayList list = new ArrayList();
        list.add(101);
        list.add(108);
        for (Integer i : list) {
            System.out.println(i);
        }
        List userList = mapper.findInList(list);
        for (User user : userList) {
            System.out.println(user);
        }
    }
	@org.junit.Test
    public void testInArr(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int [] arr = new int[2];
        arr[0] = 101;
        arr[1] = 108;
    
        List userList = mapper.findInArray(arr);
        for (User user : userList) {
            System.out.println(user);
        }
    }
	@org.junit.Test
    public void testInMap(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map map = new HashMap();
        List list = new ArrayList();
        list.add(101);
        list.add(108);
        map.put("keyVal",list);
        List userList = mapper.findInMap(map);
        for (User user : userList) {
            System.out.println(user);
        }
    }

执行结果:

101
108
2022-01-11 17:38:23,010 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findInList] - ==>  Preparing: select * from user where id in ( ? , ? )
2022-01-11 17:38:23,079 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findInList] - ==> Parameters: 101(Integer), 108(Integer)
2022-01-11 17:38:23,112 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findInList] - <==      Total: 2
User{id=101, username='Alascanfu', password='123456'}
User{id=108, username='HHXF', password='123'}

Process finished with exit code 0

和预期结果一致QwQ

但是需要注意的点在于你传入Map 作为参数的时候 collection 传入的是key值 也就是说明你需要先创建一个集合添加到map当中然后并给这个map赋予key,然后通过collection调用的时候就只能用key来获取。

2、Mybatis中 如何使用模糊查询

使用模糊查询 首先要防止SQL注入问题咱们就需要用到动态的SQL语句


	and username like "%"#{username}"%"

测试用例:

步骤1:我们需要现在Mapper接口中定义相关的模糊查询方法

public interface UserMapper {
    List findLike(Map map);
}

步骤2:然后我们需要在对应的Mapper的配置文件进行书写SQL语句

    
        select * from USER where 1=1
        
            and username like "%"#{username}"%"
        
    

这一段代码是为了防止SQL注入导致的恶意查询

步骤3:进行测试

public void testLike(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map map = new HashMap();
        map.put("username","a");
        List userList = mapper.findLike(map);
        for (User user : userList) {
            System.out.println(user);
        }
    }

测试结果:

2022-01-11 18:28:44,935 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findLike] - ==>  Preparing: select * from USER where 1=1 and username like "%"?"%"
2022-01-11 18:28:44,974 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findLike] - ==> Parameters: a(String)
2022-01-11 18:28:45,005 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findLike] - <==      Total: 2
User{id=101, username='Alascanfu', password='123456'}
User{id=103, username='admin', password='admin'}

Process finished with exit code 0

答案如预期的一致~

注意点:

传递的参数如果是map类型的话,则test属性中写的就是key。

同时

#{} 相当于占位符

${} 表示拼接 可能会引起SQL注入问题

test属性中读取属性值时直接写属性名

模糊查询读取属性时使el 表达式, 标签调用的时候

${属性名}

除以上位置外,都使用#{属性名}

3、Mybatis中 如何进行区间查询

步骤1:在Mapper接口中书写对应的接口方法

List findArea(Map map);

步骤2: 在Mapper配置文件中书写SQL语句

	
        select * from user where 1=1 and id
        
            between #{startId} and #{endId}
        
    

步骤3:测试

@org.junit.Test
    public void testBetween(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map map = new HashMap();
        map.put("startId",102);
        map.put("endId",105);
        List userList = mapper.findArea(map);
        for (User user : userList) {
            System.out.println(user);
        }
    }

执行结果

2022-01-11 18:46:53,056 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findArea] - ==>  Preparing: select * from user where 1=1 and id between ? and ?
2022-01-11 18:46:53,102 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findArea] - ==> Parameters: 102(Integer), 105(Integer)
2022-01-11 18:46:53,130 [main] DEBUG [com.alascanfu.pojo.mapper.UserMapper.findArea] - <==      Total: 2
User{id=102, username='root', password='root'}
User{id=103, username='admin', password='admin'}
5、Mybatis 进阶 多表之间复杂操作 以及 进阶使用 1、处理单个表中的关系

可以通过过resultMap 处理表的关系

为数据库表中的列起别名 = 属性名 同样可以映射数据

步骤1:在Mapper的配置文件中创建一个resultMap的映射关系

    
        
        
        
    

注意:这里的properties对应的数据是你type中的属性值

而column对应的是数据库中的列头属性

步骤2:在对应的方法中添加返回resultMap类型

	
        select * from user where 1=1 and id
        
            between #{startId} and #{endId}
        
    
2、处理多个表之间的关系

两表联合查询:一对一和多对一

注意事项:

单表查询 selet中使用resultType 设置返回的类型即可。但是如果在多表查询,返回的就需要使用自定义的resultMap来对查询结果进行映射。

一表对多表查询

步骤1:初始化数据库表

create table `role`(
    `id` int not null primary key ,
    `name` varchar(32) default null,
    `nameZh` varchar(256) default null
)engine = innodb default charset = utf8;

create table `user`(
                       `id` int not null primary key ,
                       `username` varchar(32) default null
)engine = innodb default charset = utf8;

create table `user_role`(
                       `id` int not null primary key ,
                       `uid` int default null ,
                       `rid` int default null
)engine = innodb default charset = utf8;

步骤2:向表中插入数据

mysql> select * from user;
+----+-----------+
| id | username  |
+----+-----------+
|  1 | Alascanfu |
|  2 | HHXF      |
+----+-----------+
2 rows in set (0.00 sec)

mysql> select * from role;
+----+-------+--------------------+
| id | name  | nameZh             |
+----+-------+--------------------+
|  1 | admin | 系统管理员         |
|  2 | DBA   | 数据库管理员       |
|  3 | user  | 普通用户           |
+----+-------+--------------------+
3 rows in set (0.00 sec)

mysql> select * from user_role;
+----+-----+-----+
| id | uid | rid |
+----+-----+-----+
|  1 |   1 |   3 |
|  2 |   1 |   1 |
|  3 |   2 |   1 |
|  4 |   2 |   2 |
+----+-----+-----+
4 rows in set (0.00 sec)

初始化类与Mapper接口以及Mapper的配置文件 进行一对多连表查询

Role.java

public class Role {
    private int id ;
    private String name;
    private String nameZh;
    
    public Role() {
    }
    
    public Role(int id, String name, String nameZh) {
        this.id = id;
        this.name = name;
        this.nameZh = nameZh;
    }
    
    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 getNameZh() {
        return nameZh;
    }
    
    public void setNameZh(String nameZh) {
        this.nameZh = nameZh;
    }
    
    @Override
    public String toString() {
        return "Role{" +
            "id=" + id +
            ", name='" + name + ''' +
            ", nameZh='" + nameZh + ''' +
            '}';
    }
}

User.java

public class User1 {
    private int id ;
    private String username;
    private List roleList;
    
    public User1() {
    }
    
    public User1(int id, String username, List roleList) {
        this.id = id;
        this.username = username;
        this.roleList = roleList;
    }
    
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public List getRoleList() {
        return roleList;
    }
    
    public void setRoleList(List roleList) {
        this.roleList = roleList;
    }
    
    @Override
    public String toString() {
        return "User{" +
            "id=" + id +
            ", username='" + username + ''' +
            ", roleList=" + roleList +
            '}';
    }
}

UserMapper.java

public interface UserMapper1 {
    List getUserById(int id);
}

UserMapper.xml




    
        
        
        
            
            
            
        
    

    
        select u.id ,u.username,r.name ,r.nameZh from user u,role r,user_role ur where u.id = #{id} and  ur.uid = u.id and ur.rid = r.id
    

Test.java

@org.junit.Test
    public void test(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper1 mapper = sqlSession.getMapper(UserMapper1.class);
        List userList = mapper.getUserById(1);
        for (User1 user1 : userList) {
            System.out.println(user1);
        }
    }

执行结果

User{id=1, username='Alascanfu', roleList=[Role{id=1, name='user', nameZh='普通用户'}, Role{id=1, name='admin', nameZh='系统管理员'}]}

Process finished with exit code 0

上述案例也可以转化为多对多进行多个表关系查询

3、数据库中的分页查询 1、Mybatis自带的接口方法

Mybatis插件接口RowBounds实现对象数据分页

实现步骤:

selectList这个函数的参数为Mapper接口中的方法,第二个是方法中的参数,第三个是偏移量

	@Test
    public void test1(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        List userList = sqlSession.selectList("com.alascanfu.pojo.mapper.UserMapper.getUserList", null, new RowBounds(0, 1));
        for (User user : userList) {
            System.out.println(user);
        }
    }

配置文件