项目管理与SSM框架 MyBatis(五)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 项目管理与SSM框架 MyBatis(五)

十、MyBatis注解开发

  1. 创建maven工程,引入依赖
  2. 创建mybatis核心配置文件SqlMapConfig.xml
  3. 将log4j.properties文件放入resources中,让控制台打印SQL语句。
  4. 创建实体类
  5. 创建持久层接口,并在接口方法上定义Sql语句
public interface UserMapper {
  @Select("select * from user")
  List<User> findAll();
}

由于注解在方法上方,而方法中就有参数类型和返回值类型,所以使用注解开发不需要定义参数类型和返回值类型

6、在核心配置文件注册持久层接口,由于没有映射文件,所以只能采用注册接口或注册包的方法。

<!--基于注解开发的话,没有映射文件就注册接口-->
    <mappers>
       <package name="com.zj.mapper"/>
    </mappers>

7、测试方法

@Test
    public void testFindAllUsers(){
        List<User> allUsers = userMapper.findAllUsers();
        for (User allUser : allUsers) {
            System.out.println(allUser);
        }
    }

10.1 基于注解实现增删改查

@Select("select * from user")
    List<User> findAllUsers();
    @SelectKey(keyColumn = "id",keyProperty = "id",resultType = int.class,before = false,
              statement = "select LAST_INSERT_ID()")
    @Insert("insert into user values (default, #{username}, #{sex},#{address})")
    void addUser(User user);
    @Delete("delete from user where id = #{id}")
    void removeUser(int id);
    @Update("update user set username = #{username}, sex = #{sex}, address = #{address}" +
            "where id = #{id}")
    void updateUser(User user);
    @Select("select * from user where username like #{username}")
    List<User> findUserLike(String username);

10.2 动态sql

MyBatis注解开发中有两种方式构建动态Sql:

使用脚本标签(了解即可千万别用,又臭又长)

将Sql嵌套在<script>内即可使用动态Sql标签:

// 根据任意条件查询
@Select("<script>" +
    "  select * from user\n" +
    "     <where>\n" +
    "       <if test=\"username != null and username.length() != 0\">\n" +
    "         username like #{username}\n" +
    "       </if>\n" +
    "       <if test=\"sex != null and sex.length() != 0\">\n" +
    "         and sex = #{sex}\n" +
    "       </if>\n" +
    "       <if test=\"address != null and address.length() != 0\">\n" +
    "         and address = #{address}\n" +
    "       </if>\n" +
    "     </where>" +
    "</script>")
List<User> findByCondition(User user);

在方法中构建动态Sql

在MyBatis中有@SelectProvider@UpdateProvider@DeleteProvider@InsertProvider注解。当使用这些注解时将不在注解中直接编写SQL,而是调用某个类的方法来生成SQL。

1、创建类构建sql语句

package com.zj.provider;
import com.zj.pojo.User;
/*构建sql*/
public class UserProvider {
        //生成根据任意条件查询的sql语句
    public String findByConditionSql(User user){
        StringBuffer sb = new StringBuffer("SELECT * FROM  user WHERE 1=1");
        if (user.getUsername() != null && user.getUsername().length() > 0){
            sb.append(" and username = #{username}");
        }
        if (user.getSex() != null && user.getSex().length() > 0){
            sb.append(" and sex = #{sex}");
        }
        if (user.getAddress() != null && user.getAddress().length() > 0){
            sb.append(" and address = #{address}");
        }
        return sb.toString();
    }
}

2、持久层

/*根据任意给定条件查询用户,使用某个类构建sql*/
    @SelectProvider(type = UserProvider.class,method = "findByConditionSql")
    List<User> findByConditionSql(User user);

3、测试

@Test
    public void testFindByConditionSql(){
        User user = new User();
        user.setUsername("顾田然");
        List<User> users = userMapper.findByConditionSql(user);
        for (User user1 : users) {
            System.out.println(user1);
        }
    }

10.3 自定义映射

