SSM框架学习——SqlSession以及Spring与MyBatis整合

SqlSession以及Spring与MyBatis整合

准备所需要的JAR包

要实现MyBatis与Spring的整合,很明显需要这两个框架的JAR包,但是只是使用这两个框架中所提供的JAR包是不够的,还需要配合其他包使用:

  • Spring的JAR包
  • MyBatis的JAR包
  • Spring与MyBatis整合中间包mybatis-spring-x.x.x.jar
  • 数据库驱动JAR(以MYSQL为例)mysql-connector-java-x.x.x-bin.jar
  • 数据源所需的JAR(DBCP)commons-dbcp2-x.x.x.jarcommons-pool2-x.x.x.jar

配置文件介绍

关于resources文件夹

我们在之前的项目中,几乎每次都会创建这个文件夹,然后Use as a source folder,那么这个文件夹到底是用来干啥的,凭什么使用它里面的文件是直接写文件名?

实际上这个文件夹是专门存放你的应用所需资源的,如XML等配置文件。这个文件夹被标记为source folder后,在编译后,里面的文件会放到与编译好的文件相同目录里,所以你读取的直接使用文件名实际上是相对路径。

pom.xml

如果我们创建的是一个Maven项目,就可以在pom.xml里添加<properties></properties>标签来定义库版本,然后在下方的<dependencies></dependencies>中的<dependency></dependency><version></version>${...}形式引用它。

下面的XML文件省略了很多,仅为了演示。

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><junit.version>4.12</junit.version><!-- 此处表示省略 -->[...]
</properties><dependencies><!-- JUINT --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><!-- 引用上方标签的版本号 --><version>${junit.version}</version><scope>test</scope></dependency><!-- 此处表示省略 -->[...]
</dependencies>

db.properties

db.properties主要包含一些数据库连接信息,比如JDBC连接驱动、数据库账户名和密码等。

我们在之前的项目中就已经使用过这个文件了,但我们一直没有详细介绍过其每条内容的含义(实际上语义很明显)

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis?useUnicode=true&characterEncoding=utf8
jdbc.username=db_mybatis
jdbc.password=db_mybatis

首先第一行jdbc.driver是指定数据库连接驱动。JDBC即Java数据库连接,它定义了一套关系型数据库的规则,没错实际上就是接口,然后实现并不是由Java官方进行的,而是交给各个数据库厂商来做,它们打包的库也就是JAR包,就被叫做数据库驱动,同时也意味着不同数据库就有不同的驱动实现。

程序设计者无需去关心每个数据库驱动是怎么实现的,而是像你把手机充电器插到墙上的插座一样,把驱动按照接口给“插”进去。这就是面向接口编程的好处。

你的程序只是一个调用者,数据库驱动就像一个代理人,你要先告诉这个代理人怎么操作,然后让这个代理人去真正操纵数据库(怎么操纵你是不关心的,只要满足你的操作需求即可)。你与这个代理人约定的通用交流方式就是刚才的接口,而代理人具体的操纵方式就是驱动的实现。

我们所给的代码中很显然是MySQL的数据库驱动,后面的mysql.jdbc.Driver实际上是随你pom.xml添加的包一块引入的。

第二行的是数据库连接URL,它实际上是数据库JDBC连接字符串的一部分。它的书写形式应该参考数据库驱动提供方的文档!

  • jdbc说明这是一个JDBC的连接字符串
  • mysql说明连接的数据库为MYSQL
  • localhost所在部分,一般是数据库的网络地址或域名,localhost实际上是一个域名,它在你系统的HOST文件中被解析到了127.0.0.1(通常是这样,不绝对,你完全可以修改它),这个地址是一个回环地址,它实际上表示你机器本身。同理,我的MySQL如果在远程服务器192.168.10.2上面,这里就不再是localhost,而是192.168.10.2或者对应的域名。
  • db_mybatis部分对应数据库名称,这个我们在之前创建过。
  • useUnicode这里的值为true表示使用Unicode编码,它是国际标准字符集,将世界上每一种自然语言每个字符都定义为一个唯一编码,满足跨语言需要,尤其是包含中文的时候。
  • characterEncoding部分是指定Unicode编码的存储方式。Unicode只是一个符号集,但并没有规定怎么存放。这里的存放方式为utf8,被定义为将码点编码为1到4个字节byte,具体取决于有效二进制位的数量。

