springboot第15集:MyBatis分页

news2024/11/6 7:07:38

我们在测试SQL的时候,要是能够在控制台输出 SQL 的话,是不是就能够有更快的排错效率?

是的,输出 SQL 可以帮助我们更好地理解代码的执行流程和结果。在控制台输出 SQL 可以让我们看到实际执行的 SQL 语句,这样就能够更轻松地检查 SQL 查询、插入或更新语句是否正确。此外,通过输出 SQL,还可以查看实际执行过程中的参数和变量的值,从而更好地调试代码问题。因此,在测试 SQL 的时候,输出 SQL 可以帮助我们提高排错效率,并提高代码质量。

为了方便开发者进行日志记录,Mybatis内置了日志工厂。该日志工厂支持多种具体的日志实现,包括以下几种工具:

  1. SLF4J

  2. Apache Commons Logging

  3. Log4j 2

  4. Log4j

  5. JDK logging

<settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

介绍一下Log4j:

Log4j是Apache开源项目之一,它提供了灵活的日志功能,可以控制日志信息的输出目的地,如控制台、文本、GUI组件等。同时,我们也可以定义每条日志信息的输出格式,并通过定义不同级别的日志来更加精细地控制日志的生成过程。最为方便的是,这些设置都可以通过一个配置文件进行灵活配置,而无需修改应用程序的代码。

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

<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>

//注意导包:org.apache.log4j.Logger
static Logger logger = Logger.getLogger(MyTest.class);
@Test
public void selectUser() {
    logger.info("info:进入selectUser方法");
    logger.debug("debug:进入selectUser方法");
    logger.error("error: 进入selectUser方法");
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.selectUser();
    for (User user: users){
        System.out.println(user);
    }
    session.close();
}

为什么需要使用分页?

在使用持久层框架(如Mybatis)进行数据访问操作时,最常用的就是数据库的查询操作。当需要查询大量数据时,我们往往会采取分页的方式进行查询,即每次只查询一小部分数据。这样做的好处在于可以有效地减轻数据库的负担,保证系统的可靠性和稳定性。同时,通过分页操作还可以使查询结果更加清晰明了,方便用户查看相关数据。

#语法
SELECT * FROM table LIMIT stratIndex,pageSize
SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15   
#为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:    
SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.   
#如果只给定一个参数,它表示返回最大的记录行数目:    
SELECT * FROM table LIMIT 5; //检索前 5 个记录行   
#换句话说,LIMIT n 等价于 LIMIT 0,n。
<select id="selectUser" parameterType="map" resultType="user">
    select * from user limit #{startIndex},#{pageSize}
</select>
//选择全部用户实现分页
List<User> selectUser(Map<String,Integer> map);
//分页查询 , 两个参数startIndex , pageSize
@Test
public void testSelectUser() {
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    int currentPage = 1;  //第几页
    int pageSize = 2;  //每页显示几个
    Map<String,Integer> map = new HashMap<String,Integer>();
    map.put("startIndex",(currentPage-1)*pageSize);
    map.put("pageSize",pageSize);
    List<User> users = mapper.selectUser(map);
    for (User user: users){
        System.out.println(user);
    }
    session.close();
}
//选择全部用户RowBounds实现分页
List<User> getUserByRowBounds();
<select id="getUserByRowBounds" resultType="user">
  select * from user
</select>
@Test
public void testUserByRowBounds() {
   SqlSession session = MybatisUtils.getSession();
   int currentPage = 2;  //第几页
   int pageSize = 2;  //每页显示几个
   RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize);
   //通过session.**方法进行传递rowBounds,[此种方式现在已经不推荐使用了]
   List<User> users = session.selectList("com.kuang.mapper.UserMapper.getUserByRowBounds", null, rowBounds);
   for (User user: users){
       System.out.println(user);
   }
   session.close();
}