当POJO属性名与数据库列名不一致时,需要自定义实体类和结果集的映射关系,在MyBatis注解开发中,使用@Results定义并使用自定义映射,使用@ResultMap使用自定义映射,用法如下:

/*自定义映射*/
    @Results(id = "userMapper",value = {
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "username",column = "username"),
            @Result(property = "sex",column = "sex"),
            @Result(property = "address",column = "address")
    })
    @Select("select * from user")
    List<User> findAllUsers();

10.4 基于注解开启二级缓存

1、POJO类实现Serializable接口。

2、在持久层接口上方加注解@CacheNamespace(blocking=true),该接口的所有方法都支持二级缓存。

@CacheNamespace(blocking = true)
public interface UserMapper {
……
}

10.5 基于注解实现一对一关联查询

在MyBatis的注解开发中对于多表查询只支持分解查询(N+1),不支持连接查询。

1、创建实体类

public class Student {
  private int sid;
  private String name;
  private int age;
  private String sex;
  private Classes classes;
  // 省略getter/setter/toString
}
public class Classes {
  private int cid;
  private String className;
  private List<Student> students;
  // 省略getter/setter/toString
}

2、持久层

package com.zj.mapper;
import com.zj.pojo.Student;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface StudentMapper {
    //查询全部学生
    @Results(id = "StudentMapper" ,value = {
            @Result(id = true,property = "sid",column = "sid"),
            @Result(property = "name",column = "name"),
            @Result(property = "age",column = "age"),
            @Result(property = "sex",column = "sex"),
            //调用查询时传入的参数是哪列
            @Result(property = "classes",column = "classId",
                    one = @One(select = "com.zj.mapper.ClassesMapper.findClassById",
                    fetchType = FetchType.EAGER)
            )
    })
    @Select("select * from Student")
    List<Student> findAllStudent();
}
package com.zj.mapper;
import com.zj.pojo.Classes;
import org.apache.ibatis.annotations.Select;
public interface ClassesMapper {
    //根据班级cid查询班级信息
    @Select("select * from classes where cid = #{cid}")
    Classes findClassById(int cid);;
}

3、测试

@Test
    public void testStudentMapper() {
        List<Student> allStudent = studentMapper.findAllStudent();
        for (Student student : allStudent) {
            System.out.println(student);
        }
    }

10.6 基于注解实现一对多关联查询

查询班级信息的时候将该班级下的学生一起查出来。

1、持久层

//查询全部班级(一对多一般使用懒加载)
    @Results(id = "classesMap",value = {
            @Result(id = true,property = "cid",column = "cid"),
            @Result(property = "className",column = "className"),
            @Result(property = "studentList",column = "cid",
            many = @Many(select="com.zj.mapper.StudentMapper.findStudentByCid",
            fetchType = FetchType.LAZY))
    })
    @Select("select * from classes")
    List<Classes> findAllClasses();
    //根据班级id查询学生
    @Select("select * from student where classId = #{classId}")
    Student findStudentByCid(int classId);

2、测试

@Test
    public void testFindAllClasses(){
        List<Classes> allClasses = classesMapper.findAllClasses();
        for (Classes allClass : allClasses) {
            System.out.println(allClass);
        }
    }

10.7 注解和映射文件对比

MyBatis中更推荐使用映射文件开发,Spring、SpringBoot更推荐注解方式。具体使用要视项目情况而定。它们的优点对比如下:

映射文件:

  • 代码与Sql语句是解耦的,修改时只需修改配置文件,无需修改源码。
  • Sql语句集中,利于快速了解和维护项目。
  • 级联查询支持连接查询和分解查询两种方式,注解开发只支持分解查询。

注解:

  • 配置简单,开发效率高。
  • 类型安全,在编译期即可进行校验,不用等到运行时才发现错误。

十一、PageHelper分页插件

开发过程中如果要进行分页查询,需要传入页数和每页条数。返回页面数据,总条数,总页数,当前页面,每页条数等数据。此时使用PageHelper插件可以快速帮助我们获取这些数据。

