JavaWeb后端基础(3)

原打算把Mysql操作数据库的一些知识写进去,但是感觉没必要,要是现在会的都是简单的增删改查,所以,这一篇,我直接从java操作数据库开始写,所以这一篇大致就是记一下JDBC、MyBatis、以及SpringBoot的配置文件

JDBC

JDBC是java最底层最基础的操作数据库的技术,这一部分因为之后用的少,我直接从代码开始看了。

@Testpublic void testUpdata() throws ClassNotFoundException, SQLException {//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取数据库链接String url = "jdbc:mysql://localhost:3306/web01";String username = "root";String password = "123456";Connection connection = DriverManager.getConnection(url, username, password);//获取SQL语句执行对象Statement statement = connection.createStatement();//执行SQLint flag = statement.executeUpdate("update user set age = 25 where id = 1");//DML语句System.out.println("sql语句执行完毕 影响记录数" + flag);//释放资源statement.close();connection.close();}

这是基本操作的几个步骤, 注册驱动 数据库连接 获取SQL语句执行对象 然后执行SQL 关流

在SQL语句,为了防止SQL注入,我们一般使用参数动态传递,也就是预编译SQL,不光可以防止SQL注入,而且性能更高,缓存会存储已编译的SQL语句。举个栗子

    @Testpublic void testSelect() {String url = "jdbc:mysql://localhost:3306/web01";String username = "root";String password = "123456";String sql = "SELECT id, username, password, name, age FROM user WHERE username = ? AND password = ?";// 用于存储查询结果的 User 列表List<User> userList = new ArrayList<>();// JDBC 连接和查询try (Connection connection = DriverManager.getConnection(url, username, password);PreparedStatement preparedStatement = connection.prepareStatement(sql)) {// 设置 SQL 参数preparedStatement.setString(1, "daqiao");preparedStatement.setString(2, "123456");// 执行查询try (ResultSet resultSet = preparedStatement.executeQuery()) {// 遍历结果集while (resultSet.next()) {// 将每一行数据封装到 User 对象中User user = new User();user.setId(resultSet.getInt("id"));user.setUsername(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));user.setName(resultSet.getString("name"));user.setAge(resultSet.getInt("age"));// 将 User 对象添加到列表userList.add(user);}}} catch (SQLException e) {e.printStackTrace();}// 输出查询结果for (User user : userList) {System.out.println(user);}}
  • JDBC程序执行DML语句:int rowsUpdated = pstmt.executeUpdate(); //返回值是影响的记录数

  • JDBC程序执行DQL语句:ResultSet resultSet = pstmt.executeQuery(); //返回值是查询结果集

MyBatis 

MyBatis是一款优秀的持久层框架,用于简化JDBC的开发,也就是之前提到的DAO层。通过Mybatis就可以大大简化原生的JDBC程序的代码编写。在pom文件中导入Mybatis依赖即可使用。

在java中对于数据库的数据,一般都使用对象进行封装。

配置

然后在java文件夹的resouse中有一个数据库的配置文件application.properties,用于配置数据库的连接信息

#数据库访问的url地址
spring.datasource.url=jdbc:mysql://localhost:3306/web
#数据库驱动类类名
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#访问数据库-用户名
spring.datasource.username=root
#访问数据库-密码
spring.datasource.password=root@1234
#mybatis的配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

但是遇到特别复杂的工程配置,一般使用application.yml进行配置 方便 直观 清晰

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl这条配置是查看SQL语句执行的日志信息

spring:application:name: springboot-mybatis-quickstart#配置数据库连接信息datasource:type: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://localhost:3306/web01driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:com.ght666.mapper/*.xml

编写

一般编写Mybatis程序 是在mapper包中编写Mybatis的持久层接口,定义SQL语句(注解)

package com.ght666.mapper;import com.ght666.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper//应用程序在运行时会自动的为该接口创建一个实现类对象,并且会自动将该实现类对象存入IOC容器 -bean对象
public interface UserMapper {@Select("select * from user")public List<User> findAll();
}
  • @Mapper注解:表示是mybatis中的Mapper接口

      程序运行时,框架会自动生成接口的实现类对象(代理对象),并给交Spring的IOC容器管理

  • @Select注解:代表的就是select查询,用于书写select查询语句

在创建出来的SpringBoot工程中,在src下的test目录下,已经自动帮我们创建好了测试类 ,并且在测试类上已经添加了注解 @SpringBootTest,代表该测试类已经与SpringBoot整合。

该测试类在运行时,会自动通过引导类加载Spring的环境(IOC容器)。我们要测试那个bean对象,就可以直接通过@Autowired注解直接将其注入进行,然后就可以测试了。

@SpringBootTest //springboot单元测试注解 当前测试类的测试方法运行时 会自动启动Springboot 产生IOC容器
class SpringbootMybatisQuickstartApplicationTests {@Autowiredprivate UserMapper userMapper;@Testpublic void testFindAll() {List<User> userList = userMapper.findAll();userList.forEach(System.out::println);//方法引用 }
}

 数据库连接池

数据库连接池是个容器,负责分配、管理数据库连接(Connection),程序在启动时,会在数据库连接池(容器)中,创建一定数量的Connection对象

允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个

客户端在执行SQL时,先从连接池中获取一个Connection对象,然后在执行SQL语句,SQL语句执行完之后,释放Connection时就会把Connection对象归还给连接池(Connection对象可以复用)

释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏,客户端获取到Connection对象了,但是Connection对象并没有去访问数据库(处于空闲),数据库连接池发现Connection对象的空闲时间 > 连接池中预设的最大空闲时间,此时数据库连接池就会自动释放掉这个连接对象

Spring默认连接池是Hikari(追光者),还有一个常用的是阿里巴巴开源的数据库连接池项目Druid

如果使用Druid连接池,先添加依赖,再在application配置文件中引入数据库连接配置

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

Mybatis占位符 

在Mybatis中,占位符是#{...} 生成的是预编译的SQL语句。例如:

/*** 根据id删除*/
@Delete("delete from user where id = #{id}")
public void deleteById(Integer id);
  • Mybatis的提供的符号,有两个,一个是 #{...},另一个是 ${...},区别如下

符号说明场景
#{…}占位符。执行时,会将#{…}替换为?,生成预编译SQL参数值传递
${…}拼接符。直接将参数拼接在SQL语句中,存在SQL注入问题表名、字段名动态设置时使用

补充一个点:有一个注解,@param,这个注解的作用是为接口的方法形参起名字的。(由于用户名唯一的,所以查询返回的结果最多只有一个,可以直接封装到一个对象中)举个栗子

/*** 根据用户名和密码查询用户信息*/
@Select("select * from user where username = #{username} and password = #{password}")
public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);

XML映射配置

Mybatis的开发有两种方式:注解  XML。使用Mybatis的注解方式,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件中。

XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名) 如果不同包同名,可以在配置文件中添加配置

mybatis:mapper-locations: classpath:com.ght666.mapper/*.xml

XML映射文件的namespace属性为Mapper接口全限定名,XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ght666.mapper.UserMapper"><!--查询操作--><select id="findAll" resultType="com.ght666.pojo.User">select * from user</select>
</mapper>

SpringBoot配置文件

主要就是yml配置文件的语法:

  1. 大小写敏感

  2. 数值前边必须有空格,作为分隔符

  3. 使用缩进表示层级关系,缩进时,不允许使用Tab键,只能用空格(idea中会自动将Tab转换为空格)

  4. 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

  5. #表示注释,从这个字符一直到行尾,都会被解析器忽略

yml文件中常见的数据格式。在这里我们主要介绍最为常见的两类:

  1. 定义对象或Map集合

  2. 定义数组、list或set集合

user:name: zhangsanage: 18password: 123456hobby: - java- game- sport

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

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

相关文章

Pytorch实现之SRGAN+CBAM的结构设计

简介 简介:在SRGAN的残差连接中加入了CBAM注意力机制,同时设计了四类损失来训练。 论文题目:Super-resolution Generative Adversarial Networks Based on Attention Model(基于注意力模型的超分辨率生成对抗网络) 会议:2020 IEEE第六届计算机与通信国际会议 摘要:基…

移动端国际化翻译同步解决方案-V3

1.前言 因为软件出海&#xff0c;从在上上家公司就开始做翻译系统&#xff0c;到目前为止已经出了两个比较大的版本了&#xff0c;各个版本解决的痛点如下&#xff1a; V1版本&#xff1a; 主要针对的是AndroidiOS翻译不一致和翻译内容管理麻烦的问题&#xff0c;通过这个工具…

2.css简介

什么是css&#xff1a; CSS (Cascading Style Sheets&#xff0c;层叠样式表&#xff09;&#xff0c;是一种用来为结构化文档&#xff08;如 HTML 文档或 XML 应用&#xff09;添加样式&#xff08;字体、间距和颜色等&#xff09;的计算机语言&#xff0c;CSS 文件扩展名为 .…

机器人学习模拟框架 robosuite (3) 机器人控制代码示例

Robosuite框架是一个用于机器人模拟和控制的强大工具&#xff0c;支持多种类型的机器人。 官方文档&#xff1a;Overview — robosuite 1.5 documentation 开源地址&#xff1a;https://github.com/ARISE-Initiative/robosuite 目录 1、通过键盘或SpaceMouse远程控制机器人…

可终身授权的外国工具,不限次数使用!PDF转CAD的软件

最近有不少朋友问我有没有好用的CAD转换工具&#xff0c;今天就来给大家分享两款超实用的小软件&#xff0c;希望能帮到大家。 第一款软件是一款国外开发的&#xff0c;它专门用来把PDF文件转换成CAD格式&#xff0c;特别方便。 这款软件的操作非常简单&#xff0c;打开后无需安…

Ubuntu系统上部署Node.js项目的完整流程

以下是在Ubuntu系统上部署Node.js项目的完整流程&#xff0c;分为系统初始化、环境配置、项目部署三个部分&#xff1a; 一、系统初始化 & 环境准备 bash # 1. 更新系统软件包 sudo apt update && sudo apt upgrade -y# 2. 安装基础工具 sudo apt install -y buil…

Android内存优化指南:从数据结构到5R法则的全面策略

目录 一、APP 内存限制 二、内存的三大问题 2.1、内存抖动(Memory Churn) 2.1.1 频繁创建短生命周期对象 2.1.2 系统API或第三方库的不合理使用 2.1.3 Handler使用不当 2.2、内存泄漏(Memory Leak) 2.2.1 静态变量持有Activity或Context引用 2.2.2 未取消的回调或…

ffmpeg源码编译支持cuda

1.安装cuda CUDA Toolkit 11.3 Downloads | NVIDIA Developer 在选择组件的时候&#xff0c;将CUDA中的Nsight VSE和Visual Studio Integration取消勾选 不然会安装失败 2.编译ffmpeg 把cuda编译宏定义开启&#xff0c;再编译avcodec 3.编译livavutil报错struct "Cuda…

Git强制覆盖分支:将任意分支完全恢复为main分支内容

Git强制覆盖分支&#xff1a;将任意分支完全恢复为main分支内容 场景背景完整操作步骤一、前置准备二、操作流程步骤 1&#xff1a;更新本地 main 分支步骤 2&#xff1a;强制重置目标分支步骤 3&#xff1a;强制推送至远程仓库 三、操作示意图 关键风险提示&#xff08;必读&a…

【Java反序列化测试】

Java反序列化测试 1. 识别反序列化入口点2. 构造探测Payload3. 发送Payload并观察结果4. 绕过可能的防护5. 自动化工具注意事项总结 Java反序列化测试&#xff1a; 1. 识别反序列化入口点 常见入口&#xff1a; HTTP请求参数&#xff08;如POST数据、Cookie、Headers&#xff…

golang的io

https://www.bilibili.com/list/BV1gx4y1r7xb 1. 原生io包 io包是Go语言标准库中底层的I/O接口层&#xff0c;定义了通用的读写规则和错误处理逻辑。每次读写都是直接调用底层系统 I/O&#xff0c;每次读取1字节&#xff0c;系统调用次数多。适用于小数据量、实时性要求高。io…

【北京迅为】iTOP-RK3568OpenHarmony系统南向驱动开发-第4章 UART基础知识

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

【计算机网络入门】初学计算机网络(十)(重要)

目录 1. 网络层的作用 2. IPV4 2.1 IP 数据报格式 2.2 IP地址分类方案 2.3 数据的转发 2.4 特殊用途的IP地址 3. 子网划分和子网掩码 3.1 子网划分 3.2 子网掩码 1. 网络层的作用 按照教学五层模型&#xff0c;应用层、传输层、网络层、数据链路层、物理层&#xff…

机器学习(五)

一&#xff0c;多类&#xff08;Multiclass&#xff09; 多类是指输出不止有两个输出标签&#xff0c;想要对多个种类进行分类。 Softmax回归算法&#xff1a; Softmax回归算法是Logistic回归在多类问题上的推广&#xff0c;和线性回归一样&#xff0c;将输入的特征与权重进行…

基于 Vue 和 SSM 的前后端分离项目实战:登录与注册功能实现

文章目录 前言项目概述前端部分&#xff08;Vue&#xff09;1. 项目初始化2. 页面布局Login.vueRegister.vue 3. 路由配置4. 主组件 后端部分&#xff08;SSM&#xff09;1. 项目结构2. 数据库设计3. MyBatis 配置4. DAO 层5. Service 层6. Controller 层7. 配置文件8. Spring …

Windows安装nvm【超详细图解】

目录 前言 一、NVM下载 方式一&#xff1a;官网下载 方式二&#xff1a;GitHub 下载 二、NVM安装 镜像源配置 三、Node安装 四、环境变量配置 前言 NVM&#xff08;Node Version Manager&#xff09;是一个命令行工具&#xff0c;用于在一台计算机上轻松管理和切换多…

KVM虚拟机磁盘创建探究-2

使用 virt-install 命令自动创建磁盘镜像和使用 qemu-img 手动创建磁盘镜像&#xff0c;在磁盘镜像本身格式和基本功能上是一致的&#xff0c;但在一些特性如初始占用磁盘空间、创建时的可配置性等方面存在区别&#xff0c;下面以 QCOW2 格式磁盘镜像为例进行详细说明。 初始占…

京准电钟:NTP校时服务器于安防监控系统应用方案

京准电钟&#xff1a;NTP校时服务器于安防监控系统应用方案 京准电钟&#xff1a;NTP校时服务器于安防监控系统应用方案 NTP校时服务器在安防监控系统中的应用方案主要通过高精度时间同步技术&#xff0c;解决设备间时间差异问题&#xff0c;确保日志、录像等数据的时间一致性…

递归遍历目录 和 普通文件的复制 [Java EE]

递归遍历目录 首先 先列出当前目录所包含的内容 File[] files currentDir.listFiles();if (files null || files.length 0) {// 若是空目录或非法目录, 则直接返回return;} 然后 遍历列出的文件, 分情况两种讨论 for (File f: files) {// 加个日志, 方便查看程序执行情…

NO.19十六届蓝桥杯模拟赛第三期上

1 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问&#xff0c; 2024 的最大的质因数是多少&#xff1f; 答&#xff1a;23 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false)…