从Servlet+JSP+JDBC到MyBatis:重构用户CRUD操作的高效之旅

news2024/9/25 0:49:06

 前言

原生的JDBC:

  • 原生的JDBC操作数据库,书写较为繁琐,降低开发效率。
  • JDBC的局限性(如代码冗余、SQL语句与Java代码紧密耦合、难以维护等)。

相比于JDBC,Mybatis的优势:

  • SQL与Java代码的分离、强大的映射能力、易于维护和扩展等。

什么是Mybatis?

MyBatis是一个用于简化数据库操作、提高开发效率的持久层框架,它允许开发者通过简单的配置和映射来直接操作数据库,而无需深入处理JDBC的繁琐细节。

简而言之,Mybatis底层是基于JDBC进行的高级别封装,在简化原生JDBC操作的基础上,提高开发效率

 重构用户的CRUD项目

使用Mybatis框架重构项目,可以提高项目的扩展性,为后续框架整合打下基础,这里我会介绍如何使用mybatis框架代替原生JDBC操作数据库的相关操作。

原来项目可以参考我的博客: 实战指南:深度剖析Servlet+JSP+JDBC技术栈下的用户CRUD操作-CSDN博客

这里我主要介绍DAO层的开发

重构步骤如下:

第一步:导入mybatis相关的依赖,和log4j依赖

pom.xml:

新增如下依赖

<!--mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>
    <!--log4j-->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.7</version>
    </dependency>

注意:添加log4j依赖的目的是为了在mybatis开发过程中查看sql的执行情况,以便快速定位sql的错误位置。并且添加了log4j依赖,需要导入相关的配置文件到resources

 log4j.properties

### set log levels ###

log4j.rootLogger = debug,stdout 
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 =  %d %p [%c] - %m%n

log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug,stdout

 第二步:在resources目录下创建mybatis.xml文件作为mybatis的主配置文件

mybatis.xml

(这个配置文件名称可以任意)

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver"
                          value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/csx_demo?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

</configuration>

 注意:这里的数据库名以及username和password的value值应当是自己本地mysql服务器上的数据

第三步:创建DAO层,书写与之对应的mapper.xml映射文件

UserDao:

接口和接口方法和重构之前保持差不多,目的都是定义一个实现需求的规范,无论使用JDBC还是mybatis,本质上都是对接口声明的实现。

(下面展示的接口和原本项目的接口有些不同,因为我使用mybatis时,为了保证映射关系的正确配置,将传递多个参数的情况全部封装成对象,并通过对应的对象作为参数传递)

package dao;

import entity.User;
import entity.dto.UserDto;
import entity.dto.UserDtoNew;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserDao {

    /**
     * 查看用户总条数
     * @return
     */
    int selectUsersCount();

    /**
     * 分页查询用户列表
     * @return
     */
    List<User> selectUserListByPage(UserDto userDto);

    /**
     * 新增用户
     * @param user
     * @return
     */
    public int insertUser(User user);

    /**
     * 根据id查询指定用户信息
     * @param userId
     * @return
     */
    public User selectUserByUserId(int userId);

    /**
     * 根据id删除用户信息
     * @param userId
     * @return
     */
    public int deleteUserByUserId(int userId);

    /**
     * 修改用户数据
     * @param user
     * @return
     */
    public int updateUser(User user);

    /**
     * 根据用户名和密码查看指定用户是否存在
     * @return
     */
    public User selectUserByuserNameAndpassword(UserDtoNew userDtoNew);

}

新增实体类:

UserDto:

package entity.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UserDto implements Serializable {
    private String keyword;
    private Integer pageIndex;
    private Integer pageSize;



}

UserDtoNew:

package entity.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Setter
public class UserDtoNew implements Serializable {
    private String userName;
    private String password;
}

新增实体类的目的是当DAO接口中方法的形参为多个时,将形参封装成对象进行传参,从而可以方便的进行Java的属性和数据库中的字段(列)进行映射。

mapper.xml:

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" >
<!--
    mapper为映射的根节点,用来管理DAO接口 
    namespace指定DAO接口的完整类名,表示mapper配置文件管理哪个DAO接口(包.接口名)
    mybatis会依据这个接口动态创建一个实现类去实现这个接口,而这个实现类是一个Mapper对象
 -->