PageHelper是一款非常好用的开源免费的Mybatis第三方分页插件。使用该插件时,只要传入分页参数,即可自动生成页面对象。我们使用该插件分页查询所有用户:

1、引入依赖

<!-- PageHelper -->
<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.3.0</version>
</dependency>

2、Mybatis配置文件中配置PageHelper插件

<plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 设置数据库类型-->
            <property name="helperDialect" value="mysql"/>
        </plugin>
    </plugins>

3、测试

@Test
    public void testFindAllUsers(){
        //1、设置分页参数
        Page<Object> objects = PageHelper.startPage(1, 3);
        //查询数据库
        List<User> allUsers = userMapper.findAllUsers();
        //封装查询结果生成页面对象
        PageInfo<User> pageInfo = new PageInfo(allUsers);
        //打印页面数据
        List<User> list = pageInfo.getList();
        System.out.println("结果集:"+list);
        System.out.println("总条数:"+pageInfo.getTotal());
        System.out.println("总页数:"+pageInfo.getPages());
        System.out.println("当前页:"+pageInfo.getPageNum());
        System.out.println("每页条数:"+pageInfo.getSize());
    }

十二、MyBatis Generator

MyBatis Generator(MBG)是MyBatis官方提供的代码生成器。它可以根据数据库的表结构自动生成POJO类、持久层接口与映射文件,极大减少了代码的编写量,提高开发效率。

MBG可以作为项目引入使用,也可以作为Maven插件使用,其中作为Maven插件使用更加方便快捷。

1、准备数据库表

2、在pom文件中配置MBG插件

<build>
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.2</version>
                <!--MBG配置-->
                <configuration>
                    <!--配置文件的位置-->
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <!--运行显示详情-->
                    <verbose>true</verbose>
                    <!--允许文件覆盖-->
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>

3、编写MBG配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!-- jdbc的jar包位置,插件需要连接数据库 -->
    <classPathEntry location="D:\Java\apache-maven-3.8.3\repositories\mysql\mysql-connector-java\8.0.26\mysql-connector-java-8.0.26.jar"/>
    <context id="default" targetRuntime="MyBatis3">
        <!-- 是否去除自动生成的注释-->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库连接参数-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis"
                        userId="root"
                        password="123456">
        </jdbcConnection>
        <!-- 类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- targetProject:POJO类路径  targetProject:生成的POJO类的包(需要提前创建包)-->
        <javaModelGenerator targetProject="src/main/java" targetPackage="com.zj.pojo">
            <!-- 是否生成子包 -->
            <property name="enableSubPackages" value="false"/>
            <!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- targetProject:配置文件路径  targetPackage:生成映射文件的位置(要提前创建文件目录) -->
        <sqlMapGenerator targetProject="src/main/resources" targetPackage="com.zj.mapper">
            <!-- 是否生成子包 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- targetPackage:JAVA类路径 targetProject:生成的持久层接口包 -->
        <javaClientGenerator targetProject="src/main/java" targetPackage="com.zj.mapper" type="XMLMAPPER">
            <!-- 是否生成子包 -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>
        <!-- 数据库表(根据哪些表生成,可以写多个table标签),表名不要和其他库中的表名一样 -->
        <table tableName="product"></table>
    </context>
</generatorConfiguration>

4、双击运行插件,自动生成POJO,持久层接口,映射文件:

 

 

  • Product.java:POJO类
  • ProductMapper.java:持久层接口
  • ProductMapper.xml:映射文件
  • ProductExample.java:查询扩展类,该类可以构造复杂的查询条件。
  • Criterion:代表一个字段。
  • GeneratedCriteria:抽象类,生成查询条件的工具。
  • Criteria:GeneratedCriteria的子类,生成查询条件的工具。

12.1 增删改方法

注意在生成插件后还要搭建mybatis,再添加上配置文件。

