当前位置:   article > 正文

2.7 SpringBoot整合Mybatis_springboot mybatis 版本

springboot mybatis 版本


1.Mybatis 缓存机制

1.1 缓存概念

如果有大量相同的请求查询数据库,则数据库需要执行多次重复的sql,那么并发压力高,查询效率低. 如果引入缓存机制,则可以极大的提升用户的查询的效率。请添加图片描述

缓存介于服务器和数据库之间,其为了减轻数据库查询压力,提供服务器更高效的反馈速度出现。

1.2 Mybatis 提供缓存机制

  1. Mybatis中共俩级缓存
  2. 一级缓存 SqlSession 在同一个sqlSession内部 执行多次查询 缓存有效. 一级缓存默认开启状态.
  3. 二级缓存 SqlSessionFactory级别. 利用同一个工厂,创建的不同的SqlSession 可以实现数据的共享(缓存机制). 二级缓存
    默认也是开启的.
    请添加图片描述

1.3 一级缓存测试

    @Test
    public void testCache(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        EmpMapper userMapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> userList1 = userMapper.findAll();
        List<Emp> userList2 = userMapper.findAll();
        List<Emp> userList3 = userMapper.findAll();
        sqlSession.close();
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

我们利用同一个SqlSession,执行多次数据库操作后,可以在控制台输出观察看,虽然执行了3次方法,但是sql只执行一次此时缓存就是生效的。要注意的时,使用缓存时,数据模型类要实现序列号接口。

1.4 二级缓存测试

1.4.1 指定使用二级缓存

语法: 在各自的xml 映射文件中 指定缓存标签.在这里插入图片描述

1.4.2 二级缓存测试

注意事项: sqlSession关闭之后,二级缓存才能生效

  //测试二级缓存
    @Test
    public void testCache2(){
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        EmpMapper empMapper = sqlSession1.getMapper(EmpMapper.class);
        List<Emp> list1 = empMapper.findAll();
        sqlSession1.close(); //sqlSession使用之后必须关闭.否则二级缓存不生效.
        //利用同一个SqlSessionFactory 创建不同的SqlSession
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        EmpMapper empMapper2 = sqlSession2.getMapper(EmpMapper.class);
        List<Emp> list2 = empMapper2.findAll();
        sqlSession2.close();
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

1.4.3 注意事项

如果需要使用一级/二级缓存,则POJO对象必须实现序列化接口. 否则数据不可以被缓存.请添加图片描述
图解序列化规则:
请添加图片描述

在俩次查询中,相当于调用了俩次线程,线程A查询到的JAVA对象,线程B并不认识,这时就需要序列号排列字节信息,使线程B可以认识线程A查询到的JAVA对象,从而使线程B可以去使用。

2 SpringBoot整合Mybatis

2.1 创建项目

在这里插入图片描述

2.2 修改pom.xml文件

说明: 在新项目中添加依赖信息,可以直接赋值demo3中的pom内容

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--引入插件lombok 自动的set/get/构造方法插件  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--mybatis依赖包-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <!--jdbc依赖包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

    </dependencies>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2.3 目录结构

在这里插入图片描述

这里要注意的是,mybatis.mappers是层级目录的结构,不是其名字中包含一个.,而是代表层级目录的意思。

2.4 SpringBoot整合Mybatis

2.4.1 编辑application.yml

SpringBoot整合Mybatis中,不再使用之前的mybatis-config.xml文件,而是使用springboot.yml配置文件。

#配置端口号
server:
  port: 8090

#管理数据源
spring:
  datasource:
    #高版本驱动使用
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    #设定用户名和密码
    username: root
    password: root

#SpringBoot整合Mybatis
mybatis:
  #指定别名包
  type-aliases-package: com.study.pojo
  #扫描指定路径下的映射文件
  mapper-locations: classpath:/mybatis/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2.4.2 将Mapper接口交给容器管理

1. 通过@Mapper注解 管理对象

@Mapper //将Mapper接口交给Spring容器管理.
public interface UserMapper {

    List<User> findAll();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2. 通过包扫描的方式,管理mapper接口 编辑主启动类, 指定包扫描路径

@SpringBootApplication
//按照指定的包路径,扫描mapper的接口管理对象
@MapperScan("com.study.mapper")
public class SpringbootSsmApplication {

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3. 编辑数据模型类

@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.4.3 Mybatis 单元测试案例

1. 编辑测试类

@SpringBootTest
class SpringbootSsmApplicationTests {

    @Autowired  //注入指定的对象
    private UserMapper userMapper; //IDEA 编译提示 不影响执行

    /**
     * 测试SpringBoot整合Mybatis
     */
    @Test
    public void testFindAll(){
        List<User> userList = userMapper.findAll();
        System.out.println(userList);

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2. 编辑UserMapper.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是mybaits映射文件的唯一标识,与接口对应-->
<mapper namespace="com.study.mapper.UserMapper">

    <select id="findAll" resultType="User">
        select * from demo_user
    </select>



</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.5 关于Mapper接口对象的说明

请添加图片描述
解释:

  1. 将接口交给Spring容器管理,spring会根据class类型,动态的选择创建代理对象. 最终将代理对象交给spring容器管理.

请添加图片描述

  1. 代理对象的使用请添加图片描述

2.5.1 代理方式介绍

2.5.1.1 JDK动态代理

特点:

  1. 要求被代理者,必须有接口.
  2. 默认条件下如果有接口,则使用JDK动态代理
2.5.1.2 CGLIB动态代理

特点:
1.不管被代理者是否有接口,都可以为其创建代理对象.
2. 代理对象是目标对象的子类. 继承关系.

结论:
1.Spring中如果有接口,默认使用JDK代理方式,如果没有接口,则默认使用CGLIB代理方式.
2.Spring5以后,自身接口对象创建代理对象时,使用cglib

2.5.2 IDEA 自动注入Mapper异常说明

我们在mapper类中添加的@Mapper注解,就可以很好的解决这个报错;

但是当项目并没有在mapper类中添加@Mapper注解,而是在主启动类上添加包扫描路径时,因为包扫描只有在主启动类启动时才会生效,所以会导致在项目启动前报此警告错误,这时只需要按照下图设置即可取消:
在这里插入图片描述

2.6 SSM框架案例

2.6.1 业务需求

用户访问URL: http://localhost:8090/findAll
返回值: List 的JSON串.

2.6.2 框架关系图

请添加图片描述

用户访问时,首先会调用SpringMVC控制的Controller层代码,Controller层注入被Spring框架管理的Service层代码,Service层需要注入Mybatis管理的Mapper层代码,其统一被SpringBoot管理,共同构成SpringBoot框架。

2.6.3 层级代码实现

在这里插入图片描述

2.6.4 编辑UserController

@RestController  //@ResponseBody 将list集合转化为json
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * URL: http://localhost:8090/findAll
     * 参数: 无
     * 返回值: List<User>
     */
    @RequestMapping("/findAll")
    public List<User> findAll(){

        return userService.findAll();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.6.5 编辑UserServicelmpl

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserMapper userMapper;


    @Override
    public List<User> findAll() {

        return userMapper.findAll();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.6.6 编辑UserMapper

  1. mapper接口
public interface UserMapper {

    List<User> findAll();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  1. mapper映射文件
<mapper namespace="com.jt.mapper.UserMapper">

    <!--必须配置别名包-->
    <select id="findAll" resultType="User">
        select * from demo_user
    </select>
</mapper>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.6.7 页面效果展现

打开浏览器搜索http://localhost:8090/findAll
在这里插入图片描述

3 框架代码案例练习

3.1 根据ID查询数据

3.1.1 需求说明

根据Id查询数据库
URL: http://localhost:8090/findUserById?id=1
返回值: User对象

3.1.2 编辑UserController

 /**
     * 需求: http://localhost:8090/findUserById?id=1
     * 参数接收: id=1
     * 返回值: User对象
     */
    @RequestMapping("/findUserById")
    public User findUserById(Integer id){

        return userService.findUserById(id);
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.1.3 编辑UserService

 @Override
    public User findUserById(Integer id) {

        return userMapper.findUserById(id);
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.1.4 编辑UserMapper

    User findUserById(Integer id);

  • 1
  • 2

编辑UserMapper.xml文件:

    <select id="findUserById" resultType="User">
        select * from demo_user where id = #{id}
    </select>
  • 1
  • 2
  • 3

或者也可以使用注解的方式进行查询,但是要注意,注解和映射文件只能二选一,不能同时使用:

    @Select("select * from demo_user where id = #{id}")
    User findUserById(Integer id);
  • 1
  • 2

3.1.5 页面效果展现

在这里插入图片描述

3.2 根据age与sex查询数据

3.2.1 需求说明

根据age与sex查询数据库
URL: http://localhost:8090/findUserByAs?age=18&sex=女
返回值: List集合封装.

3.2.2 编辑UserController

    /*
     *URL:http://localhost:8090/findUserByAs?age=18&sex=女
     * 参数:age=18/sex=女
     * 返回值:List<集合>
     * 参数的接收:如果是多个参数,并且与属性名称一致,可以使用对象接收
     *
     */
    @RequestMapping("/findUserByAs")
    public List<User> findUserByAs(User user){
        return userService.findUserByAs(user);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.2.3 编辑UserService


    List<User> findUserByAs(User user);
  • 1
  • 2
    @Override
    public List<User> findUserByAs(User user){
        return userMapper.findUserByAs(user);
    }
  • 1
  • 2
  • 3
  • 4

3.2.4 编辑UserMapper

    @Select("select * from demo_user where age = #{age} and sex = #{sex}")
    List<User> findUserByAs(User user);
  • 1
  • 2

3.2.5 页面展示效果

在这里插入图片描述

3.3 Restful参数传递

3.3.1 业务需求

说明:要求修改id=1的数据,将name=“黑熊精” age=3000 sex=男,要求使用restFul的结构实现参数传递

常规get请求:http://localhost:8090/updateById?id=1&name=黑熊精&age=3000&sex=男

Restful请求路径:http://localhost:8090/updateById?1/黑熊精/3000/男

3.3.2 编辑UserController

    /*
     *URL:http://localhost:8090/updateById/1/黑熊精/3000/男
     * 参数:4个
     * 返回值:修改成功
     * restFul结构 参数分析 {属性名称}
     * 参数接收:
     *      1:单个参数使用@PathVariable Integer id接收
     *      2:多个参数接收 使用对象mvc自动提供的功能
     */
    @RequestMapping("/updateById/{id}/{name}/{age}/{sex}")
    public String updateById(User user){
        userService.updateById(user);
        return "用户修改成功";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3.3.3 编辑UserService

 //spring整合mybatis之后,事务自动提交.
    @Override
    public void updateById(User user) {

        userMapper.updateById(user);
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.3.4 编辑UserMapper

@Update("update demo_user set name=#{name},age=#{age},sex =#{sex} where id=#{id}")
    void updateById(User user);

  • 1
  • 2
  • 3

4.练习

  1. 模糊查询 查询name中包含 "乔"的用户.
    http://localhost:8090/findUserByLike?name=乔 返回list集合
  2. 批量查询 查询id=1,3,5,7的数据
    http://localhost:8090/findUserByIds?ids=1,3,5,7 返回list集合
  3. 实现用户新增
    http://localhost:8090/saveUser/悟空/8000/男 返回成功的提示即可

4.1 模糊查询

编辑UserController

    /*
     *URL:http://localhost:8090/findUserByLike?name=乔
     * 参数:乔
     * 返回值: 返回list集合
     * restFul结构 参数分析 {属性名称}
     */
    @RequestMapping("/findUserByLike")
    public List<User> findUserByLike(String name){
        return userService.findUserByLike(name);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

编辑UserService

    List<User> findUserByLike(String name);
  • 1
    @Override
    public List<User> findUserByLike(String name) {
        return userMapper.findUserByLile(name);
    }
  • 1
  • 2
  • 3
  • 4

编辑UserMapper

    @Select("select * from demo_user where name like \"%\"#{name}\"%\"")
    List<User> findUserByLile(String name);
  • 1
  • 2

4.2 批量查询

编辑UserController

    /*
    * 批量查询
    * http://localhost:8090/findUserByIds?ids=1,3,5,7
    * 返回list集合
    * 参数:ids=1,3,5,7
    * 返回值:List<User>
    * 知识点:MVC中参数,号分割的规则,应该使用数组接收mvc的规则
    * */
    @RequestMapping("/findUserByIds")
    public List<User> findUserByIds(Integer[] ids){
        return userService.findUserByIds(ids);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

编辑UserService

    List<User> findUserByIds(Integer[] ids);
  • 1
    @Override
    public List<User> findUserByIds(Integer[] ids) {
        return userMapper.findUserByIds(ids);
    }
  • 1
  • 2
  • 3
  • 4

编辑UserMapper

    List<User> findUserByIds(Integer[] ids);
  • 1

== 因为多个查询,所以查询语句需要写到UserMapper.xml中==

    <select id="findUserByIds" resultType="User">
        select * from demo_user where id in (
            <foreach collection="array" separator="," item="id">
                #{id}
            </foreach>
            )
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4.3 实现用户新增

编辑UserController

    /*
    *实现用户新增
    * http://localhost:8090/saveUser/悟空/8000/男
    * 返回成功的提示即可
    * 返回值:String
    * */
    @RequestMapping("/saveUser/{name}/{age}/{sex}")
    public String saveUser (User user){
        userService.saveUser(user);
        return "新增入库成功";
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

编辑UserService

void saveUser(User user);
  • 1
    @Override
    public void saveUser(User user) {
        userMapper.saveUser(user);
    }
  • 1
  • 2
  • 3
  • 4

编辑UserMapper

    @Insert("insert into demo_user (id,name,age,sex) values(null,#{name},#{age},#{sex} )")
    void saveUser(User user);
}

}
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/498244
推荐阅读
相关标签
  

闽ICP备14008679号