Mybatis入门の基础操作

1 Mybatis概述
在这里插入图片描述

   MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。 mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。 采用ORM思想解决了实体和数据库映射的问题,对jdbc进行了封装,屏蔽了jdbc api底层访问细节,使我们不用与jdbc api打交道,就可以完成对数据库的持久化操作。

mybatis技术曾经做过“更名”,早期这个团队将技术框架称为“iBatis",mybatis研发团队”跳槽“google,从google跳”githup",将之前“ibatis"改为”mybaits"

mybatis中文网站:https://mybatis.net.cn/

2 mybatis框架技术定位

SSM框架与三层架构对应关系: Java提供JDBC,Spring提供SpringJdbc,mybatis
在这里插入图片描述

3 Mybatis的优势:传统jdbc存在的问题

在这里插入图片描述

JDBC操作步骤:

1、注册驱动:Class.forName(“com.mysql.jdbc.Driver”)2、获取连接:Connection connection=DriverManager.getConnection(url,username,password);3、获取预处理对象:PreparedStatement pstm=connection.PreparedStatement(“sql”);4、执行sql操作:Result result=pstm.ExecuteQuery();/pstm.ExecuteReader().5、封装结果集:While(result.next()){……}6、释放资源:Result.close();  Pstm.close();  Connection.close();

分析:如果我们要在mysql中查询一个内容应该怎样操作才能得到结果?在mysql中我们只需要编写出相应的sql语句即可,但是在jdbc中除了编写sql语句外还要做很多额外的工作才能得到结果。能不能只编写sql语句其余工作不再去关注呢?这就是mybatis的作用,我们唯一要做的就是思考怎样去编写高效的sql语句。

4 Mybatisの入门案例

创建maven控制台程序,按照以下步骤完成mybatis开发环境搭建工作:

  • pom.xml 导入mybatis依赖
<!-- mybatis依赖-->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version>
</dependency>
<!-- 数据库驱动-->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version>
</dependency>
  • 项目中引入数据库配置文件:db.properties
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/bookstore?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=root
  • 添加mybatis核心配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--加载数据库配置信息的文件:db.propertiesproperties:读取classpath下面的配置文件,所以不用写classpath--><properties resource="db.properties"/>
<!--
配置数据库连接信息:从配置文件读取对应的key的值
--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments>
</configuration>