面向接口编程

  • 解耦(Decoupling):将系统各个模块之间的依赖关系降到最小,使得修改一个模块不会对其他模块产生影响。这样可以提高系统的可维护性和扩展性。

  • 可拓展(Scalable):系统应该能够支持未来的扩展和增长,而不需要进行大规模的重构。这通常需要采用标准化的技术和接口,并保持系统的松散耦合。

  • 提高复用(Reusable):将通用的模块或功能封装成可复用的组件,可以节省开发时间和成本,并且使得整个系统更易于维护。

  • 分层开发(Layered Architecture):将系统按照不同的层次分解,每个层次都有特定的职责和功能,层与层之间通过标准化的接口进行通讯。这样可以降低系统的复杂度,提高可维护性和可扩展性。

  • 上层不用管具体的实现(Abstraction):将具体的实现细节隐藏在抽象的接口后面,上层只需要知道接口的使用方法和结果,不需要了解底层的实现。这可以提高系统的灵活性和可维护性,并且降低对实现的依赖。

  • 面向对象(Object-oriented):这种开发方式将系统中的对象作为基本的构建模块,每个对象具有特定的属性和方法,并且可以相互交互。这种开发方式更加注重对象之间的关系和交互,强调封装、继承和多态等概念。

  • 面向过程(Procedure-oriented):这种开发方式以一个从头到尾的流程或者事务为单元,考虑它们的实现细节。这种开发方式更加注重任务的执行步骤和流程控制,强调顺序结构、分支结构和循环结构等概念。

  • 接口设计与非接口设计:这是针对复用技术而言的,与面向对象(过程)不是一个问题。接口设计提供了标准化的接口来实现模块之间的通讯,从而提高了代码的复用性和可维护性。而非接口设计则通过直接调用其他模块的函数或方法来实现代码的复用,但这种方式会增加模块之间的依赖性,降低系统的灵活性和可维护性。

总的来说,这些概念都是软件开发中的基础概念,对于系统的整体架构和开发方式都有很大的影响。

sql 类型主要分成 : @select () @update () @Insert () @delete ()

这是 SQL 语言中常用的四个操作类型:

  • SELECT:用于查询数据库中的数据,可以指定需要查询的表、字段、条件等信息,并返回符合要求的数据结果集。

  • UPDATE:用于更新数据库中的数据,可以修改已有记录或新增记录,并返回被更新的记录数。

  • INSERT:用于向数据库中插入新的记录,可以同时插入多条记录,并返回被插入记录的 ID 或者新增成功的记录数。

  • DELETE:用于删除数据库中的数据,可以根据指定的条件删除单条记录或多条记录,并返回被影响的记录数。

这些操作类型是 SQL 语言中最基础的操作,用于对数据库进行增删改查等操作。在实际应用中,我们可以通过组合使用这些操作类型来完成更加复杂的操作,例如多表联合查询、批量更新等。掌握这些操作类型对于开发 SQL 数据库和进行数据处理非常重要。

//查询全部用户
@Select("select id,name,pwd password from user")
public List<User> getAllUser();
<!--使用class绑定接口-->
<mappers>
    <mapper class="com.kuang.mapper.UserMapper"/>
</mappers>
@Test
public void testGetAllUser() {
    SqlSession session = MybatisUtils.getSession();
    //本质上利用了jvm的动态代理机制
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.getAllUser();
    for (User user : users){
        System.out.println(user);
    }
    session.close();
}
5d01548fc7a42acd994a71a1922bf869.png
image.png
//获取SqlSession连接
public static SqlSession getSession(){
   return getSession(true); //事务自动提交
}
public static SqlSession getSession(boolean flag){
   return sqlSessionFactory.openSession(flag);
}
//根据id查询用户
@Select("select * from user where id = #{id}")
User selectUserById(@Param("id") int id);
@Test
public void testSelectUserById() {
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserById(1);
    System.out.println(user);
    session.close();
}
//添加一个用户
@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
@Test
public void testAddUser() {
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = new User(6, "xx", "123456");
    mapper.addUser(user);
    session.close();
}
//修改一个用户
@Update("update user set name=#{name},pwd=#{pwd} where id = #{id}")
int updateUser(User user);
@Test
public void testUpdateUser() {
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = new User(6, "xxxx", "3456");
    mapper.updateUser(user);
    session.close();
}
//根据id删除用
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id")int id);
@Test
public void testDeleteUser() {
    SqlSession session = MybatisUtils.getSession();
    UserMapper mapper = session.getMapper(UserMapper.class);
    mapper.deleteUser(6);
    session.close();
}

