手机网站开发语言/电商运营自学网站

手机网站开发语言,电商运营自学网站,南京做网站哪家公司最好,北京矿建建设集团有限公司网站MyBatis是一个优秀的持久化框架,用于简化JDBC的开发。 持久层就是持久化访问的层,就是数据访问层(Dao),用于访问数据库的。 MyBatis使用的准备工作 创建项目,导入mybatis的启动依赖,mysql的驱…

MyBatis是一个优秀的持久化框架,用于简化JDBC的开发。

持久层就是持久化访问的层,就是数据访问层(Dao),用于访问数据库的。

MyBatis使用的准备工作

创建项目,导入mybatis的启动依赖,mysql的驱动包

在pom文件中生成依赖

        <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.4</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>

首先我们准备一下数据库的数据

 

 创建user_info表

DROP DATABASE IF EXISTS mybatis_test;CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
USE mybatis_test;DROP TABLE IF EXISTS user_info;CREATE TABLE `user_info` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1
',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; 
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )VALUES ( 'admin', 'admin', 18, 1, '18612340001' );INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

配置数据库的连接(.yml文件中的配置)

 

创建数据库表中对应的实体类

@Data
public class UserInfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;private Integer deleteFlag;private Date createTime;private Date updateTime;
}

 注:数据库中字段全部都使用小写,单词之间用_来连接,Java中的属性使用小驼峰的方式

 注:由于引入了lombok依赖,所以直接使用@Date注解,不需要再去写Getter和Setter方法

 

创建在持久层的接口,在MyBatis中持久层中的接口一般使用 xxxMapper 的命名方法

我们创建了UserInfoMapper接口

注:@Mapper注解就是表明该接口是MyBatis中的Mapper接口

单元测试

在创建出来的SpringBoot⼯程中,在src下的test⽬录下,已经⾃动帮我们创建好了测试类,我们可以 直接使⽤这个测试类来进⾏测试

单元测试是开发人员进行的测试,与测试人员无关。

 

进行测试的方法

生成测试类的方法

 找到你需要生成测试类的Mapper接口的方法上,右键generate,点击Test

在你需要测试的方法上打 √ ,然后点ok就会自动生成了

MyBatis中的基础操作(注解)

打印日志

只需要在配置文件中配置即可

就可以直接看到sql的执行过程,参数传递,执行结果。

参数的传递

查询对象的方式(select)

id为固定值的时候
@Select("select * from user_info where id=3")List<UserInfo> selectAllById();
@Testvoid selectAllId() {System.out.println(userInfoMapper.selectAllById());}

 

id为动态的数值

使用#{}的方式获取方法中的参数

    @Select("select * from user_info where id=#{id}")UserInfo selectAllById3(Integer id);
@Testvoid selectAllById3() {System.out.println(userInfoMapper.selectAllById3(1));}

 

 

传递多个参数 
 @Select("select * from user_info where username=#{username} and password=#{password}")UserInfo selectAllByUserNameAndPassWord(String username,String password);
 @Testvoid selectAllByUserNameAndPassWord() {System.out.println(userInfoMapper.selectAllByUserNameAndPassWord("zhangsan","zhangsan"));}

 可以使用@Param注解进行参数的绑定(重命名)
@Select("select * from user_info where username=#{aa} and password=#{bb}")UserInfo selectAllByUserNameAndPassWord2(@Param("aa") String username,@Param("bb") String password);
@Testvoid selectAllByUserNameAndPassWord2() {System.out.println(userInfoMapper.selectAllByUserNameAndPassWord2("zhangsan","zhangsan"));}

 

增 (Insert)

@Insert("insert into user_info (username,password,age) values (#{username},#{password},#{age})")Integer insert(UserInfo userInfo);
@Testvoid insert() {UserInfo userInfo=new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("lisi");userInfo.setAge(1);Integer result=userInfoMapper.insert(userInfo);System.out.println("新增行数"+result);}

 

返回主键

获得自增Id

//获取自增Id@Options(useGeneratedKeys = true,keyProperty = "id")@Insert("insert into user_info (username,password,age) values (#{username},#{password},#{age})")Integer insert1(UserInfo userInfo);
@Testvoid insert1() {UserInfo userInfo=new UserInfo();userInfo.setUsername("lisi");userInfo.setPassword("lisi");userInfo.setAge(1);Integer result=userInfoMapper.insert1(userInfo);System.out.println("新增行数"+result+"Id"+userInfo.getId());}

 

