Mybatis学习基础篇(一)——使用Maven快速搭建一个mybatis项目,并实现简单的增删改查

news/2024/3/29 19:15:20/文章来源:https://blog.csdn.net/qq_45922256/article/details/130346330

题外话:
在了解mybatis框架之前,我先说明一句,目前主流的框架技术层出不穷,每个人都有自己喜欢的技术框架,自己喜欢用就行。技术并没有高低之分,喜欢用就用,虽然目前大部分人都喜欢向新技术看齐,但是我个人觉得任何技术,都有他自己存在的意义,新的技术可以学,但旧技术我们也不能说他不行。

本文将带你使用java快速搭建一个MyBatis项目,并且实现简单的增删改查操作,动态增删改查将在本文第二篇

MyBatis框架介绍

Mybatis是一款优秀的持久层框架,它是一个基于Java语言的、开源的、轻量级的ORM框架,可以用于处理关系型数据库的操作。

Mybatis作为ORM框架,其内部封装JDBC,故而使得开发者只需要关注SQL本身,并不需要花费精力去加载驱动,创建链接,创建statement等繁琐的过程。

Mybatis的主要特点是灵活、简单、易于学习和使用。Mybatis的主要工作原理是将Java对象映射成数据库的记录,实现Java对象和数据库表之间的转换。Mybatis的核心组件包括SqlSessionFactory、SqlSession、Mapper和MappedStatement。

  1. SqlSessionFactory
    SqlSessionFactory是用于创建SqlSession对象的工厂类。SqlSession对象是Mybatis中最重要的核心类之一,它是一个线程安全的、非常轻量级的对象,用于执行数据库操作和管理事务。SqlSessionFactory通常通过Mybatis的配置文件进行配置,可以指定数据源、事务管理器和Mapper映射文件等信息。

  2. SqlSession
    SqlSession是一个线程安全的、非常轻量级的对象,用于执行数据库操作和管理事务。SqlSession提供了多种操作数据库的方法,包括查询、插入、更新和删除等,还可以设置事务的隔离级别和自动提交等。

  3. Mapper
    Mapper是一个Java接口,用于定义SQL语句的执行方法。Mapper接口中的方法与SQL语句是一一对应的,可以通过SqlSession的getMapper方法获取Mapper接口的实例,并调用其中的方法执行SQL语句。

  4. MappedStatement
    MappedStatement是一个Java对象,用于描述Mapper接口中的SQL语句和参数信息。MappedStatement包括SQL语句的ID、SQL语句的类型、输入参数和输出参数等信息。

Mybatis的主要优点是:

  1. 灵活性高:Mybatis的配置文件非常灵活,可以使用XML或注解进行配置,支持自定义标签和属性,可以灵活地进行SQL语句的编写和调优。

  2. 易于学习和使用:Mybatis的API非常简单,容易学习和使用,开发人员可以快速上手,快速实现对数据库的操作。

  3. 易于维护和调试:Mybatis的映射文件和Java代码是分离的,容易维护和调试,开发人员可以很方便地对SQL语句进行调优和修改,提高SQL语句的执行效率。

  4. 易于扩展和定制化:Mybatis的插件机制非常强大,可以对SQL语句进行拦截和修改,也可以自定义类型处理器和结果集处理器,实现对特定数据类型的处理和转换。

  5. 良好的性能和扩展性:Mybatis采用了基于XML的配置方式和基于Java的Mapper接口,可以实现动态SQL语句的生成和优化,同时也支持多数据源和分布式数据库的操作,具有良好的性能和扩展性。

总之,Mybatis是一款优秀的持久层框架,它具有灵活性高、易于学习和使用、易于维护和调试、易于扩展和定制化、良好的性能和扩展性等优点,被广泛应用于Java企业级应用中的数据持久化层。

我的文件目录结构:
在这里插入图片描述
文件目录结构摆上了,如果跟着我的步骤下来的出现问题,我觉得是你的目录结构出问题了。

简单介绍完了,开始重头戏

第一步,先拿到数据库,这里提供一个实例数据库:

create database if not exists MyBatis_stu default character set utf8 collate utf8_bin; use MyBatis_stu ;create table if not exists classinfo(cid int primary key auto_increment,cname varchar(100) not null unique comment '班级编号' 
)ENGINE=InnoDB auto_increment=101 default charset=utf8 collate=utf8_bin;create table if not exists stuinfo (sid int primary key auto_increment,sname varchar(100) not null comment '学生姓名',cid int comment '所在班级编号',tel varchar(15) unique comment '联系方式',addr varchar(100) comment '家庭住址',constraint FK_stuinfo_cid foreign key(cid) references classinfo(cid)
)ENGINE=InnoDB auto_increment=101 default charset=utf8 collate=utf8_bin;

这一步,我觉得不要多说了,毕竟你学java到现在,这一步还是没看懂的话,我觉得你可以准备考虑考虑其他路了。

第二步前台条件,你要创建好一个maven项目,并导入相关依赖,别告诉我你忘记了maven工程如何创建了?

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xh</groupId><artifactId>Maven</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>Maven</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--导入maven链接,让maven去下载https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.8</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.17.2</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency></dependencies>
</project>

第二步,根据我们的数据库创建Bean类,什么?你告诉我你不知道什么事Bean类?额,你该恶补一下java了。

public class ClassInfo {private Integer cid;private String cname;public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getCname() {return cname;}public void setCname(String cname) {this.cname = cname;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((cid == null) ? 0 : cid.hashCode());result = prime * result + ((cname == null) ? 0 : cname.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;ClassInfo other = (ClassInfo) obj;if (cid == null) {if (other.cid != null)return false;} else if (!cid.equals(other.cid))return false;if (cname == null) {if (other.cname != null)return false;} else if (!cname.equals(other.cname))return false;return true;}@Overridepublic String toString() {return "ClassInfo [cid=" + cid + ", cname=" + cname + "]";}//记得这里我的需要创建的构造方法,你可以选择跟我也可以选择不跟public ClassInfo( String cname) {this.cname = cname;}public ClassInfo(Integer cid, String cname) {super();this.cid = cid;this.cname = cname;}public ClassInfo() {super();}
}

注意,这个类,我实际上在本篇没用上,我会在下篇才用到,你可以自行选择创建或者不创建

public class StudentInfo {private Integer sid;//学生idprivate String sname;//学生姓名private Integer cid; //外键管理,类idprivate String tel; //电话号码private String addr;//地址public Integer getSid() {return sid;}public void setSid(Integer sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getTel() {return tel;}public void setTel(String tel) {this.tel = tel;}public String getAddr() {return addr;}public void setAddr(String addr) {this.addr = addr;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((addr == null) ? 0 : addr.hashCode());result = prime * result + ((cid == null) ? 0 : cid.hashCode());result = prime * result + ((sid == null) ? 0 : sid.hashCode());result = prime * result + ((sname == null) ? 0 : sname.hashCode());result = prime * result + ((tel == null) ? 0 : tel.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;StudentInfo other = (StudentInfo) obj;if (addr == null) {if (other.addr != null)return false;} else if (!addr.equals(other.addr))return false;if (cid == null) {if (other.cid != null)return false;} else if (!cid.equals(other.cid))return false;if (sid == null) {if (other.sid != null)return false;} else if (!sid.equals(other.sid))return false;if (sname == null) {if (other.sname != null)return false;} else if (!sname.equals(other.sname))return false;if (tel == null) {if (other.tel != null)return false;} else if (!tel.equals(other.tel))return false;return true;}@Overridepublic String toString() {return "StudentInfo [sid=" + sid + ", sname=" + sname + ", cid=" + cid + ", tel=" + tel + ", addr=" + addr+ "]";}public StudentInfo(Integer sid, String sname, Integer cid, String tel, String addr) {super();this.sid = sid;this.sname = sname;this.cid = cid;this.tel = tel;this.addr = addr;}public StudentInfo() {super();}
}

第三步,我们要准备数据库配置文件

这个自行确定,账号密码请你更改为自己安装数据库的账号密码,我给出我的实例db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis_stu?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useOldAliasMetadataBehavior=true
username=root
password=123456

第四步,创建mybatis配置文件

有了上边三步的基础之后,我们需要配置mybatis-config.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><!-- 引入配置文件 请好好的看我  我是db.properties --><properties resource="db.properties"></properties><!-- 配置环境变量 development :开发环境 work :工作环境 --><environments default="development"><environment id="development"><!-- 事务管理 --><transactionManager type="JDBC" /><!-- 配置数据库连接信息 POOLED UNPOOLED --><dataSource type="POOLED"><property name="driver" value="${driver}" /><property name="url" value="${url}" /><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment></environments><mappers><!-- 加载mapper指向位置 --><mapper resource="mapper/ClassInfoMapper.xml" /><mapper resource="mapper/StudentInfoMapper.xml"></mapper></mappers></configuration>

至此,第四步就完成。

第五步,配置映射

我想说的这上面的每一步都很重要,但是这一步也很重要,我们将相关SQL语句全部写在这里,这一步,我们其实可以说是直接对数据库进行操作,我的理解是这样的,但是不同的人有不同的理解,我也不能去把我的思想强加给别人,对吧?

对了,如果你是初学者,我推荐你了解一下我在本项目的注释
ClassInfoMapper.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace :命名空间 ,就是用来避免命名冲突的,同一个命名空间下面都不能出现相同的id时间上这个就是指向 "ClassInfo.findAll" 测试类的这个属性的ClassInfo代表命名空间,findAll代表id-->
<mapper namespace="ClassInfo">  <!-- 写insert delete update select 语句 每一个语句都有一个id,到时候通过命名空间.id 来获取对应的sql语句执行 通过paramenterType 属性来指定这个sql执行语句的参数 通过resultType属性指定这个sql语句后返回值的类型,是每条结果对应的类型 --><select id="findAll" resultType="com.xh.mybatis.bean.ClassInfo">select cid,cname from classinfo;</select><!-- 假设我们要查询某单一的字段,我们需要的操作是如下 --><select id="find" resultType="com.xh.mybatis.bean.ClassInfo">select cid,cname from classinfowhere cname=#{cname};</select><insert id="add" parameterType="com.xh.mybatis.bean.ClassInfo"><!--#{} 采用预编译的方式 ${} 采用字符串拼接的方法 -->insert into classinfo values(0,#{cname});</insert><!-- 模糊查询 vague '%${parameters}%' %#{parameters}%此时这个语句是有问题的,不能这么写 应该是 '%#{parameters}%' _${parameters}这种模糊查询也是可以的,但是没有%那么灵活,不过你觉得你使用哪个舒服就使用哪个 --><select id="findByVague"resultType="com.xh.mybatis.bean.ClassInfo">select cid,cname from classinfo where cname like'_${parameters}';</select><!--更新表中的数据 --><update id="update"parameterType="com.xh.mybatis.bean.ClassInfo">update classinfo set cname = #{cname} where cid =#{cid};</update><!-- 删除表中的数据 --><delete id="delete"parameterType="com.xh.mybatis.bean.ClassInfo">delete from classinfo where cid = #{cid};</delete>
</mapper>

另一个文件StudentInfoMapper.xml我不会在本篇使用,故而我不在本篇展示,如果你感兴趣的话,请查看下篇。

第六步,测试类的编写

package com.xh.mybatis;import java.io.IOException;
import java.io.InputStream;import java.util.List;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;import com.xh.mybatis.bean.ClassInfo;public class MyTest {/*** classinfo中的所有的值* @throws IOException*/@Testpublic void test1() throws IOException {try (InputStream reader = Resources.getResourceAsStream("mybatis-config.xml")){//创建sqlSession工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);System.out.println("-----------");//从sqlsession工厂中获取一个sql会话SqlSession sqlSession = sqlSessionFactory.openSession();//通过这个回话执行与sql语句 //将从表中查询的多条数据以作为对象的方式添加到list中List<ClassInfo> cls = sqlSession.selectList("ClassInfo.findAll");//遍历list中的所有的值cls.forEach(System.out::println);sqlSession.close();}}/*** 在classinfo表中添加值 ,非动态添加* @throws IOException*/@Testpublic void test2() throws IOException {try (InputStream reader = Resources.getResourceAsStream("mybatis-config.xml")){//创建sqlSession工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);SqlSession sqlSession = sqlSessionFactory.openSession();//通过这个回话执行与sql语句,      /*** 这里的new ClassInfo对象是由于我们创建的表是主键存在主键自增,故而在构造方法中不需要添加cid* 我们可以选择几种方式,这边我们对构造方法可以进行多种构造,让构造方法去选择添加,也可以直接用全部构造* 不够就是我们需要对构造方法进行置空处理*/int result = sqlSession.insert("ClassInfo.add",new ClassInfo("相关"));System.out.println(result);sqlSession.commit();sqlSession.close();}}/*** ClassInfo表中* mybatis查询某数据库中某个值* @throws IOException*/@Testpublic void test3() throws IOException {InputStream reader = Resources.getResourceAsStream("mybatis-config.xml");//创建SqlSession工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);SqlSession sqlSession = sqlSessionFactory.openSession();//我们可以查看到当前查到的对象可以被查出来//ClassInfo obj = sqlSession.selectOne("ClassInfo.find",new ClassInfo("四班"));//ClassInfo.find表示调用Mybatis中的com.xh.bean.ClassInfo下的id=find的sql语句//如果我们使用的是MVC架构进行开发,这个语句应该是属于serviceImpl层调用dao接口的时候ClassInfo obj = sqlSession.selectOne("ClassInfo.find","四班");//查找单个//int result = sqlSession.selectOne("Classinfo.find","四班");System.out.println(obj);sqlSession.commit();sqlSession.close();}/*** 使用模糊查询classInfo中的数据* 没做动态查询* @throws IOException */@Testpublic void test4() throws IOException {InputStream reader = Resources.getResourceAsStream("mybatis-config.xml");//创建sqlSession工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);System.out.println("-----------");//从sqlsession工厂中获取一个sql会话SqlSession sqlSession = sqlSessionFactory.openSession();//通过这个回话执行与sql语句 //将从表中查询的多条数据以作为对象的方式添加到list中List<ClassInfo> cls = sqlSession.selectList("ClassInfo.findByVague","班");//遍历list中的所有的值cls.forEach(System.out::println);sqlSession.commit();sqlSession.close();}/*** 更新表中数据,先从简单的开始,ClassInfo表中的数据* @throws IOException*/@Testpublic void test5() throws IOException {InputStream reader = Resources.getResourceAsStream("mybatis-config.xml");//创建sqlSession工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);System.out.println("-----------");//从sqlsession工厂中获取一个sql会话SqlSession sqlSession = sqlSessionFactory.openSession();//通过这个回话执行与sql语句 //将从表中查询的多条数据以作为对象的方式添加到list中ClassInfo obj = new ClassInfo();obj.setCid(1);obj.setCname("一班");int result = sqlSession.update("ClassInfo.update",obj);if(result > 0) {System.out.println("更新成功");}else {System.out.println("更新失败");}List<ClassInfo> cls = sqlSession.selectList("ClassInfo.findAll");//遍历list中的所有的值cls.forEach(System.out::println);//注意在开启事务的情况下,你不提交数据库是查不到值的sqlSession.commit();sqlSession.close();}/*** 删除* @throws IOException */@Testpublic void test6() throws IOException {InputStream reader = Resources.getResourceAsStream("mybatis-config.xml");//创建sqlSession工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);//从sqlsession工厂中获取一个sql会话SqlSession sqlSession = sqlSessionFactory.openSession();List<ClassInfo> cls = sqlSession.selectList("ClassInfo.findAll");System.out.println("删除之前的数据");cls.forEach(System.out::println);/** ClassInfo obj = new ClassInfo(); obj.setCid(7);*/int result = sqlSession.delete("ClassInfo.delete",8);if(result > 0) {System.out.println("删除成功");}else {System.out.println("删除失败");}//注意在开启事务的情况下,你不提交数据库是查不到值的sqlSession.commit();System.out.println("删除之后的数据");List<ClassInfo> cls1 = sqlSession.selectList("ClassInfo.findAll");//遍历list中的所有的值cls1.forEach(System.out::println);sqlSession.close();}//至此,上边对mybatis的简单操作到此结束
}

至此,我们搭建简单的Mybatis项目就完成了,如果您觉得本文不错的话,请你对本文点一下点赞或者收藏,或者一键三连。您的鼓励将是我最大的动力

mybatis 注意事项:

#{} 和 ${} 的区别

注意:#{}是预编译处理,${}是字符替换

注意:#{}会在mybatis运行的过程中替换为?,调用PreparedStatement的set方法来赋值。

mybatis 在处理$()会将他替换为变量的值。

多使用#{}可以防止sql注入,提高系统安全性。

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

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

相关文章

C++、STL标准模板库和泛型编程 ——迭代器、 算法、仿函数(侯捷)

C、STL标准模板库和泛型编程 ——迭代器、 算法、仿函数 &#xff08;侯捷&#xff09; 迭代器iterator_category 算法accumulatefor_eachreplacecountfindsortbinary_search 仿函数 functors(六大部件中最简单的一种&#xff01;) 使用一个东西&#xff0c;却不明白它的道理&a…

4月21日第壹简报,星期五,农历三月初二

4月21日第壹简报&#xff0c;星期五&#xff0c;农历三月初二坚持阅读&#xff0c;静待花开1. 推特拒向大模型免费开放数据&#xff01;马斯克威胁起诉微软&#xff1b;Reddit宣布不再向大模型免费开放数据&#xff0c;要求科技巨头付费使用API接口。2. 浙江&#xff1a;鼓励杭…

2023.04.24 c++第六讲

作业&#xff1a; 1. 手动实现顺序栈&#xff0c;要求实现数据结构中&#xff0c;所有栈的相关操作 #include <iostream> #define MAXSIZE 20 //宏定义&#xff0c;栈的最大容量 using namespace std;template <typename T> class stacklink { pri…

FBEC大会 | 瑞云科技 CTO 赵志杰:元宇宙时代的基础设施——实时云渲染

​ FBEC未来商业生态链接大会于2023年2月24日在深圳福田大中华喜来登酒店盛大召开&#xff0c;本次大会由广东省游戏产业协会、深圳市互联网文化市场协会指导&#xff0c;陀螺科技主办。 大会以“勇毅前行逐光而上”为主题&#xff0c;以具有行业前瞻洞察的“探索者”为视角&a…

Three.js+TypeScript+Webpack学习记录(二)

使用环境参考 Node.js v16.19.1 正文 跟着文档画个线 看看 Three 的官方文档&#xff0c;起步 -> 画线 -> 没了&#xff1f;&#xff01;&#xff01; 不管怎么说&#xff0c;先画个线吧。 import * as THREE from threeconst scene new THREE.Scene() const camer…

PyTorch深度学习实战 | 基于深度学习的电影票房预测研究

基于深度学习的映前票房预测模型(Cross&Dense网络结构模型)&#xff0c;该模型通过影片基本信息如&#xff1a;电影类型、影片制式、档期和电影的主创阵容和IP特征等信息对上映影片的票房进行预测。 本篇采用451部电影作为训练模型&#xff0c;最后再在194部影片上进行测试…

【计网 从头自己构建协议】一、libpcap 介绍 手撕以太网帧

上一篇&#xff1a;IndexError: list index out of range 下一篇&#xff1a;[【计网 从头自己构建协议】二、收发 ARP 请求帧与响应帧] 介绍 理论的学习总是枯燥的&#xff0c;想要加深对理论的理解&#xff0c;最好的方法就是自己实践一遍。 想要亲手实现各种协议&#xf…

【音视频第17天】RTSP、RTMP协议初识

被叫去搞直播了&#xff0c;悲喜交加。先学习一下基本的技术栈&#xff0c;RTSP RTMP HTTP 先简单随便看看吧。 目录 什么是流媒体协议RTMPRTMP 工作原理 RTSPRTSP 工作原理 RTMP 与 RTSP 区别详细看看RTSP简介RTSP交互流程OPTIONSDESCRIBESETUPPLAYPAUSESET_PARAMETERGET_PAR…

春招,进阿里了....

个人背景是东北某 985 科班本硕&#xff0c;做的 测试开发&#xff0c;有两个自己写的小项目。下面是一些印象比较深刻的面试题 阿里一面 什么是软件测试&#xff1f; 软件测试过程中会面向哪些群体&#xff1f; 开发一个软件都要经过哪些阶段&#xff1f; 什么是黑盒测试&…

八年软件测试生涯,是时候做出改变了

五年前&#xff0c;我在南方的大城市&#xff1a;广州&#xff0c;做着一个快乐的游戏测试&#xff0c;工作不太忙&#xff0c;对一切技术充满了好奇心。测试工作不专业&#xff0c;也不受重视。但我有自己的快乐。工作不忙的时候&#xff0c;我今天学学Python&#xff0c;明天…

什么是客户服务平台?

在社交媒体和智能手机出现之前&#xff0c;品牌主要通过单向广告渠道与客户互动。社交媒体打破了这种自上而下的动态&#xff0c;以前所未有的方式打开了对话&#xff0c;将客户包括在内。 品牌不再控制客户对人们分享公司内容的行为。人们可以点击离开&#xff0c;向左滑动&a…

Python-pyppeteer解决微软Microsoft的登录机器人验证(8)

前言 本文是该专栏的第8篇,结合优质项目案例,让你精通使用Pyppeteer,后面会持续分享Pyppeteer的干货知识,记得关注。 在注册微软Microsoft账号或者注册outlook邮箱账号的时候,会遇到如下机器人验证: 是的,你可能第一眼看到这个验证页面,首先会想到是定位它的页面元素N…

非常详细的阻抗测试基础知识

编者注&#xff1a;为什么要测量阻抗呢&#xff1f;阻抗能代表什么&#xff1f;阻抗测量的注意事项... ...很多人可能会带着一系列的问题来阅读本文。不管是数字电路工程师还是射频工程师&#xff0c;都在关注各类器件的阻抗&#xff0c;本文非常值得一读。全文13000多字&#…

Vue CLI 服务

使用命令 在一个 Vue CLI 项目中&#xff0c;vue/cli-service 安装了一个名为 vue-cli-service 的命令。你可以在 npm scripts 中以 vue-cli-service、或者从终端中以 ./node_modules/.bin/vue-cli-service 访问这个命令。 这是你使用默认 preset 的项目的 package.json&…

电脑突然变成绿屏错误代码无法使用怎么办?

电脑突然变成绿屏错误代码无法使用怎么办&#xff1f;有用户使用电脑的时候&#xff0c;电脑桌面变成了绿屏的显示&#xff0c;所有的操作无法继续进行。遇到这个问题要怎么去进行解决呢&#xff1f;来看看详细的解决方法教学吧。 准备工作&#xff1a; 1、U盘一个&#xff08;…

(原创)Flutter基础入门:手把手教你搭建Flutter混合项目

前言 Flutter是Google开源的构建用户界面&#xff08;UI&#xff09;工具包 支持在不同平台构建一致的ui效果 但在实际业务中&#xff0c;一般不会整个APP都用纯Flutter开发 尤其一些老的项目&#xff0c;会采用接入Flutter的方式来混合开发 那么今天就主要讲一下如何搭建一个…

SQLServer:Win/Linux环境安装及一键部署脚本

1. Win安装SQLServer CSDN已有完整安装流程&#xff0c;亲测可用。----》Windows安装SQLServer流程 2. Linux安装 SQLServer 2.1 设置镜像 curl https://packages.microsoft.com/config/rhel/7/mssql-server-2017.repo > /etc/yum.repos.d/mssql-server.repo 2.2 通过y…

深度学习模型参数量与训练数据量的平衡对泛化性能的影响

一、引言 深度学习模型在计算机视觉、自然语言处理等领域取得了显著的成果。为了获得泛化性能良好的模型&#xff0c;研究者需要在模型复杂度和训练数据量之间找到合适的平衡。本文将探讨这两者之间的关系以及如何在实际应用中实现最佳效果。 二、模型复杂度与训练数据量的关…

史上最严宝宝口粮新国标出台,DHA和维生素D可能无需额外补充了

自2023年2月22日起&#xff0c;我国婴幼儿配方食品&#xff08;以下简称配方奶&#xff09;新国标开始实施。这意味着2023年2月22日以后在中国上架销售的配方奶必须符合新国标&#xff0c;重新取得国家市场监督管理总局食品评审中心&#xff08;CFE-SAMR&#xff09;的注册。这…