关于 @Param 注解的用法,主要是为方法中的参数指定一个名称,以便在 SQL 语句中引用。以下是一些使用原则:

  • 在方法只接受一个参数时,可以不使用 @Param 注解。此时,MyBatis 会将参数作为"param1"来处理。

  • 在方法接受多个参数的情况下,建议一定要使用 @Param 注解给参数命名,以避免出现混淆或错误的情况。同时,在 SQL 语句中引用参数时,也需要使用相应的名称。

  • 如果参数是 JavaBean,那么不能使用 @Param 注解进行命名。MyBatis 会自动将 JavaBean 的属性名作为参数名,并且可以通过 #{} 来引用属性值。

  • 如果不使用 @Param 注解,那么方法中只能有一个参数,并且这个参数必须是 JavaBean 类型。

总之,使用 @Param 注解可以提高代码的可读性和可维护性,特别是在方法接收多个参数的情况下。而对于 JavaBean,则不需要使用 @Param 注解,因为 MyBatis 能够自动处理 JavaBean 属性名和参数名的映射关系。

public interface UserMapper {
    /**
     * 根据用户id查询用户信息
     *
     * @param userId 用户id
     * @return 查询结果
     */
    @Select("SELECT * FROM users WHERE id = #{userId}")
    User getUserById(@Param("userId") Long userId);

    /**
     * 根据用户名和密码查询用户信息
     *
     * @param username 用户名
     * @param password 密码
     * @return 查询结果
     */
    @Select("SELECT * FROM users WHERE username = #{username} AND password = #{password}")
    User getUserByUsernameAndPassword(@Param("username") String username, @Param("password") String password);

    /**
     * 插入新的用户记录
     *
     * @param user 用户对象
     * @return 影响的行数
     */
    @Insert("INSERT INTO users(username, password) VALUES(#{user.username}, #{user.password})")
    int insertUser(@Param("user") User user);

    /**
     * 更新用户信息
     *
     * @param user 用户对象
     * @return 影响的行数
     */
    @Update("UPDATE users SET password = #{user.password} WHERE id = #{user.id}")
    int updateUser(@Param("user") User user);

    /**
     * 删除用户记录
     *
     * @param userId 用户id
     * @return 影响的行数
     */
    @Delete("DELETE FROM users WHERE id = #{userId}")
    int deleteUserById(@Param("userId") Long userId);
}

在 MyBatis 中,#{}${} 是用于 SQL 语句中参数占位的两种方式。

public interface UserMapper {
    /**
     * 根据用户名和密码查询用户信息
     *
     * @param username 用户名
     * @param password 密码
     * @return 查询结果
     */
    @Select("SELECT * FROM users WHERE username = #{username} AND password = #{password}")
    User getUserByUsernameAndPassword(@Param("username") String username, @Param("password") String password);

    /**
     * 动态查询用户记录
     *
     * @param condition 查询条件
     * @param orderField 排序字段
     * @param orderType 排序方式
     * @param limitStart 分页起始位置
     * @param limitSize 分页大小
     * @return 查询结果
     */
    @Select("<script>"
            + "SELECT * FROM users"
            + "<where>"
            + "<if test='condition != null'>"
            + "<![CDATA[AND (username LIKE CONCAT('%',#{condition},'%') OR email LIKE CONCAT('%',#{condition},'%'))]]>"
            + "</if>"
            + "</where>"
            + "<if test='orderField != null and orderType != null'>"
            + "<![CDATA[ORDER BY ${orderField} ${orderType}]]>"
            + "</if>"
            + "<if test='limitStart != null and limitSize != null'>"
            + "<![CDATA[LIMIT #{limitStart},#{limitSize}]]>"
            + "</if>"
            + "</script>")
    List<User> listUsers(@Param("condition") String condition, @Param("orderField") String orderField, @Param("orderType") String orderType, @Param("limitStart") Integer limitStart, @Param("limitSize") Integer limitSize);
}