删 (delete)

@Delete("delete from user_info where id =#{id}")Integer deleteUser(Integer id);
@Testvoid deleteUser() {userInfoMapper.deleteUser(13);}

 

 

改(update)

@Update("update user_info set delete_flag= #{deleteFlag},phone= #{phone} where id= #{id}")Integer updateUser(UserInfo userInfo);
@Testvoid updateUser() {UserInfo userInfo=new UserInfo();userInfo.setDeleteFlag(1);userInfo.setPhone("123");userInfo.setId(11);Integer result=userInfoMapper.updateUser(userInfo);System.out.println(result);}

 

查询的需要注意的问题

当我们进行查询的时候,我们会发现某些字段是没有进行赋值的,只有Java对象属性和数据库字段⼀模⼀样时,才会进⾏赋值

原因:MyBatis 在执行查询后,会将数据库中的字段值映射(映射 = 赋值)到 Java 实体类对象的属性中。但是,如果 数据库字段名和 Java 对象属性名不一致,MyBatis 默认不会自动进行映射赋值

解决办法:

1.起别名

@Select("select id, username,`password`, age, gender,  phone, " + 
"delete_flag as deleteFlag, create_time as createTime, update_time as updateTime" + 
" from user_info")

 2.结果映射

@Results(id = "BaseMap", value = {@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})
@Select("select * from user_info")

3.添加驼峰命名的配置文件

设置为true

MyBatis XML配置文件 

MyBatis的开发方式一般有两种,注解 & XML

现在我们来学习XML的开发方式

配置mybatis

Spring Boot 集成 MyBatis 时指定 Mapper XML 文件的位置,告诉 MyBatis 去哪里加载 SQL 映射文件 

添加Mapper接口

添加 .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 namespace="com.blame.springmybatis.mapper.UserInfoMapperXML"><select id="selectUserAll" resultType="com.blame.springmybatis.model.UserInfo">select * from user_info</select></mapper>

 

单元测试

@SpringBootTest
class UserInfoMapperXMLTest {@Autowiredprivate UserInfoMapperXML userInfoMapperXML;@Testvoid selectUserAll() {userInfoMapperXML.selectUserAll().stream().forEach(x-> System.out.println(x));}
}

 

XML中的增删改查 