类似于useUnicode的参数还有很多,比如设置SSL等,这里不过多介绍,碰到了请参考文档或搜索引擎。

jdbc.usernamejdbc.password就很简单了,一般是具有权限的数据库用户的用户名和密码。分配一个或多个具有部分权限的用户是好习惯,而不是一直用root(它权限太大了,不安全)。

app.xml

app.xml为Spring配置文件,名称同样不固定,根据你自己来。对于内容的解释请看下方代码的注释:

<!-- 指定XML版本和编码方式为Unicode UTF-8 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- 指定需要扫描的包,使注解生效 --><context:component-scanbase-package="xxx.xxxx.xxx" /><!--读取db.properties --><context:property-placeholder location="classpath:db.properties"/><!-- 配置数据源 --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><!--数据库驱动 --><property name="driverClassName" value="${jdbc.driver}" /><!--连接数据库的url --><property name="url" value="${jdbc.url}" /><!--连接数据库的用户名 --><property name="username" value="${jdbc.username}" /><!--连接数据库的密码 --><property name="password" value="${jdbc.password}" /></bean><!-- 事务管理器,依赖于数据源 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean>	<!-- 注册事务管理器驱动,开启事务注解 --><tx:annotation-driven transaction-manager="transactionManager"/><!-- 配置MyBatis工厂 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><!-- 这里指定了MyBatis配置文件为mybatis-config.xml --><property name="configLocation" value="classpath:mybatis-config.xml"/></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="xx.xxx.xx.mapper" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /></bean></beans>

mybatis-config.xml

mybatis-config.xml为MyBatis配置文件,当然你可以不写它,将它的配置写在Spring配置文件中(写法不太一样),但不建议这么做,当文件内容特别多时不利于维护。

<?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><properties resource="db.properties" /><settings><!-- 延迟加载的开关 --><setting name="lazyLoadingEnabled" value="false" /><!-- 设置积极加载(true)或按需加载(false) --><setting name="aggressiveLazyLoading" value="true" /><setting name="mapUnderscoreToCamelCase" value="true" /><setting name="logImpl" value="STDOUT_LOGGING" /></settings><typeAliases><!-- 对应的dao实体对象 --><package name="xx.xxx.xx.dao" /></typeAliases><!--2.配置Mapper的位置 --><mappers><mapper resource="xx/xxx/xx/mapper/CustomerMapper.xml" /></mappers>
</configuration>

log4j.properties

日志的配置文件

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.top.cairbin.test5=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

进程、线程与CPU调度

在开始Spring与MyBatis的整合之前,为了了解一些概念,我们来讲下进程与线程。

什么是进程?进程是对程序过程的抽象。它是OS的动态执行单元,在传统OS上既是基本分配单元又是基本执行单元。

举个不太严谨的例子,你在Windows下打开一个音乐播放器,随之你能在任务管理器中看到这一项,而这个正在运行的音乐播放器就是一个进程。

线程实际上算是轻量级的进程,但二者还是不太相同,不过它们的相同点要多余不同点。它是看起来就像是对计算机创建进程的模拟,只不过这个模拟是在进程之中的。

进程内存资源相对来讲较独立,而多个线程共享进程的内存资源。

另外我们的CPU调度一般是抢占式的,我们在使用计算机的时候看起来没啥感觉,但实际上CPU一直在“抽疯”——在多个线程之间进行高速切换,这就带来一些问题。

有些操作它不是原子的,即可分割为更小的操作,当一个活没有干完的时候,CPU便去干另一个活。

同时,多个线程尝试对同一个变量进行修改的时候,顺序可能是乱的。

这些都有可能导致线程不安全。什么是线程不安全?指多线程并发执行某个代码的时候,产生了逻辑上的错误,结果与预期值不同。

当然,内存可变性以及Java编译器对指令优化也有可能导致这种情况。

SqlSession

对于MyBatis来讲实际上有三种SqlSession,我们来分别讲讲它们的区别和使用场景。

首先看一张图片,描述再来描述它们的关系:

DefaultSqlSession

DefaultSqlSession类是SqlSession接口的默认实现,它通常被使用于执行SQL操作数据库。