加群联系作者vx:xiaoda0423

仓库地址:https://github.com/webVueBlog/JavaGuideInterview

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/485078.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

武忠祥老师每日一题||定积分基础训练(一)

若积分区间相同&#xff0c;最常用的思想&#xff1a; 若 f ( x ) > g ( x ) , 则 ∫ a b f ( x ) > ∫ a b g ( x ) 若f(x)>g(x),则\int_{a}^{b}f(x)>\int_{a}^{b}g(x) 若f(x)>g(x),则∫ab​f(x)>∫ab​g(x) 但 是 往 往 等 号 只 是 在 有 限 个 点 成…

Java实现添加文字水印、图片水印功能

Java实现添加水印功能 添加水印Java 2D API介绍绘制文字水印绘制图片水印循环添加文字水印 添加水印 为图片添加水印的主要作用是保护图片版权&#xff0c;防止图片被未经授权的人使用或传播。为图片添加水印是一种常用的图片处理技术。在Java 中可以使用JDK自带的 Graphics2D …

快速上手Django(九) -Django下载文件、Django上传文件、Django实现excel导入导出

文章目录 快速上手Django(九) -django 上传文件request.FILES&#xff0c;下载文件一、Django下载文件1. Django下载文件方案和思路2. HttpResponse、StreamingHttpResponse和FileResponse区别和选择StreamingHttpResponse和FileResponse对象的对比和选择使用HttpResponse使用S…

浏览器安全之XSS跨站脚本

基本概念 跨站脚本&#xff08;Cross-Site Scripting&#xff0c;XSS&#xff09;是一种经常出现在Web应用程序中的计算机安全漏洞&#xff0c;是由于Web应用程序对用户的输入过滤不足而产生的。 攻击者利用网站漏洞把恶意的脚本代码&#xff08;通常包括HTML代码和客户端Javas…

采用.Net Core技术框架开发的B/S版区域检验管理系统(云LIS)

实验室信息管理系统云LIS源码 SaaS模式运维管理系统 云LIS系统源码是一款全面的实验室信息管理系统源码&#xff0c;其主要功能包括样本管理、检测项目管理、质控管理、报告管理、数据分析、两癌筛查等多个方面。具有独立的配套SaaS模式运维管理系统&#xff0c;支持远程运维&…

AtCoder Beginner Contest 300——A-G题讲解

蒟蒻来讲题&#xff0c;还望大家喜。若哪有问题&#xff0c;大家尽可提&#xff01; Hello, 大家好哇&#xff01;本初中生蒟蒻讲解一下AtCoder Beginner Contest 300这场比赛的A-G题&#xff01; A - N-choice question 原题 Problem Statement Given integers A A A and…

数据埋点2

文章目录 1 数据埋点流程2 六个步骤实现数据埋点设计2.1 确认事件与变量2.2 明确事件的触发时机2.3 明确事件的上报机制2.4 设计数据表结构2.5 统一字段命名规范2.6 明确优先级 3 以电商购物成交转化为例实现数据埋点设计 作为数据分析师的你&#xff0c;是否和我一样经常会被业…

基于改进的离散PSO算法的FJSP的研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

排位赛结果“测谎”

甲乙丙丁说的关于排位赛结果只正确一半&#xff0c;根据甲乙丙丁说的信息求出正确的排位赛结果顺序。 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那…

chatGPT免费入口-ChatGPT国内中文版网站