增(insert)

 Integer insertUser(UserInfo userInfo);
 <insert id="insertUser">insert into user_info (username, `password`, age) VALUES (#{username}, #{password}, #{age})</insert>
@Testvoid insertUser() {UserInfo userInfo=new UserInfo();userInfo.setUsername("xiaohei");userInfo.setPassword("123");userInfo.setAge(11);Integer result=userInfoMapperXML.insertUser(userInfo);System.out.println("增加行数"+result+"Id"+userInfo.getId());}

 

使用@Param注解进行重命名

Integer insertUser2(@Param("UserInfo") UserInfo userInfo);
<insert id="insertUser2">insert into user_Info (username, `password`, age) VALUES (#{username}, #{password}, #{age})</insert>
@Testvoid insertUser2() {UserInfo userInfo=new UserInfo();userInfo.setUsername("hei");userInfo.setPassword("15");userInfo.setAge(13);Integer result=userInfoMapperXML.insertUser(userInfo);System.out.println("增加行数"+result+"Id"+userInfo.getId());}

自增Id

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">insert into user_info (username, `password`, age, gender, phone) values(#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender},#{userInfo.phone})</insert>

 删(delete)

Integer deleteUser(Integer id);
<delete id="deleteUser">delete from user_info where id =#{id}</delete>
   @Testvoid deleteUser() {userInfoMapperXML.deleteUser(16);}

 

 

改(update)

<update id="updateUser">update user_info set  password= #{password} , age=#{age} where id= #{id}</update>
Integer updateUser(String password,Integer age,Integer id);
@Testvoid updateUser() {UserInfo userInfo=new UserInfo();Integer result=userInfoMapperXML.updateUser("123",88,9);}

查(select) 

List<UserInfo> selectUserAll();
<select id="selectUserAll" resultType="com.blame.springmybatis.model.UserInfo">select * from user_info</select>

其他查询

联合查询(多表查询)

在数据库中导入表

DROP TABLE IF EXISTS articleinfo;
CREATE TABLE articleinfo (id INT PRIMARY KEY auto_increment,title VARCHAR ( 100 ) NOT NULL,content TEXT NOT NULL,uid INT NOT NULL,delete_flag TINYINT ( 4 ) DEFAULT 0 COMMENT,create_time DATETIME DEFAULT now(),update_time DATETIME DEFAULT now() 
) DEFAULT charset 'utf8mb4';INSERT INTO articleinfo ( title, content, uid ) VALUES ( 'Java', 'Java正⽂', 1 );

配置对应的实体类

@Data
public class ArticleInfo {private Integer id;private String title;private String content;private Integer uid;private Integer deleteFlag;private Date createTime;private Date updateTime;private String username;private Integer age;
}

 定义接口

@Mapper
public interface ArticleInfoMapper {ArticleInfo selectArticleById(Integer id);
}

配置 .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 namespace="com.blame.springmybatis.mapper.ArticleInfoMapper"><select id="selectArticleById" resultType="com.blame.springmybatis.model.ArticleInfo">select ta.*,tb.username,tb.age from article_info ta left 
join user_info tb on ta.uid = tb.id where ta.id=#{id}</select>
</mapper>

测试类

@SpringBootTest
class ArticleInfoMapperTest {@Autowiredprivate ArticleInfoMapper articleInfoMapper;@Testvoid selectArticleById() {articleInfoMapper.selectArticleById(1);}
}

 

#{ }和${ }

这是mybatis中非常重要的两个占位符

首先我们看一下#{}

@Select("select username,`password`,age,gender,phone from user_info where id=#{id}")UserInfo queryById(Integer id);
@Testvoid queryById() {System.out.println(userInfoMapper.queryById(2));}

通过观察我们的sql语句,我们发现我们输入的参数 2 ,并没有在语句后面显示,而是用 ? ,我们把这种叫做预编译SQL

我们再观察一下${}

    @Select("select username,`password`,age,gender,phone from user_info where id=${id}")UserInfo queryById2(Integer id);
@Testvoid queryById2() {System.out.println(userInfoMapper.queryById2(2));}

 我们可以发现参数直接是拼在SQL语句中了

我们再把参数换成String类型

@Select("select username,`password`,age,gender,phone from user_info where username=#{username}")UserInfo queryById3(String username);@Select("select username,`password`,age,gender,phone from user_info where username=${username}")UserInfo queryById4(String username);
@Testvoid queryById3() {System.out.println(userInfoMapper.queryById3("zhangsan"));}@Testvoid queryById4() {System.out.println(userInfoMapper.queryById4("zhangsan"));}

我们先来看一下#{}的测试结果

 再看一下${}的测试结果

我们发现报错了,说SQL语法异常

这次的参数是直接拼在SQL语句的后面,没有自动给username添加  ' '

修改后,测试成功

 @Select("select username,`password`,age,gender,phone from user_info where username='${username}'")UserInfo queryById4(String username);

 

通过上面这个例子,我们可以发现#{}使用的是预编译SQL,通过?进行占位,提前对SQL进行编译,将参数填充到SQL语句中,#{}会根据参数类型,自动拼接引号 ' '

${}会直接进行字符的替换,一起对SQL进行编译,如果是字符串,得加上引号' '

SQL语句的执行流程

1.语法解析        2.SQL优化        3.SQL编译        4.SQL执行 

 #{} 和${}区别

#{}的性能更高

${}会出现SQL注入的风险

SQL注入:是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的 ⽅法

SQL注入的代码演示

@Select("select username, `password`, age, gender, phone from user_info where username= '${name}' ")List<UserInfo> queryByName(String name);
@Testvoid queryByName() {List<UserInfo> userInfos = userInfoMapper.queryByName("admin");System.out.println(userInfos);}

 测试成功

但是,如果我们参数传为以下的情况,我们发现不仅没有报错,而且得到了我们表中的全部信息,这就是SQL注入

@Testvoid queryByName() {List<UserInfo> userInfos = userInfoMapper.queryByName("' or 1='1");System.out.println(userInfos);}

 

排序功能 

当我们表中数据按Id逆序进行排序,发现${}排序成功

 @Select("select id, username, age, gender, phone, delete_flag, create_time,update_time " +"from user_info order by id ${sort} ")List<UserInfo> queryAllUserBySort(String sort);
@Testvoid queryAllUserBySort() {System.out.println(userInfoMapper.queryAllUserBySort("desc"));}

但我们发现#{} 没有成功,进行了报错。

@Select("select id, username, age, gender, phone, delete_flag, create_time,update_time " +"from user_info order by id #{sort} ")List<UserInfo> queryAllUserBySort2(String sort);

SQL语法错误异常 

 

可以发现,当使⽤ #{sort} 查询时,asc前后⾃动给加了引号,导致sql错误

like的使用

 @Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +"from user_info where username like '%#{key}%' ")List<UserInfo> queryAllUserByLike(String key);

这里 '%#{key}%' 是错误写法,因为 #{} 在 MyBatis 中是 参数占位符,它不会在 SQL 字符串内部被当作字符串拼接,而是被替换成 ? 

我们可以使用从concat()

@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +"from user_info where username like concat('%',#{key},'%')")List<UserInfo> queryAllUserByLike(String key);

 