//添加
    @Test
   public void testAdd(){
       Product product = new Product(0,"英特尔(Intel) i7-13700K 13代 酷睿 处理器",2999.0);
       int insert = productMapper.insert(product);
       sqlSession.commit();
   }
   //修改
    @Test
    public void testUpdate(){
        Product product = new Product();
        product.setId(3);
        product.setProductname("小天才电话手表");
        product.setPrice(499.0);
        int i = productMapper.updateByPrimaryKey(product);
        sqlSession.commit();
    }
    //删除
    @Test
    public void testDelete(){
        int i = productMapper.deleteByPrimaryKey(2);
        sqlSession.commit();
    }

12.2 查询方法

//根据id查询
    @Test
    public void testFindById(){
        Product product = productMapper.selectByPrimaryKey(1);
        System.out.println(product);
    }
    //查询全部
    @Test
    public void testFindAll(){
        /*除了根据id查询之外其他的查询方法都需要使用查询扩展对象来构建查询条件*/
        ProductExample productExample = new ProductExample();
        /*查询全部不需要构建查询条件*/
        List<Product> products = productMapper.selectByExample(productExample);
        for (Product product : products) {
            System.out.println(product);
        }
    }
    //根据名称查询
    @Test
    public void testFindByName(){
        /*构建查询条件*/
        ProductExample productExample = new ProductExample();
        ProductExample.Criteria criteria = productExample.createCriteria();
        criteria.andProductnameLike("%华为Mate40%");
        /*查询*/
        List<Product> products = productMapper.selectByExample(productExample);
        for (Product product : products) {
            System.out.println(product);
        }
    }

12.3复杂查询

//多条件的and查询
    @Test
    public void testFindAnd(){
        /*构建查询条件*/
        ProductExample productExample = new ProductExample();
        ProductExample.Criteria criteria = productExample.createCriteria();
        criteria.andProductnameLike("%华为%");
        criteria.andPriceBetween(3000.0,10000.0);
        List<Product> products = productMapper.selectByExample(productExample);
        for (Product product : products) {
            System.out.println(product);
        }
    }
    //多条件的or查询
    @Test
    public void testFindOr(){
        /*构建查询条件1*/
        ProductExample productExample = new ProductExample();
        ProductExample.Criteria criteria1 = productExample.createCriteria();
        criteria1.andProductnameLike("%华为%");
        /*构建查询条件2*/
        ProductExample.Criteria criteria2 = productExample.createCriteria();
        criteria2.andPriceBetween(8000.0,10000.0);
        /*创建or关系(括号中只放第二个)*/
        productExample.or(criteria2);
        /*查询*/
        List<Product> products = productMapper.selectByExample(productExample);
        for (Product product : products) {
            System.out.println(product);
        }
    }


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
Java 数据库连接 Maven
手把手教你如何搭建SSM框架、图书商城系统案例
这篇文章是关于如何搭建SSM框架以及实现一个图书商城系统的详细教程,包括了项目的配置文件整合、依赖管理、项目结构和运行效果展示,并提供了GitHub源码链接。
手把手教你如何搭建SSM框架、图书商城系统案例
|
11天前
|
SQL Java 数据库连接
持久层框架MyBatisPlus
持久层框架MyBatisPlus
29 1
持久层框架MyBatisPlus
|
25天前
|
缓存 Cloud Native 安全
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
28 0
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
2月前
|
XML Java 数据库连接
如何搭建SSM框架、图书商城系统
这是一份详尽的《Spring + SpringMVC + Mybatis 整合指南》,作者耗时良久整理出约五万字的内容,现已经全部笔记公开。此文档详细地介绍了如何搭建与整合SSM框架,具体步骤包括创建Maven项目、添加web骨架、配置pom文件以及整合Spring、SpringMVC和Mybatis等。无论是对初学者还是有一定基础的开发者来说,都是很好的学习资源。此外,作者还提供了项目源码的GitHub链接,方便读者实践。虽然当前主流推荐学习SpringBoot,但了解SSM框架仍然是不可或缺的基础。
35 0
|
3月前
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
36 0
|
1月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
105 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
52 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
287 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
1月前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
16 0
mybatis使用二:springboot 整合 mybatis,创建开发环境