chatgpt怎么使用 如果您有Chat GPT的API Key并想要使用Chat GPT进行自然语言处理或生成处理&#xff0c;您可以按照以下步骤操作&#xff1a; 安装必要的软件和工具 在使用Chat GPT之前&#xff0c;您需要先安装一些必要的软件和工具&#xff0c;例如Python解释器、HTTP客户…

【Android车载系列】第11章 系统服务-SystemServer自定义服务

1 编写自定义系统服务 1.1 AIDL接口定义 系统源码目录/frameworks/base/core/java/android/app/下新建AIDL接口IYvanManager.aidl package android.app;/** * 目录&#xff1a;/frameworks/base/core/java/android/app/IYvanManager.aidl */ interface IYvanManager{String …

YOLOV5入门讲解+常用数据集

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

TIM-输出比较(PWM)——STM32

TIM-输出比较——STM32 Oc (Output Compare) 输出比较 输出比较可以通过比较CNT与CCR寄存器值的关系&#xff0c;来对输出电平进行置1、置0或翻转的操作&#xff0c;用于输出一定频率和占空比的PWM波形 每个高级定时器和通用定时器都拥有4个输出比较通道高级定时器的前3个通道…

2023年股票质押违约处置研究报告

第一章 行业概况 1.1 产品定义 股票质押违约处置是指在股票质押融资中&#xff0c;当质押人&#xff08;股票持有者&#xff09;无法按照约定履行还款义务时&#xff0c;质权人&#xff08;通常为金融机构&#xff09;对质押股票进行处置的一系列活动。这个行业涉及到多个领域…

DAY 55 mysql数据库管理

常用的数据类型&#xff1a; 类型说明int整型&#xff0c;用于定义整数类型的数据fload单精度浮点4字节32位&#xff0c;准确表示到小数点后六位double双精度浮点8字节64位char固定长度的字符类型&#xff0c;用于定义字符类型数据。varchar可变长度的字符类型text文本image图…

Python基础合集 练习23 (错误与异常语句处理3)

‘’’ raise语句 raise[ExceptionName[(reason)]] 其中ExceptionName[(reason)]是可选参数用来指定抛出异常名称和原因,如果省略该参数,就会原样输出当前的错误 ‘’’ 在下面程序中,使用raise语句抛出ValueError异常 def num_calu(): book int(input(输入图书数量: )) stu…

探秘C语言:位运算符的奥秘

本篇博客会讲解C语言中的6个位操作符&#xff1a;按位取反(~)、按位与(&)、按位或(|)、按位异或(^)、左移(<<)、右移(>>)。这6个操作符都是操作整数的二进制位的。在学习这6个位操作符之前&#xff0c;大家需要先掌握“整数在内存中的存储”这个知识点&#xf…

数电中需要注意的问题

逻辑函数表达式之间的相互转换 &#xff08;更多请详见PPT&#xff09;若题目要求用&#xff1a; 与非门实现逻辑函数&#xff0c;则画卡诺图圈出值为1的然后化简 或非门实现逻辑函数&#xff0c;则画卡诺图圈出值为0的然后化简 与或非门实现逻辑函数&#xff0c;则画卡诺图圈…

一文了解获得 Zebec Labs 投资的 Coral Finance,空投计划或在不久推出

在前不久&#xff0c;Zebec Labs宣布对链上衍生品协议Coral Finance进行150万美元的投资&#xff0c;以帮助该协议完成早期启动并&#xff0c;并在后续持续的为其提供孵化支持。Coral Finance将在不久部署在Nautilus Chain主网上。据了解&#xff0c;Coral Finance是Nautilus C…

51单片机电路基础

一.电平特性 单片机是一种数字集成芯片&#xff0c;数字电路中只有两种电平:高电平和低电平。 高电平: 5V低电平: 0V TTL电平信号被利用的最多是因为通常数据表示采用二进制&#xff0c;5V等价于逻辑“1”&#xff0c;0V等价于逻辑“0”。 TTL电平规定高电平输出电压>2.…