数据库连接池

预先创建好的一批数据库连接,当应用程序要访问数据库时,从池中获取连接,操作完成后再归还,而不是每次都重新建立和关闭连接

常用的的数据连接池

HikariCP(Spring Boot默认):性能最快、轻量

Druid(阿里巴巴):功能丰富、监控强大

C3P0 :比较落后

DBCP :使用少

切换数据库连接池 

如果我们想把默认的数据库连接池切换为Druid数据库连接池,只需要引⼊相关依赖即可 

<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.21</version></dependency>

希望能对大家有所帮助!!!!! 

 

 

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

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

相关文章

Go语言的基础类型

一基础数据类型 一、布尔型&#xff08;Bool&#xff09; 定义&#xff1a;表示逻辑真 / 假&#xff0c;仅有两个值&#xff1a;true 和 false内存占用&#xff1a;1 字节使用场景&#xff1a;条件判断、逻辑运算 二、数值型&#xff08;Numeric&#xff09; 1. 整数类型&…

发布第四代液晶电视,TCL引领全新美学境界

在不断革新的消费电子领域中&#xff0c;电视行业在视觉体验上正面临重要的美学挑战。如何打破全面屏时代的物理束缚&#xff0c;将家居空间提升到“视觉无界”的层次&#xff0c;以及如何让尖端技术更好地服务于影像沉浸感&#xff0c;成为行业关注的焦点。 3月10日&#xff…

【C++】STL库面试常问点

STL库 什么是STL库 C标准模板库&#xff08;Standard Template Libiary&#xff09;基于泛型编程&#xff08;模板&#xff09;&#xff0c;实现常见的数据结构和算法&#xff0c;提升代码的复用性和效率。 STL库有哪些组件 STL库由以下组件构成&#xff1a; ● 容器&#xf…

【问题解决】Postman 测试报错 406

现象 Tomcat 日志 org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved org.springframework.web.HttpMediaTypeNotAcceptableException: No acceptable representation HTTP状态 406 - 不可接收 的报错&#xff0c;核心原因 客…

Flutter 打包 ipa出现错误问题 exportArchive

一、错误信息: Encountered error while creating the IPA: error: exportArchive: "Runner.app" requires a provisioning profile with the Push Notifications feature. Try distributing the app in Xcode: open /project/your_app/build/ios/archive/Runner.…

STC89C52单片机学习——第28节: [12-2] AT24C02数据存储秒表(定时器扫描按键数码管)

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.03.20 51单片机学习——第28节: [12-2] AT24C02数据存储&秒表&#xff08;定时器扫…

Verilog-HDL/SystemVerilog/Bluespec SystemVerilog vscode 配置

下载 verible https://github.com/chipsalliance/verible的二进制包 然后配置 vscode

STM32使用HAL库,模拟UART输出字符串

测试芯片是STM32F103C8T6&#xff0c;直接封装好了&#xff0c;波特率是 9600 MyDbg.h #ifndef __MYDBG_H #define __MYDBG_H #include "stm32f1xx_hal.h" #include <stdio.h> #include <stdarg.h>/*使用GPIO口 模拟 UART 输出字符串 */ //初始化调试…

[工控机安全] 使用DriverView快速排查不可信第三方驱动(附详细图文教程)

导语&#xff1a; 在工业控制领域&#xff0c;设备驱动程序的安全性至关重要。第三方驱动可能存在兼容性问题、安全漏洞甚至恶意代码&#xff0c;威胁设备稳定运行。本文将手把手教你使用 DriverView工具&#xff0c;高效完成工控机驱动安全检查&#xff0c;精准识别可疑驱动&a…