//读取配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");// 构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();try {MyDao myDao = sqlSession.selectOne("MyMapper.selectDao", 1);System.out.println(myDao);
} finally {sqlSession.close();
}

DefaultSqlSession是一个线程不安全的,也就是说它不能是单例。

啥是单例?某些组件在整个程序运行时只要一个实例对象,多个实例化可能会报错。

DefaultSqlSession即然不能是单例,那每次从工厂中获取一个不就行了,实际上这会带来额外开销和资源重用。

另外,DefaultSqlSession还需要手动调用close()方法,这很容易忘记(虽然对于C++程序员是家常便饭),但是聪明的你肯定能用我们所学过的东西来解决这一问题吧——没错就是AOP。

我们既想要单例,又要线程安全,还想要自动关闭怎么办?这就有了SqlSessionManager

SqlSessionManager

SqlSessionManager使用了JDK动态代理技术(我们之前讲过),动态生成代理对象sqlSessionProxy,并通过SqlSessionInterceptor来对DefaultSqlSession进行增强。

虽然对于SqlSessionManager实际上还是创建非单例的DefaultSqlSession来执行方法,但SqlSessionManager可以是单例!

那你可能会怼我,说多个DefaultSqlSession这不还是会造成额外开销和资源重用吗?SqlSessionManager还有另外一种形态,它会复用线程本地的DefaultSqlSession

线程不安全是由于多个线程之间共享DefaultSqlSession导致的,那我在同线程内“共享”(复用)我自己的DefaultSqlSession那不就解决线程安全问题了吗。这就大大提高了效率。

治不了洋人还治不了你吗(雾)!

SqlSessionTemplate

SqlSessionTemplate是MyBatis与Spring整合时的线程安全SqlSession

SqlSessionTemplate实现线程安全的思路与SqlSessionManager相反,我既然自己管不了,我就让别人管——它交给SqlSessionUtils去获取SqlSession

但从本质上讲SqlSessionTemplateSqlSessionManager还是一样的。

SqlSessionUtils会先尝试从事务同步器中获取,获取不到再从工厂里要。而事务同步器本身就是一个线程本地变量管理器。

所以SqlSessionTemplateSqlSessionManager在实现线程安全这一点上殊途同归。

但是二者在自动关闭,即自动执行close()方法的时候就有区别了。

SqlSessionTemplate分两种情况:

  • 当获取的对象由事务同步管理器返回的时候,那关闭是交给Spring的。
  • 如果是从工厂里拿的,直接调用close()方法。

Spring与MyBatis整合

Spring与MyBatis整合方式分为两种:

  • 传统Dao方式
  • Mapper接口方式

传统Dao方式整合

采用传统的Dao方式整合Spring和MyBatis框架,可采用mybatis-spring中所提供的SqlSessionTemplate类或者SqlSessionDaoSupport类来实现。

由于这种方式在现在的开发中已经不常用了,所以这里仅做演示。

@Repository
public class CustomerDaoImpl extends SqlSessionDaoSupport implements ICustomerDao{@Autowiredpublic void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory){super.sqlSessionFactory = sqlSessionFactory;}public void add(Customer customer){[...]}
}

更细化的讲解可参考Spring | 整合MyBatis中SqlSessionTemplate和MapperScannerConfigurer类的使用

Mapper接口方式

传统Dao方式会产生大量重复代码,而且需要正确指定映射文件中的id。

为了解决上述问题,我们采用Mapper的方式整合开发。

基于MapperFactoryBean的整合

MapperFactoryBean是MyBatis-Spring团队提供的一个用来根据Mapper接口生成Mapper对象的类,该类在配置文件中使用时可以配置一下参数

  • mapperInterface用于指定接口
  • SqlSessionFactory用于指定SqlSessionFactory
  • SqlSessionTemplate用于指定SqlSessionTemplate,如果与SqlSessionFactory同时设定,则一般情况下只会启用SqlSessionTemplate。

虽然使用Mapper接口编程的方式很简单,但是在具体使用的时候还是需要遵循一些规范:

  • Mapper接口的名称和对应的XML映射文件名称必须一致
  • XML映射文件中的namespace与Mapper接口的类路径相同
  • Mapper接口方法名要和XML映射文件中定义的每个执行语句的id相同
  • Mapper接口中的方法的输入参数类型和XML映射文件中的parameterType类型相同
  • Mapper接口方法的输出类型要和XML映射文件的resultType类型相同