mybatis-confg.xml是mybatis的核心配置文件,该文件中要配置哪些东西呢:即基本的sql语句执行环境需要的就是数据驱动类型、数据库服务器地址、数据库服务器登录账号及密码。

  • 测试代码
  • public class Tester {@Testpublic void test01()throws  Exception{//1.读取配置文件,构建mybatis核心执行对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession可以理解为Connection,此行代码的意思就是:读取配置文件获取数据库连接的工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂获取数据库连接对象SqlSession session = sqlSessionFactory.openSession();System.out.println(session);}
    }
    

5 Mybatis的CRUD操作

准备工作

确定要操作的数据库和数据表后,按照持久层dao开发流程,完成代码准备:

创建Notice实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Notice {private Integer id;private String title;private String content;private Integer employeeId;//jdk1.8新增日期格式:LocalDateTime对象中包含:年月日时分秒组成private LocalDateTime createTime;
}

为表创建对应的dao接口:NoticeDao.java

/*** mybatis接口不再提供实现类,取而代之使用xml配置文件完成代码执行,* xml文件主要作用:写sql,成为sql映射文件* sql映射文件要求:文件名必须和接口同名,单词一模一样;文件存放位置和接口所在包一样*/
public interface NoticeDao {/*** 查询所有的帖子信息*/List<Notice> selectAll();
}

为NoticeDao接口创建SQL映射文件:NoticeDao.xml

mybatis中规定dao只是用来声明方法的接口类,接口中方法的实现由mapper.xml映射文wrh来实现(sql语句)。

<?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:sql映射文件.作用:配置sql语句namespace:命名空间,理解包 设置当前sql映射文件是对应哪个接口文件,填写接口包名.类名
-->
<mapper namespace="com.woniu.dao.NoticeDao"><select id="" resultType=""></select>
</mapper>

注意:mapper.xml映射文件须和dao接口在同一包中且名称相同。创建好的文件目录如下图所示:

案例一:查询所有公告信息

修改NoticeDao.xml映射文件:为查询方法配置对应的sql语句

注意:使用mapper代理开发时不用为dao接口编写实现类,但是在mapper.xml文件中的mapper节点中的namespace必须指定与同名接口类的全限定名

<!--
id:指定sql为接口里面哪个方法提供的。id设置方法:方法名
resultType:方法返回值类型,如果方法返回值类型是集合,只需要填写集合泛型类型即可指定类型时:必须使用全路径:包名.类名
-->
<select id="selectAll" resultType="com.woniu.entity.Notice">SELECT id,title,content,employeeId,createtime from wy_notice
</select>

属性说明:

 id: 设置要实现的方法名称resultType: 方法返回值类型,如果返回值是集合类型,写集合的泛型类型。鉴于之前使用JdbcTemplate执行sql的经验,我们可以这么理解resultType:resultType提供类型用于完成查询结果与实体类映射关系,默认情况:entity定义属性时属性名和表列名单词一样的。

注意:使用mapper代理开发时mapper.xml中sql节点的id值必须与dao接口中的方法名称一致

		resultType属性的值必须与dao接口中方法的返回值类型一致

核心配置文件中注册Sql映射文件:NoticeDao.xml

 每一个mapper.xml映射文件要能正确被程序解析到,还要在mybatis核心配置文件中进行注册<mappers><mapper resource="com/woniu/dao/NoticeDao.xml"/>
</mappers>resource读取的是classpath下的文件url地址,所以此处写的是xml的路径,不是接口的包名

常见异常:

如果没有在核心配置文件中“注册”sql映射文件,执行代码时通常会提示以下异常:

测试代码

@Test
public void test01()throws  Exception{//1.读取配置文件,构建mybatis核心执行对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession可以理解为Connection,此行代码的意思就是:读取配置文件获取数据库连接的工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂获取数据库连接对象SqlSession session = sqlSessionFactory.openSession();System.out.println(session);//执行sql语句了 重点,mapper其实就是依靠jdk代理为接口生成实现类NoticeDao noticeDaoImpl = sqlSession.getMapper(NoticeDao.class);//com.sun.proxy.$Proxy6 基于jdk代理,获取接口对应的实现类System.out.println(noticeDaoImpl.getClass());List<Notice> notices = noticeDaoImpl.selectAll();notices.forEach(System.out::println);
}

观察以上输出结果,我们不难发现,mybatis的底层其实是利用JDK代理完成了dao接口对应实现类的动态生成。我们之前学过JDK代理的知识,我们可以这么理解

所以,在mybatis 框架中它将“通用且重复”的sql执行过程在程序运行过程中,动态增强到xml配置的sql语句前后。简化了程序员持久层开发工作的负担和繁复。

案例二:DML操作の添加公告信息

修改NoticeDao.xml映射文件:为insert方法配置对应的sql语句

注意:使用mapper代理开发时不用为dao接口编写实现类,但是在mapper.xml文件中的mapper节点中的namespace必须指定与同名接口类的全限定名

<insert id="insert">insert wy_notice values(null,'测试数据','测试数据内容',1,now())
</insert>

属性说明:

 id: 设置要实现的方法名称insert配置新增语句,该标签一般只需要配置id即可因为insert没有查询结果集,所以insert标签也就没有resultType属性了

测试代码

@Test
public void testInsert()throws IOException{//1.获取SqlSessionString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession(true);//2.基于jdk代理,获取要测试接口对应的实现类NoticeDao noticeDaoImpl = sqlSession.getMapper(NoticeDao.class);int insert = noticeDaoImpl.insert(null);System.out.println("insert语句执行后,受影响的行数:" + insert);
}

添加代码执行成功后,数据库数据并没有新增的问题:

测试结果暗示的意思是数据添加成功,我们去刷新mysql数据库,观察发现并没有出现”测试数据“这条新增数据,why???

真相是:mybatis在openSession()时,默认开启了事务手动提交模式,所以在没有代码明确写明“commit()"的情况下,程序操作的结果不会物理更新到数据表中。

解决方案如下:

方案一:手动提交事务

@Test
public void test01()throws  Exception{//1.读取配置文件,构建mybatis核心执行对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession可以理解为Connection,此行代码的意思就是:读取配置文件获取数据库连接的工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂获取数据库连接对象,SqlSession默认配置:事务手动提交,如果openSession(true)设置事务自动提交SqlSession session = sqlSessionFactory.openSession();       //sql执行:获取UserDao接口的代理对象,NoticeDao noticeDaoImpl = session.getMapper(NoticeDao.class);int i = noticeDaoImpl.insert(null);System.out.println("新增方法执行结果是:" + i);//提交事务session.commit();//释放资源session.close();
}

方案二:开启事务自动提交模式

@Test
public void test01()throws  Exception{//1.读取配置文件,构建mybatis核心执行对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession可以理解为Connection,此行代码的意思就是:读取配置文件获取数据库连接的工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂获取数据库连接对象,SqlSession默认配置:事务手动提交,如果openSession(true)设置事务自动提交SqlSession session = sqlSessionFactory.openSession(true);       //sql执行:获取UserDao接口的代理对象,NoticeDao noticeDaoImpl = session.getMapper(NoticeDao.class);int i = noticeDaoImpl.insert(null);System.out.println("新增方法执行结果是:" + i);//释放资源session.close();
}

扩展补充:SqlSession释放资源的问题

SqlSession使用完毕后,也是要释放数据库资源的,所以此处如果想不写“session.close()“,可以借助JDK1.8中try-catch的新语法,代码如下所示:

@Testpublic void test01()throws  Exception{//1.读取配置文件,构建mybatis核心执行对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession可以理解为Connection,此行代码的意思就是:读取配置文件获取数据库连接的工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂获取数据库连接对象,SqlSession默认配置:事务手动提交,如果openSession(true)设置事务自动提交try(SqlSession session = sqlSessionFactory.openSession(true);) {//sql执行:获取UserDao接口的代理对象,NoticeDao noticeDaoImpl = session.getMapper(NoticeDao.class);int i = noticeDaoImpl.insert(null);System.out.println("新增方法执行结果是:" + i);}}

6 日志框架 logback

模仿日志输出,日志将程序执行过程,执行了什么sql,带入什么参数,执行的是什么结果,执行出现问题具体描述信息…

作用:日志框架增强程序员跟踪程序执行过程,对于发生一些程序问题,更好进行定位、分析。

日志框架选择:Springboot内置日志框架:logback

logback使用步骤

  • pom.xml导入logback的依赖:整个日志框架需要导入三个依赖:logback-classic、logback-core、slf4j-api

  • <!-- 日志框架 -->
    <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version>
    </dependency>
    <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.2.3</version>
    </dependency>
    <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version>
    </dependency>
    
  • 项目引入自己的日志配置文件:logback.xml

  • <configuration debug="false"><!-- appender配置输出的位置和输出日志格式CONSOLE:控制台--><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%5p | %-40.40logger{39}  :%m%n</pattern><charset>utf8</charset></encoder></appender><!-- 了解日志信息输出的级别:TRACE < DEBUG < INFO < WARN < ERROR配置哪些日志在控制台输出,可以通过设置不同的日志级别控制日志级别的输出原则:设置级别时,会输出当前设置级别的日志以及比当前更高级别的日志--><!--
    logger:特定设置,属性
    name:特定配置针对的包名,酌情修改
    level:DEBUG
    additivity:覆盖默认配置
    --><logger name="com.woniu" level="DEBUG" additivity="false"><appender-ref ref="CONSOLE"/></logger>
    <!--
    root:基础配置,level:info
    --><root level="INFO"><appender-ref ref="CONSOLE" /></root>
    </configuration>
    
  • 自己使用log对象输出日志信息

  • @Slf4j //引入日志管理器
    public class xxx{@Testpublic void test00(){String str="helloworld";//观察控制台能否输出对应的信息:信息是否可以输出与logback.xml配置的级别有关系log.trace("trace str{}",str);log.debug("debug str{}",str);log.info("info str{}",str);log.warn("warn str{}",str);log.error("error str{}",str);}
    }
    

按照步骤配置好日志框架后,重新启动上面案例的测试代码,就可以在控制台看到sql的输出信息了。

7 mybatis中#{}和${}设置sql参数对比

案例:根据id查询用户信息

修改UserDao.xml中配置:使用${}带入参数

 <select id="selectById" resultType="com.woniu.entity.Users">select * from wy_employee where id=${id}</select>

执行测试方法

@Test
public void test01()throws  Exception{//1.读取配置文件,构建mybatis核心执行对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession可以理解为Connection,此行代码的意思就是:读取配置文件获取数据库连接的工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂获取数据库连接对象,SqlSession默认配置:事务手动提交,如果openSession(true)设置事务自动提交try(SqlSession session = sqlSessionFactory.openSession(true);) {System.out.println(session);//sql执行:获取UserDao接口的代理对象,UsersDao usersDaoImpl = session.getMapper(UsersDao.class);System.out.println(usersDaoImpl.getClass());//调用方法,获取执行结果List<Users> list = usersDaoImpl.selectAll("id");list.forEach(System.out::println);}
}

修改UserDao.xml中配置:使用#{}带入参数

 <select id="selectById" resultType="com.woniu.entity.Users">select * from wy_employee where id=#{id}</select>

再次执行同一个测试方法,观察两次测试的日志输出结果:

由上图得出以下结论:

#{}与${}的区别:#{}:使用?占位符,即是将sql语句编译好后再取值,能够有效防止sql注入,#{}取的是属性中的值${}:是sql后面直接拼接参数值,即取值后再编译语句,不能防止注入。
适用场景:${}方式一般用于传入数据库对象,例如传入表名或者列名,就只能使用${}带入参数。在实际使用中能使用#{}就不用${},

案例2:根据指定列名完成查询结果的排序

  • UsersDao.java中定义方法

      List<Users> selectAll(String name);
    
  • UsersDao.xml配置sql

    select * from wy_employee order by ${name} desc
  • 测试代码

@Test
public void test01()throws  Exception{//1.读取配置文件,构建mybatis核心执行对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession可以理解为Connection,此行代码的意思就是:读取配置文件获取数据库连接的工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//通过工厂获取数据库连接对象,SqlSession默认配置:事务手动提交,如果openSession(true)设置事务自动提交try(SqlSession session = sqlSessionFactory.openSession(true);) {System.out.println(session);//sql执行:获取UserDao接口的代理对象,UsersDao usersDaoImpl = session.getMapper(UsersDao.class);System.out.println(usersDaoImpl.getClass());//调用方法,获取执行结果List<Users> list = usersDaoImpl.selectAll("id");list.forEach(System.out::println);}
}
  • 将UserDao.xml中sql修改成#{}再次执行单元测试
<select id="selectAll" resultType="com.woniu.entity.Users">select * from wy_employee order by #{name} desc
</select>

观察执行结果可以发现:#{}带入参数时,查询结果没有排序。只有使用${}带入参数时,才有排序的效果

8 #{}带入参数的写法

#{}带入参数时,使用什么名称来引用值,分为三种场景区别:
1 方法有且只有一个参数,并参数是基本类型或String,#{随便写}
形如:Users selectById(Long id); 
配置sql:select * from wy_employee where id=#{随便写,一般见词知意形参名}2 方法有且只有一个参数,并参数是对象,#{对象的属性名}
形如:insert(user  u) update(User u)3 方法N个参数 #{参数} 借助注解@Param给参数设置引用名
形如:
int update(@Param("pkId") Long id, @Param("pwd") String password,@Param("username") String realName);
xml文件:update wy_employee set password=#{pwd},realname=#{username} where id=#{pkId}

案例:新增公告信息

  • NoticeDao.java定义新增方法
  • int insert(Notice notice);
    
  • NoticeDao.xml配置insert语句
  • <insert id="insert">insert wy_notice values(null,#{title},#{content},#{userId},#{createTime})
    </insert>
    
  • MyTester.java测试代码
  • @Test
    public void test02()throws Exception{//1 指定mybatis开发环境基于哪个配置文件来使用resource基于classpathString resource = "mybatis-config.xml";//2 基于配置文件构建IO输入流InputStream inputStream = Resources.getResourceAsStream(resource);//SqlSession本质就是Connection   SqlSessionFactory是连接池SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//执行sql语句,验证执行结果,连接池获取连接对象时,其实需要指定事务提交方式,如果不指定默认不是自动提交模式try (SqlSession session = sqlSessionFactory.openSession(true)) {//获取dao实现类对象,mybatis依据JDK代理模式动态获取实现类型NoticeDao implProxy = session.getMapper(NoticeDao.class);int i = implProxy.insert(Notice.builder().title("aaaaaaaaaaaa").content("bbbbbbbbbbbbbbbbbbbbbbb").userId(1).createTime(LocalDateTime.now()).build());System.out.println("本次新增的数据行数:"+i);}
    
  • 跟踪控制台输出的日志结果
    在这里插入图片描述

常见坑点

sql映射文件没有在核心配置文件中注册时:
在这里插入图片描述

Sql映射文件和所实现的接口文件不在同一个目录

如何确认接口文件和sql映射文件是否在一个目录呢?可以通过mvn:compile编译项目后,观察target中的classes目录。同一目录的现象如下所示:

UsersDao.java和UsersDao.xml“紧紧挨在一起“
在这里插入图片描述

i

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

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

相关文章

# mysql 中文乱码问题分析

mysql 中文乱码问题分析 一、问题分析&#xff1a; MySQL 中文乱码通常是因为字符集设置不正确导致的。MySQL 有多种字符集&#xff0c;如 latin1、utf8、utf8mb4 等&#xff0c;如果在创建数据库、数据表或者字段时没有指定正确的字符集&#xff0c;或者在插入数据时使用了与…

Go语言特点、编译及命令

本文主要分为三部分内容分别为&#xff1a;Go语言的特点介绍&#xff1b;编译windows、linux环境文件及Go命令。 目录 Go语言特点 编译文件 编译window文件 编译linux文件 Go命令&#xff08;build/run/install/env&#xff09; 编译文件 直接运行程序 安装程序 配置G…

PG实践|内置函数之GENERATE_SERIES之深入理解(二)

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注…

#LinuxC高级 笔记二

makefile gcc gdb makefile 1. 分文件编程 1.1 源文件&#xff1a;.c结尾的文件 包含main函数的.c 包含子函数的.c 1.2 头文件&#xff1a;.h结尾的文件 头文件、宏定义、typedef 、结构体、共用体、枚举、函数声明 include引用时“”和<>的区别&#xff1a; <>去系…

Java:JDK、JRE和JVM 三者关系

文章目录 一、JDK是什么二、JRE是什么三、JDK、JRE和JVM的关系 一、JDK是什么 JDK&#xff08;Java Development Kit&#xff09;&#xff1a;Java开发工具包 JRE&#xff1a;Java运行时环境开发工具&#xff1a;javac&#xff08;编译工具&#xff09;、java&#xff08;运行…

23432443

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

聚四氟乙烯消解管/PTFE四氟消化管/配套各厂家石墨消解仪

四氟消解瓶&#xff0c;通常指的是采用聚四氟乙烯&#xff08;PTFE&#xff0c;也称为特氟龙或铁氟龙&#xff09;材料制成的实验室消解容器。 以下是关于四氟消解瓶的一些基本信息&#xff1a; 材质特性&#xff1a; 四氟消解瓶由PTFE材料制成&#xff0c;具有极佳的耐腐蚀…

Python脚本:将Word文档转换为Excel文件

引言 在文档处理中&#xff0c;我们经常需要将Word文档中的内容转换成其他格式&#xff0c;如Excel&#xff0c;以便更好地进行数据分析和报告。针对这一需求&#xff0c;我编写了一个Python脚本&#xff0c;能够批量处理指定目录下的Word文档&#xff0c;将其内容结构化并转换…

PTrade如何获取技术值班?如get_RSI - 相对强弱指标;PTrade量化软件如何获取?

get_RSI - 相对强弱指标 get_RSI(close, n6) 使用场景 该函数仅在回测、交易模块可用 接口说明 获取相对强弱指标RSI指标的计算结果 PTrade是恒生公司开发的一款专业量化软件&#xff0c;部分合作券商可提供&#xff0c;↑↑↑&#xff01; 参数 close&#xff1a;价格…

.NET发布成单个文件后获取不到程序所在路径的问题

.net程序不发布成单个文件&#xff0c;所以运行都是正常的&#xff0c;但是发布成单个文件后发现使用&#xff1a; var basePath Path.GetDirectoryName((System.Reflection.Assembly.GetExecutingAssembly().Location)); 获取不到应用程序所在的路径了。 找一下几个获取本程…

从混乱到有序:企业级在线文档助力中小企业数字化转型的蜕变

在当今数字化浪潮下&#xff0c;企业的数字化转型已成为行业发展的必然趋势。他们数字化转型的痛点在哪里&#xff1f;资金有限、技术人才短缺和管理的复杂性等。很多时候&#xff0c;它们的文件管理比较混乱&#xff0c;大量的知识和数据分散在不同的系统&#xff0c;形成了数…

Web后端开发概述环境搭建项目创建servlet生命周期

Web开发概述 web开发指的就是网页向后再让发送请求,与后端程序进行交互 web后端(javaEE)程序需要运行在服务器中 这样前端才可以对其进行进行访问 什么是服务器? 解释1: 服务器就是一款软件,可以向其发送请求,服务器会做出一个响应.可以在服务器中部署文件&#xff0c;让…

MySQL:MySQL总结

文章目录 MySQL思维导图基础实际在 Innodb 存储引擎中&#xff0c;会用一个特殊的记录来标识最后一条记录&#xff0c;该特殊的记录的名字叫 supremum pseudo-record &#xff0c;所以扫描第二行的时候&#xff0c;也就扫描到了这个特殊记录的时候&#xff0c;会对该主键索引加…

OpenCV 张正友标定法(二)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 在之前的博客OpenCV 张氏标定法中,我们没有考虑镜头畸变等因素,因此计算出的内参与外参均是理想情况下的数值,而如果我们考虑到镜头的畸变: 我们就需要考虑使用最小二乘法最小化像素坐标的重投影误差(上述所求…

重温react-10(函数组件和类组件的ref获取方式)

App.js的代码 06是函数组件 07是类组件 import React, { useEffect, useRef } from react; import LearnFunction06 from ./LearnFunction06; // 函数组件和类组件的ref使用方式 import LearnFunction07 from ./LearnFunction07; // 函数组件和类组件的ref使用方式 export de…

dell服务器RAID5磁盘阵列出现故障的解决过程二——热备盘制作与坏盘替换过程

目录 背景方案概念全局热备&#xff08;Global Hot Spare&#xff09;&#xff1a;独立热备&#xff08;Dedicated Hot Spare&#xff09;&#xff1a; 过程8号制作成热备清除配置制作独立热备热备顶替坏盘直接rebuild 更换2号盘2号热备 注意注意事项foreign状态要先清除配置 背…

【Mac】Boxy SVG for Mac(矢量图编辑器)及同类型软件介绍

软件介绍 Boxy SVG 是一款功能强大的矢量图形编辑器&#xff0c;专门为 macOS 平台设计开发。它主要用于创建和编辑 SVG&#xff08;可缩放矢量图形&#xff09;文件&#xff0c;是设计师和开发者们制作矢量图形的理想工具。 以下是关于 Boxy SVG 的主要特点和功能&#xff1a…

Rural Access Index (RAI)农村通达指数

农村通达指数&#xff08;RAI&#xff09; 简介 农村通达指数&#xff08;RAI&#xff09;是全球交通领域最重要的发展指标之一。它是目前可持续发展目标中唯一一个直接衡量农村通达性的指标&#xff0c;通过评估农村人口的四季道路通达性来实现。在 2015 年作为可持续发展目…

路由LLM:优化模型调用的成本与效率

引言 在最近的一些视频和讨论中&#xff0c;我们经常提到使用较便宜和较快的模型来替代一些昂贵的大型语言模型&#xff08;LLM&#xff09;。这种方法的一个主要原因是看到许多人在不必要的场合调用如GPT-4或Claude Opus等高级模型&#xff0c;从而浪费了大量资金。而事实上&…

IDEA 编译单个Java文件

文章目录 一、class文件的生成位置二、编译单个文件编译项目报错Error:java: 无效的源发行版: 8 一、class文件的生成位置 file->project structure->Modules 二、编译单个文件 选中文件&#xff0c;点击recompile 编译项目报错 Error:java: 无效的源发行版: 8 Fi…