<mapper namespace="dao.UserDao">
    <resultMap id="userMap" type="entity.User">
        <id property="userId" column="user_id"/>
        <result property="userName" column="user_name"/>
        <result property="userPic" column="user_pic"/>
    </resultMap>
    <insert id="insertUser">
        insert into t_user (user_name,password,user_pic) values (#{userName},#{password},#{userPic})

    </insert>
    <update id="updateUser">
        update t_user set user_name=#{userName},password=#{password},user_pic=#{userPic} where user_id=#{userId}
    </update>
    <delete id="deleteUserByUserId">
        delete from t_user where user_id=#{userId}
    </delete>
    <select id="selectUsersCount" resultType="java.lang.Integer">
        select count(user_id) from t_user
    </select>
    <select id="selectUserListByPage" resultMap="userMap" parameterType="entity.dto.UserDto">
        select * from t_user where user_name like concat('%',#{keyword},'%') order by user_id desc limit #{pageIndex},#{pageSize}
    </select>
    <select id="selectUserByUserId" resultMap="userMap">
        select * from t_user where user_id = #{userId}
    </select>
    <select id="selectUserByuserNameAndpassword" resultMap="userMap">
        select * from t_user where user_name=#{userName} and password=#{password}
    </select>

    <!--
        id = "接口中的方法名"
        parameterType = "接口中传入方法的参数类型"
        resultType = "返回实体类对象:包.类名"  处理结果集 自动封装
        注意:sql语句后不要出现";"号
            查询:select标签
            增加:insert标签
            修改:update标签
            删除:delete标签
 -->
</mapper>

注意:

  • 因为我使用select * 查询字段,需要配置属性和字段的映射关系,使用<resultMap>标签
  • #{}表示的是占位符的含义,这里使用它的含义和使用原生JDBC的preparedstatement预编译sql是一样的
  • 当传入的参数为一个时,#{名字可以任意},如果传入的参数是多个,#{对应类的属性名}

 第四步:将mapper.xml的配置添加到主配置文件mybatis.xml配置中

mybatis.xml

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver"
                          value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/csx_demo?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/UserMapper.xml"></mapper>
    </mappers>

</configuration>

第五步:修改servlet类,使用mybatis获取sql支持

  • 在doPost方法中通过SqlSessionfactory创建SqlSession对象,在根据SqlSession对象获取对应的Dao实现类对象(代理对象)。
  • 调用Dao接口获取sql支持
 
 @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

SqlSession session= SqlSessionFactoryUtil.getSessionSql();
  UserDao userDao= session.getMapper(UserDao.class);
//...
}

获取到Dao层的对象之后,获取到对应的数据之后。剩余处理就和未重构之前的操作一样了(细节处有点差异)。

简而言之,就是JSP发送请求到Servlet,Servlet调用DAO获取数据并处理响应。 

 总结

以上就是使用mybatis替代原生JDBC重构用户CRUD项目的实现步骤,源代码我会上传到资源中

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

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

相关文章

2-102基于matlab的蒙特卡洛仿真

基于matlab的蒙特卡洛仿真&#xff0c;对64QAM和BPSK进行蒙特卡洛仿真&#xff0c;并绘出误码率曲线。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a; 2-102基于matlab的蒙特卡洛仿真

初探shell与bash使用指南

文章目录 一、shell二、bash第一步、新建脚本第二步、添加权限第三步、执行bash脚本 在日常开发中&#xff0c;经常使用到Linux服务器相关知识&#xff0c;输入命令获取想要的结果&#xff0c;本篇介绍shell 与 bash的相关知识。 一、shell 是命令行解释器&#xff0c;接收用户…

云岚到家 第一天实战总结

为什么使用post发送请求&#xff0c;参数依旧会被拼接带url上呢&#xff1f;这应该就是param 与data传参的区别。即param传参数参数会被拼接到url后&#xff0c;data会以请求体传递 不一定post发送请求&#xff0c;数据一定在请求体中&#xff0c;主要是看数据的格式。 后端c…

Makefile的写法以及gdb调试的使用方法

all:main # 一般makefile中的第一个目标都是all:可执行文件 # 为了保证&#xff0c;最后Makefile文件执行后一定会生成一个可执行文件main:main.o add.o gcc main.o add.o -o main main.o:main.cgcc -c main.c -o main.o add.o:add.cgcc -c add.c -o add.oclean: …

无人机之4G模块的主要功能和优势

一、增强图传 在无人机飞行过程中&#xff0c;传统的图传方式可能会受到信号遮挡或干扰的影响&#xff0c;导致图像传输不稳定甚至中断。而4G模块通过结合4G网络技术&#xff0c;能够在原有图传技术的基础上提供增强的图传功能。当传统图传信号不佳时&#xff0c;无人机可以自动…

MySQL 缓冲池管理与常见优化技巧

在 MySQL 数据库的性能优化中&#xff0c;缓冲池的管理至关重要。同时&#xff0c;了解其他常见的优化技巧也能极大地提升数据库的运行效率。今天&#xff0c;我们就来深入探讨在 MySQL 中如何管理并调整缓冲池的大小&#xff0c;以及一些常见的优化技巧。 一、缓冲池的重要性…

ZBrush入门使用介绍——17、NanoMesh

大家好&#xff0c;我是阿赵。   继续介绍ZBrush的用法&#xff0c;这次看看NanoMesh 一、 NanoMesh介绍 之前介绍过ArrayMesh&#xff0c;ArrayMesh可以把一个模型复制很多份。不过ArrayMesh有一个问题&#xff0c;复制了很多个网格之后&#xff0c;很难针对某部分网格做调…

鸿蒙开发(NEXT/API 12)【基础功能(Function Flow Runtime 开发)】任务并发调度

场景介绍 Function Flow编程模型是一种基于任务和数据驱动的并发编程模型&#xff0c;允许开发者通过任务及其依赖关系描述的方式进行应用开发。FFRT&#xff08;Function Flow运行时&#xff09;是支持Function Flow编程模型的软件运行时库&#xff0c;用于调度执行开发者基于…

《动手学深度学习》笔记1.10——激活函数←模型初始化←数值稳定性

目录 1. 数值稳定性 1.1 神经网络的梯度 1.2 数值稳定性的常见两个问题 1.3 梯度爆炸 1.3.1 MLP的例子 1.3.2 使用ReLU激活函数 1.3.3 产生的问题 1.4 梯度消失 1.4.1 使用sigmoid激活函数 1.4.2 梯度消失的问题 1.5 总结 2. 让训练更稳定 2.1 目标 (ResNet, LSTM…

8.进销存系统(基于springboot的进销存系统)

目录 1.系统的受众说明 2.开发技术与环境配置 2.1 SpringBoot框架 2.2 Java语言简介 2.3 MySQL环境配置 2.4 idea介绍 2.5 mysql数据库介绍 2.6 B/S架构 3.系统分析与设计 3.1 可行性分析 3.1.1 技术可行性 3.1.2 操作可行性 3.1.3经济可行性 3.4.1 数据库…

Java—反射机制详解

介绍反射 反射的基本概念 反射&#xff08;Reflection&#xff09;是Java语言中的一种机制&#xff0c;它允许程序在运行时检查和操作类、接口、字段和方法等类的内部结构。通过反射&#xff0c;你可以在运行时获取类的信息&#xff0c;包括类的构造器、字段、方法等&#xf…

k8s StorageClass 存储类

文章目录 一、概述1、StorageClass 对象定义2、StorageClass YAML 示例 二、StorageClass 字段1、provisioner&#xff08;存储制备器&#xff09;1.1、内置制备器1.2、第三方制备器 2、reclaimPolicy&#xff08;回收策略&#xff09;3、allowVolumeExpansion&#xff08;允许…

从碎片到整合:EasyCVR平台如何重塑城市感知系统的视频数据生态

随着城市化进程的加速&#xff0c;城市感知系统作为智慧城市的重要组成部分&#xff0c;正逐步成为提升城市管理效率、保障公共安全、优化资源配置的关键手段。EasyCVR视频汇聚融合平台&#xff0c;凭借其强大的数据整合、智能分析与远程监控能力&#xff0c;在城市感知系统中扮…

Sam Altman的博客:The Intelligence Age

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

thinkphp 做分布式服务+读写分离+分库分表+负载均衡(分区)(后续接着写)

thinkphp 做分布式服务读写分离分库分表负载均衡&#xff08;分区&#xff09; 引言 thinkphp* 大道至简负载均衡分布式服务一、读写分离1、读写分离的实现方式2、主从同步的三种模式2-1、异步模式&#xff08;mysql async-mode&#xff09;2-2、半同步模式&#xff08;mysql s…

红帽rhce含金量?考到能拿多少钱工资?

随着目前国内的it职业飞速发展&#xff0c;rhce已经成为it职业的首选认证、高薪亮点。主要是linux人才出现大比例短缺的状况&#xff0c;很多企业对linux人才的需求也继续升温。 这个时候大家如果抓住了机会&#xff0c;那么实力就能得到质的提升&#xff0c;那么小编针对红帽…

OpenAI GPT-3 API: What is the difference between davinci and text-davinci-003?

题意&#xff1a;OpenAI GPT-3 API&#xff1a;davinci 和 text-davinci-003 有什么区别 问题背景&#xff1a; Im testing the different models for OpenAI, and I noticed that not all of them are developed or trained enough to give a reliable response. 我正在测试…

论文阅读【时间序列】ModerTCN (ICLR2024)

【时间序列】ModerTCN (ICLR2024) 原文链接&#xff1a;ModernTCN: A Modern Pure Convolution Structure for General Time Series Analysis 代码仓库&#xff1a;ModerTCN 简易版本实现代码可以参考&#xff1a;&#xff08;2024 ICLR&#xff09;ModernTCN&#xff1a;A Mod…

谁是AI界的老司机?谁最“纯洁”?谁能通过暧昧小短文的终极考验?

AI的能力已经让人们惊叹不已&#xff0c;不管是帮你写文章、答疑解惑&#xff0c;还是生成艺术作品&#xff0c;几乎无所不能。但如果让AI来解读一篇暗藏玄机、暧昧十足的小短文&#xff0c;结果会怎样&#xff1f;今天&#xff0c;我们就把几款顶流AI大模型拉出来&#xff0c;…

Cobalt Strike的下载与基本用法

CobaltStrike4.8 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;tgf3 what Cobalt Strike是一款渗透测试神器&#xff0c;常被业界人称为CS神器。Cobalt Strike已经不再使用MSF而是作为单独的平台使用&#xff0c;它分为客户端与服务端&#xff0c;服务端是一个&…