基于MapperScannerConfigurer的方式

使用上面的方式会使得配置文件臃肿,所以我们在做项目开发的时候一般是使用MapperScannerCongigurer的方式进行扫描。

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="top.cairbin.test6.mapper" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

我们新建一个项目top.cairbin.test6,至于哪些细节该注意你应当非常清楚了,这里就不多说了,如果不会请回去看之前的教程。

对于配置文件我们也说的很清楚了,接下来直接给文件:

pom.xml文件

<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>top.cairbin</groupId><artifactId>test6</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>test6</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.7</maven.compiler.source><maven.compiler.target>1.7</maven.compiler.target><junit.version>4.12</junit.version><spring.version>5.2.5.RELEASE</spring.version><mybatis.version>3.5.4</mybatis.version><mybatis.spring.version>2.0.4</mybatis.spring.version><mysql.version>8.0.33</mysql.version><commons-dbcp.version>2.7.0</commons-dbcp.version></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency>		<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis.spring.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-dbcp2</artifactId><version>${commons-dbcp.version}</version></dependency><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.4.0</version></dependency>		</dependencies>
</project>

db.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis?useUnicode=true&characterEncoding=utf8
jdbc.username=db_mybatis
jdbc.password=db_mybatis

Spring配置文件app.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- 指定需要扫描的包,使注解生效 --><context:component-scanbase-package="top.cairbin.test6" /><!--读取db.properties --><context:property-placeholder location="db.properties"/><!-- 配置数据源 --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><!--数据库驱动 --><property name="driverClassName" value="${jdbc.driver}" /><!--连接数据库的url --><property name="url" value="${jdbc.url}" /><!--连接数据库的用户名 --><property name="username" value="${jdbc.username}" /><!--连接数据库的密码 --><property name="password" value="${jdbc.password}" /></bean><!-- 事务管理器,依赖于数据源 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean>	<!-- 注册事务管理器驱动 --><tx:annotation-driven transaction-manager="transactionManager"/><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="configLocation" value="mybatis-config.xml"/></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="top.cairbin.test6.mapper" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /></bean>
</beans>

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><properties resource="db.properties" /><settings><!-- 延迟加载的开关 --><setting name="lazyLoadingEnabled" value="false" /><!-- 设置积极加载(true)或按需加载(false) --><setting name="aggressiveLazyLoading" value="true" /><setting name="mapUnderscoreToCamelCase" value="true" /><setting name="logImpl" value="STDOUT_LOGGING" /></settings><typeAliases><package name="top.cairbin.test6.dao" /></typeAliases><!--2.配置Mapper的位置 --><mappers><mapper resource="top/cairbin/test6/mapper/CustomerMapper.xml" /></mappers>
</configuration>

top.cairbin.test6.dao.Customer

package top.cairbin.test6.dao;public class Customer {private Integer id;			// 主键idprivate String username;	// 客户名称private String jobs;		// 职业private String phone;		// 电话public Integer getId() {return this.id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return this.username;}public void setUsername(String username) {this.username = username;}public String getJobs() {return this.jobs;}public void setJobs(String jobs) {this.jobs = jobs;}public String getPhone() {return this.phone;}public void setPhone(String phone) {this.phone = phone;}@Overridepublic String toString() {return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]";}
}

top.cairbin.test6.mapper下的CustomerMapper.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="top.cairbin.test6.mapper.CustomerMapper"><resultMap id="BaseResultMap" type="top.cairbin.test6.dao.Customer"><id column="id" jdbcType="INTEGER" property="id" /><result column="username" jdbcType="VARCHAR" property="username" /><result column="jobs" jdbcType="VARCHAR" property="jobs" /><result column="phone" jdbcType="VARCHAR" property="phone" /></resultMap><sql id="Base_Column_List">id, username, jobs, phone</sql><select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">select <include refid="Base_Column_List" />from customerwhere id = #{id,jdbcType=INTEGER}</select>
</mapper>

对应接口top.cairbin.test6.mapper.CustomerMapper