洛谷P1434 [SHOI2002] 滑雪

P1434 [SHOI2002] 滑雪 - 洛谷 代码区&#xff1a; #include<algorithm> #include<iostream> #include<cstring> using namespace std;const int MAX 105; int r, c; int arr[MAX][MAX], dp[MAX][MAX]; int xindex[4] {-1,1,0,0};//上下左右 int yindex[…

【操作系统】进程间通信方式

进程间通信方式 前言 / 概述一、管道管道命名管道 二、消息队列三、共享内存四、信号量信号量概述互斥访问条件同步信号 五、socket总结 前言 / 概述 每个进程的用户地址空间都是独立的&#xff0c;⼀般而言是不能互相访问的&#xff0c;但内核空间是每个进程都共享的&#xff…

【程序人生】成功人生架构图(分层模型)

文章目录 ⭐前言⭐一、根基层——价值观与使命⭐二、支柱层——健康与能量⭐三、驱动层——学习与进化⭐四、网络层——关系系统⭐五、目标层——成就与财富⭐六、顶层——意义与传承⭐外层&#xff1a;调节环——平衡与抗风险⭐思维导图 标题详情作者JosieBook头衔CSDN博客专家…

【最后203篇系列】020 rocksdb agent

今天还是挺开心的一天&#xff0c;又在工具箱里加了一个工具。嗯&#xff0c;但是快下班的时候也碰到一些不太顺心的事&#xff0c;让我有点恼火。我还真没想到一个专职的前端&#xff0c;加测试&#xff0c;以及其他一堆人&#xff0c;竟然不知道后端返回的markdown,在前端渲染…

vulhub靶机----基于docker的初探索,环境搭建

环境搭建 首先就是搭建docker环境&#xff0c;这里暂且写一下 #在kali apt update apt install docker.io配置docker源&#xff0c;位置在/etc/docker/daemon.json {"registry-mirrors": ["https://5tqw56kt.mirror.aliyuncs.com","https://docker…

网络编程之解除udp判断客户端是否断开

思路&#xff1a;每几秒发送一条不显示的信息&#xff0c;客户端断开则不再发送信息&#xff0c;超时则表示客户端断开连接。&#xff08;心跳包&#xff09; 服务器 #include <head.h>#define MAX_CLIENTS 100 // 最大支持100个客户端 #define TIMEOUT 5 // 5秒…

B树与B+树在MySQL中的应用:索引

数据结构演示网站&#xff1a;Data Structure Visualization 先来了解两个数据结构B树与B树 B树&#xff1a; N阶B树每个节点最多存储N-1个Key&#xff0c;N个指针 例如&#xff1a;一个5阶B树&#xff0c;当前节点存储到5个Key时&#xff0c;中间的数会向上分离&#xff0c;…

Centos7配置本地yum源

Centos7配置本地yum源 1、基于iso镜像的centos源 1.1 准备iso <span style"color:#000000"><span style"background-color:#ffffff"><code class"language-bash"><span style"color:#008000"># 首先看自己使用…

VNA操作使用学习-14 再测晶振特性

再测一下4Mhz晶振&#xff0c;看看特性曲线&#xff0c;熟悉一下vna使用。 s11模式&#xff0c;找遍了各种format都无法显示&#xff0c;只有这一种&#xff08;s11&#xff0c;Resistance&#xff09;稍微显示出一个谐振&#xff0c;但是只有一个点。 s21模式 这是201p&#…

Tr0ll2靶机详解

一、主机发现 arp-scan -l靶机ip&#xff1a;192.168.55.164 二、端口扫描、漏洞扫描、目录枚举、指纹识别 2.1端口扫描 nmap --min-rate 10000 -p- 192.168.55.164发现21端口的ftp服务开启 以UDP协议进行扫描 使用参数-sU进行UDP扫描 nmap -sU --min-rate 10000 -p- 19…

基于开源模型的微调训练及瘦身打造随身扫描仪方案__用AI把手机变成文字识别小能手

基于开源模型的微调训练及瘦身打造随身扫描仪方案__用AI把手机变成文字识别小能手 一、准备工作&#xff1a;组装你的"数码工具箱" 1. 安装基础工具&#xff08;Python环境&#xff09; 操作步骤&#xff1a; 访问Python官网下载安装包安装时务必勾选Add Python to…