package top.cairbin.test6.mapper;import top.cairbin.test6.dao.Customer;public interface CustomerMapper{// 通过id查询客户Customer selectByPrimaryKey(Integer id);
}

我们接下来实现Service层

创建src/main/java下的包top.cairbin.test6.service

然后在包中创建接口ICustomerService

package top.cairbin.test6.service;import top.cairbin.test6.dao.Customer;public interface ICustomerService {	public Customer getCustomerByID(int id);
}

创建实现这个接口的类CustomerServiceImpl

package top.cairbin.test6.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.cairbin.test6.dao.Customer;
import top.cairbin.test6.mapper.CustomerMapper;@Service
public class CustomerServiceImpl implements ICustomerService{@Autowiredprivate CustomerMapper customerMapper;public Customer getCustomerByID(int id) {Customer customer = customerMapper.selectByPrimaryKey(id);return customer;}
}

在测试目录src/test/java下的top.cairbin.test6包创建测试类CustomerTest

package top.cairbin.test6;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import top.cairbin.test6.dao.Customer;
import top.cairbin.test6.service.ICustomerService;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:app.xml" })
public class CustomerTest {@Autowiredprivate ICustomerService customerService;	@Testpublic void findTest() {Customer customer = customerService.getCustomerByID(1);System.out.println(customer);}
}

运行测试,得到结果

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

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

相关文章

用ChatGPT出题,完全做不完

最近小朋友正在学习加减法&#xff0c;正好利用ChatGPT来生成加减法练习题&#xff0c;小朋友表示够了&#xff0c;够了&#xff0c;完全做不完。本文将给大家介绍如何利用ChatGPT来生成练习题。 尚未获得ChatGPT的用户&#xff0c;请移步&#xff1a;五分钟开通GPT4.0。 角色…

用Python实现办公自动化(自动化处理PDF文件)

自动化处理 PDF 文件 目录 自动化处理 PDF 文件 谷歌浏览器 Chrome与浏览器驱动ChromeDriver安装 &#xff08;一&#xff09;批量下载 PDF 文件 1.使用Selenium模块爬取多页内容 2.使用Selenium模块下载PDF文件 3.使用urllib模块来进行网页的下载和保存 4.使用urllib…

ARMv8-A架构下的外部debug模型(external debug)简介

Armv8-A external debug Armv8-A debug模型一&#xff0c;外部调试 External debug 简介二&#xff0c;Debug state2.1 Debug state的进入与退出 三&#xff0c;DAP&#xff0c;Debug Access Port3.1 EDSCR, External Debug Status and Control Register调试状态标识&#xff0…

搭建Flutter开发环境、从零基础到精通(文末送书【北大出版社】)

目录 搭建开发环境 1. 下载Flutter SDK 2. 设置镜像地址及环境变量 3. 安装与设置Android Studio 4. 安装Visual Studio Code与Flutter开发插件 5. IDE的使用和配置 6. 安装Xcode 7. 检查Flutter开发环境 好书推荐 内容简介 作者简介 搭建开发环境 Flutter可以跨平…

【数据结构】非线性结构---二叉树

1、树 1.1 树的相关概念 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff1b; 如上图&#xff1a;A的为6 叶节点或终端节点&#xff1a;度为0的节点称为叶节点&#xff1b; 如上图&#xff1a;B、C、H、I...等节点为叶节点 非终端节点或分支节点&#…

[flink 实时流基础] 输出算子(Sink)

学习笔记 Flink作为数据处理框架&#xff0c;最终还是要把计算处理的结果写入外部存储&#xff0c;为外部应用提供支持。 文章目录 **连接到外部系统****输出到文件**输出到 Kafka输出到 mysql自定义 sink 连接到外部系统 Flink的DataStream API专门提供了向外部写入数据的方…

128:忆往昔,迎春来

机缘 时间真的是过得好快啊&#xff0c;128&#xff0c;距离我的第一篇博客已经128天了&#xff0c;从大一上的冬天&#xff0c;到大一下的春夏&#xff0c;从一个初入大学的新人&#xff0c;到一个开始思考未来的新人。我开始不断更新博客&#xff0c;开始不断吸收知识&#…

【21-40】计算机网络基础知识(非常详细)从零基础入门到精通,看完这一篇就够了

【21-40】计算机网络基础知识&#xff08;非常详细&#xff09;从零基础入门到精通&#xff0c;看完这一篇就够了 以下是本文参考的资料 欢迎大家查收原版 本版本仅作个人笔记使用21、HTTPS是如何保证数据传输的安全&#xff0c;整体的流程是什么&#xff1f;&#xff08;SSL是…

【Servlet】Servlet入门

文章目录 一、介绍二、入门案例导入servlet-api的解决办法 一、介绍 概念&#xff1a;server applet&#xff0c;即&#xff1a;运行在服务器端的小程序 Servlet就是一个接口&#xff0c;定义了Java类被浏览器访问到&#xff08;tomcat识别&#xff09;的规则。 将来我们定义…

Spring Boot | Spring Boot的“数据访问“、Spring Boot“整合MyBatis“

目录: 一、Spring Boot”数据访问概述“二、Spring Boot”整合MyBatis”1. 基础环境搭建 (引入对应的“依赖启动器” 配置数据库的“相关参数”)① 数据准备 (导入Sql文件)② 创建项目&#xff0c;引入相应的启动器&#xff0c;编写数据库对应的“实体类”③额外添加pom.xml文…

海康Ehome2.0与5.0设备接入EasyCVR视频汇聚平台时的配置区别

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

【Ubuntu】用 VMware 安装 macOS

本教程使用 Ubuntu 20.04.6 LTS&#xff0c;VMware Workstation Pro 17.5.1&#xff0c;macOS Sonoma 14.4。文中所有需要的下载链接均以 Markdown 的形式体现在文字上。 下载 VMware Workstation Pro&#xff0c;目前最新版本是 17.5.1。 使用密钥&#xff0c;进行破解。 VM…

SpringBoot+uniApp宠物领养小程序系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1.保存宠物信息代码2.提交订单信息代码3.查询评论信息代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootuniApp框架开发的宠物领养微信小程序系统。…

R语言,数据类型转换

原文链接&#xff1a;R语言技能 | 不同数据类型的转换 本期教程 写在前面 今天是4月份的第一天&#xff0c;再过2天后再一次迎来清明小假期。木鸡大家是否正常放假呢&#xff1f; 我们在使用R语言做数据分析时&#xff0c;会一直对数据进行不同类型的转换&#xff0c;有时候…

【Java】API——Calendar日期类使用+题目演示

目录 Calendar日期类简单介绍 导入对应包&#xff1a; 获取 Calendar 对象&#xff1a; 设置日期和时间&#xff1a; 获取日期和时间的各个部分&#xff1a; 日期和时间的加减操作&#xff1a; 例题&#xff1a;世纪末的星期 题目描述 题目代码 Calendar日期类简单介绍…

typescript 实现RabbitMQ死信队列和延迟队列 订单10分钟未付归还库存

Manjaro安装RabbitMQ 安装 sudo pacman -S rabbitmq rabbitmqadmin启动管理模块 sudo rabbitmq-plugins enable rabbitmq_managementsudo rabbitmq-server管理界面 http://127.0.0.1:15672/ 默认用户名和密码都是guest。 要使用 rabbitmqctl 命令添加用户并分配权限&#xf…

Java类和对象练习题

练习一 下面代码的运行结果是&#xff08;&#xff09; public static void main(String[] args){String s;System.out.println("s"s);} 解析&#xff1a;本题中的代码不能编译通过&#xff0c;因为在Java当中局部变量必须先初始化&#xff0c;后使用。所以此处编译不…

【Python刷题】将有序数组转换为二叉搜索树

问题描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 高度平衡的意思是&#xff1a;二叉树是一颗满足“每个结点的左右两个子树的高度差的绝对值不超过1”的二叉树。 示例 1&#xff1a; 输入&#xf…

农村集中式生活污水分质处理及循环利用技术指南

立项单位&#xff1a;生态环境部土壤与农业农村生态环境监管技术中心、山东文远环保科技股份有限公司、北京易境创联环保有限公司、中国环境科学研究院、广东省环境科学研究院、中铁第五勘察设计院集团有限公司、中华环保联合会水环境治理专业委员会 本文件规定了集中式村镇生活…

Stable Diffusion 模型下载:epiCPhotoGasm(真实、照片)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八下载地址模型介绍