MyBatis初级

文章目录

  • 一、mybatis
    • 1、概念
    • 2、JDBC缺点
      • 2.1、之前jdbc操作
      • 2.2 、原始jdbc操作的分析
    • 3、mybatis的使用
      • 3.1、导入maven依赖
      • 3.2、新建表
      • 3.3、实体类
      • 3.4、编写mybatis的配置文件
      • 3.5、编写接口 和 映射文件
      • 3.6、编写测试类
      • 3.7、注意事项
    • 4、代理方式开发
    • 5、mybatis和spring整合
      • 5.1、开发步骤
        • 5.1.1、导入maven依赖
        • 5.1.2、创建账户的实体类 Account
        • 5.1.3、创建mapper接口和对应的xml文件
        • 5.1.4、Service接口类和实现类
        • 5.1.5、数据库配置 db.properties
        • 5.1.6、spring配置文件
        • 5.1.7、mybatis的配置文件
        • 5.1.8、测试功能
  • 二、整合的总结
  • 三、mybatis缓存
    • 1、一级缓存
    • 2、二级缓存
  • 四、隔离级别
  • 五、事务

一、mybatis

1、概念

  • 框架是一款半成品软件,我们可以基于这个半成品软件继续开发,来完成我们个性化的需求!
  • ORM(Object Relational Mapping 对象关系映射):指的是持久化数据和实体对象的映射模式。
  • mybatis:mybatis 是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
  • mybatis通过xml或注解的方式将要执行的各种 statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句。
  • 最后mybatis框架执行sql并将结果映射为java对象并返回。采用ORM思想解决了实体和数据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作。在这里插入图片描述

2、JDBC缺点

2.1、之前jdbc操作

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2 、原始jdbc操作的分析

  • 原始 JDBC 的操作问题分析

    1. 频繁创建和销毁数据库的连接会造成系统资源浪费从而影响系统性能。
    2. sql语句在代码中硬编码,如果要修改 sql 语句,就需要修改 java 代码,造成代码不易维护。
    3. 查询操作时,需要手动将结果集中的数据封装到实体对象中。
    4. 增删改查操作需要参数时,需要手动将实体对象的数据设置到 sql 语句的占位符。 
    
  • 原始 JDBC 的操作问题解决方案

    1. 使用数据库连接池初始化连接资源。 
    2. 将 sql 语句抽取到配置文件中。 
    3. 使用反射、内省等底层技术,将实体与表进行属性与字段的自动映射    
    
  1. 使用数据库连接池初始化连接资源。
  2. 将sql语句抽取到配置文件中。
  3. 使用反射、内省等底层技术,将实体与表进行属性与字段的自动映射

3、mybatis的使用

①添加MyBatis的maven包

②创建user数据表

③编写User实体类

④编写核心文件MyBatisConfig.xml

⑤编写映射文件UserMapper.xml 和 UserMapper接口

⑥编写测试类

3.1、导入maven依赖

  <!--    数据库--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29</version></dependency><!-- MyBatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.3</version></dependency><!--    日志依赖--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>

3.2、新建表

在这里插入图片描述

CREATE TABLE user (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) DEFAULT NULL,
password varchar(255) DEFAULT NULL,
age int(11) DEFAULT NULL,
phone varchar(255) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

3.3、实体类

public class User {private int id;private String username;private String password;private String phone;private int age;set get 方法
}

3.4、编写mybatis的配置文件

可以参考官方文档

https://mybatis.org/mybatis-3/zh/getting-started.html

# 数据库信息 db.propertiesdriver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/linjiu?useUnicode=true&characterEncoding=utf-8
username=root
password=root# 配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><!--configuration 核心根标签-->
<configuration><!--引入数据库连接的配置文件--><properties resource="db.properties"/><!--配置LOG4J--><settings><setting name="logImpl" value="log4j"/></settings><!--起别名--><typeAliases><typeAlias type="com.xinzhi.model.User" alias="user"/><!--<package name="com.xinzhi.model"/>--></typeAliases><!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个--><environments default="mysql"><!--environment配置数据库环境  id属性唯一标识--><environment id="mysql"><!-- transactionManager事务管理。  type属性,采用JDBC默认的事务--><transactionManager type="JDBC"></transactionManager><!-- dataSource数据源信息   type属性 连接池--><dataSource type="POOLED"><!-- property获取数据库连接的配置信息 --><property name="driver" value="${driver}" /><property name="url" value="${url}" /><property name="username" value="${username}" /><property name="password" value="${password}" /></dataSource></environment></environments><!-- mappers引入映射配置文件 --><mappers><!-- mapper 引入指定的映射配置文件   resource属性指定映射配置文件的名称 --><mapper resource="UserMapper.xml"/></mappers>
</configuration># 日志文件  log4j.properties
# Global logging configuration
# ERROR WARN INFO DEBUG
log4j.rootLogger=DEBUG, stdout
# 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

3.5、编写接口 和 映射文件

public interface UserMapper {List<User> selectAll();User selectById(int id);
}//映射文件  
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatisDTD约束-->
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--mapper:核心根标签namespace属性:名称空间
-->
<mapper namespace="com.linjiu.mapper.UserMapper"><!--select:查询功能的标签id属性:唯一标识resultType属性:指定结果映射对象类型parameterType属性:指定参数映射对象类型--><select id="selectAll" resultType="user">SELECT * FROM user</select><select id="selectById" resultType="com.linjiu.model.User" parameterType="int">select * from user where id=#{id}</select>
</mapper>

mapper.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">
<mapper namespace=""></mapper>

3.6、编写测试类

 @Testpublic  void main1( ) throws IOException {//加载核心配置文件InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//获得sqlSession工厂对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);//获得sqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//执行sql语句List<User> users = sqlSession.selectList("com.linjiu.mapper.UserMapper.selectAll");//打印结果System.out.println(users);User user = sqlSession.selectOne("com.linjiu.mapper.UserMapper.selectById", 1);System.out.println(user);//打印结果sqlSession.close();}
  • 注意如果是增删改需要提交事务 sqlSession.commit();
  • 如果sqlSessionFactory.openSession(true),括号中添加了true,那么就是自动提交事务。

3.7、注意事项

  • environments标签
# 事务管理器(transactionManager)- JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。- MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。
# 数据源(dataSource)- UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。- POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。- JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

4、代理方式开发

采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。
Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象。
Mapper 接口开发需要遵循以下规范:
1、 Mapper.xml文件中的namespace与mapper接口的全限定名相同
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

   @Testpublic  void main1( ) throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);SqlSession sqlSession = sqlSessionFactory.openSession();// 获取到mapper的代理对象,代理对象直接操作数据库UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> users = mapper.selectAll();System.out.println(users);User user = mapper.selectById(1);System.out.println(user);sqlSession.close();}

面试题:

​ mybatis中# 和 $的区别

5、mybatis和spring整合

5.1、开发步骤

  • 1 导入maven依赖
  • 2 创建账户的实体类
  • 3 创建mapper接口和对应的xml文件
  • 4 Service接口类和实现类
  • 5 数据库的配置文件
  • 6 spring配置文件
  • 7 mybatis的配置文件
  • 8 测试功能

5.1.1、导入maven依赖

 <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.0.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.0.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>5.0.7.RELEASE</version></dependency><!-- 基于AspectJ的aop依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.7.RELEASE</version></dependency><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!-- spring 事务管理和JDBC依赖包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.7.RELEASE</version></dependency><!-- spring 单元测试组件包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.7.RELEASE</version></dependency><!-- 单元测试Junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!-- mysql数据库驱动包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.35</version></dependency><!-- dbcp连接池的依赖包 --><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency><!-- mybatis依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!-- mybatis和spring的整合依赖 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.5</version><configuration><skipTests>true</skipTests></configuration></plugin></plugins></build>

5.1.2、创建账户的实体类 Account

public class Account {private int id;private String name;private double money;set  get 方法
} 
CREATE TABLE `account` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`money` decimal(11,0) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

5.1.3、创建mapper接口和对应的xml文件

public interface AccountMapper {int update(@Param("name") String name,@Param("money") double money);double queryMoney(String name);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--mapper:核心根标签namespace属性:名称空间
-->
<mapper namespace="com.linjiu.dao.AccountMapper"><!-- 查询 --><select id="queryMoney" parameterType="string" resultType="double">SELECT money from account where name = #{name}</select><!-- 修改 --><update id="update" parameterType="account">UPDATE account SET money = #{money} WHERE name = #{name}</update></mapper>

说明:

  • @param() 当只有一个参数时,没什么好说的,传进去一个值也只有一个参数可以匹配。当存在多个参数时,传进去的值就区分不开了,这时可以考虑用

  • 当配置文件中有多个参数的时候,parameterType该怎么写呢? 一般可以使用实体类,也可以使用map。底层还是使用了反射的原理,根据对象的字段去匹配数据库相应的字段

5.1.4、Service接口类和实现类

public interface IAccountService {/*** 转账功能* @param from 主动转账的人* @param to   收款的人* @param money  金额*/void transfer(String from, String to, double money);
}@Service
@Transactional
public class AccountServiceImpl implements IAccountService {@Autowiredprivate AccountMapper accountMapper;public void transfer(String from, String to, double money) {// 先查询from账户的钱double fromMoney = accountMapper.queryMoney(from);// 对from账户进行扣钱操作accountMapper.update(from, fromMoney-money);//手动制造异常System.out.println(1 / 0);// 先查询to账户的钱double toMoney = accountMapper.queryMoney(to);// 对to账户进行加钱操作accountMapper.update(to, toMoney-money);System.out.println("支付宝到账:"+money+"元");}
}

5.1.5、数据库配置 db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/linjiu?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

5.1.6、spring配置文件

<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!--引入外部的配置文件--><context:property-placeholder location="classpath:db.properties"/><!--	配置数据源--><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="${jdbc.driver}"/><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" /><!--	xml方式配置事务,一般使用上面注解的方式,因为方便和简单,其实事务也是对业务层逻辑的增强-->
<!--	<tx:advice transaction-manager="transactionManager" id="txAdvice" >-->
<!--		<tx:attributes>-->
<!--			<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>-->
<!--		</tx:attributes>-->
<!--	</tx:advice>-->
<!--	-->
<!--	<aop:config>-->
<!--		<aop:pointcut id="myPointCut" expression="execution(* com.soft.impl.*.*(..))"/>-->
<!--		<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointCut"/>-->
<!--	</aop:config>--><!--	配置sqlSessionFactory,主要是指定数据源,配置文件的位置--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="configLocation" value="classpath:mybatis-config.xml"/><property name="mapperLocations" value="classpath:mapper/*.xml"/></bean><!--	扫描mapper文件--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.linjiu.dao"/></bean><!--	组件扫描,扫描指定包下的注解--><context:component-scan base-package="com.linjiu"/></beans>

5.1.7、mybatis的配置文件

<?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><!--    开启二级缓存,默认是关闭的--><settings><setting name = "cacheEnabled" value = "true" /></settings><!--    别名--><typeAliases><package name="com.linjiu.model" /></typeAliases><!--    map.xml文件的位置指定,因为sqlsessionfactory中已经指定过了,所以可以不配置--><mappers><!--        <mapper resource="mapper/AccountMapper.xml"/>--></mappers></configuration>

5.1.8、测试功能

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class AppTest {@Autowiredprivate IAccountService accountService;@Testpublic void testTransfer() throws Exception {accountService.transfer("husband", "wife", 100);}
}

说明:

  • @RunWith(SpringJUnit4ClassRunner.class) 让测试运行于Spring测试环境
  • @ContextConfiguration(locations = {“classpath:applicationContext.xml”})

二、整合的总结

  • 其实整合的目的就是把mapper对象放入到容器中。(从接口生成对象,底层还是反射)

  • 注意配置文件的加载,测试类中指定了spring的配置文件, spring的配置文件中又指定了mybatis配置文件和mapper映射文件。

三、mybatis缓存

mybatis的缓存主要是针对查询操作的

1、一级缓存

  • 一级缓存默认是开启的, SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。
  • 当调用 SqlSession 的修改,添加,删除,commit(),close()等,方法时,就会清空一级缓存。

2、二级缓存

  • 二级缓存是 mapper 映射级别的缓存, 默认是不开启的,需要手动开启二级缓存

  • 当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,也就是序列化

    <!-- 开启二级缓存的支持 --> 
    <setting name="cacheEnabled" value="true"/></settings>
    

四、隔离级别

1.读未提交(Read uncommitted):脏读

脏读: 一个事务在执行的过程中读取到了其他事务还没有提交的数据

Tom的账户money=0,公司发工资把5000元打到Tom的账户上,Tom的money=money+5000元,但是该事务并未提交,而Tom正好去查看账户,发现工资已经到账,账户money=5000元,非常高兴,可是不幸的是,公司发现发给Tom的工资金额不对,应该是2000元,于是迅速回滚了事务,修改金额后,将事务提交,Tom再次查看账户时发现账户money=2000元,Tom空欢喜一场,从此郁郁寡欢,走上了不归路……

2.读已提交(Read committed):

可避免 脏读 的发生。

两次读取的数据不一样,自己事务没有提交的时候可以读取别的已经提交的事务。

Tom拿着工资卡去消费,酒足饭饱后在收银台买单,服务员告诉他本次消费1000元,Tom将银行卡给服务员,服务员将银行卡插入POS机,POS机读到卡里余额为3000元,就在Tom磨磨蹭蹭输入密码时,他老婆以迅雷不及掩耳盗铃之势把Tom工资卡的3000元转到自己账户并提交了事务,当Tom输完密码并点击“确认”按钮后,POS机检查到Tom的工资卡已经没有钱,扣款失败,Tom十分纳闷,明明卡里有钱,于是怀疑POS有鬼,和收银小姐姐大打出手,300回合之后终因伤势过重而与世长辞,Tom老婆痛不欲生,郁郁寡欢,从此走上了不归路…

3.可重复读(Repeatable read):幻读

MySql默认隔离级别。自己事务没有提交的时候,读不到别的已经提交的事务。

Tom的老婆工作在银行部门,她时常通过银行内部系统查看Tom的工资卡消费记录。2019年5月的某一天,她查询到Tom当月工资卡的总消费额为80元,Tom的老婆非常吃惊,心想“老公真是太节俭了,嫁给他真好!”,而Tom此时正好在外面胡吃海塞后在收银台买单,消费1000元,即新增了一条1000元的消费记录并提交了事务,沉浸在幸福中的老婆查询了Tom当月工资卡消费明细一探究竟,可查出的结果竟然发现有一笔1000元的消费,Tom的老婆瞬间怒气冲天,外卖订购了一个大号的榴莲,傍晚降临,Tom生活在了水深火热之中,只感到膝盖针扎的痛…

4.串行化(Serializable ):

可避免 脏读、不可重复读、幻读 的发生。

五、事务

事务有以下特性(ACID):
1、原子性(Atomicity)
事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

2、一致性(Consistency)
事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。

3、隔离性(Isolation)
多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

4、持久性(Durability)
已被提交的事务对数据库的修改应该永久保存在数据库中

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

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

相关文章

PbootCMS在搭建网站

1、打开网站 https://www.pbootcms.com/ 2、点击 “本站” 下载最新的网站代码 3、在本地laragon/www下创建目录&#xff08;hejuwuye&#xff09;&#xff0c;并将代码放进去 4、创建本地数据库&#xff0c;数据库名称为&#xff1a; hejuwuye&#xff0c;然后将static/bac…

Pyhton压缩JS代码

文章目录 1.安装依赖2.目录结构3.代码4.执行结果 1.安装依赖 pip install jsmin2.目录结构 3.代码 import jsmindef run(src_path, tgt_path):with open(src_path, "r", encodingutf-8) as input_file:with open(tgt_path, "w", encodingutf-8) as outpu…

【客户案例】脊叶架构(Spine-Leaf)的云化园区网络部署实践

前言 各行业数字化转型进程加快&#xff0c;作为基础设施的园区网络也面临着升级压力。为此&#xff0c;星融元通过将先进成熟的云网络建设理念引入园区场景&#xff0c;推出了“云化园区网络解决方案”&#xff0c;帮助客户网络实现架构级的深层优化。 云化园区网络解决方案介…

Linux 或者 Docker 容器通过 date 设置系统时间

目录 1. Linux2. Docker 容器2.1 进入容器内部修改2.2 可能会遇到的问题 1. Linux 要在Linux系统中设置日期和时间&#xff0c;可以使用date命令。 使用以下命令格式来设置日期和时间&#xff1a; sudo date -s "YYYY-MM-DD HH:MM:SS"其中&#xff0c;YYYY表示年份…

苹果手机无法正常使用小程序和APP

小程序、APP 已使用了几年&#xff0c;突然大量反馈&#xff1a;苹果手机无法正常使用。但不是全部&#xff0c;只是部分手机。 因为同事苹果手机都能用&#xff0c;所以无法准确判断具体原因。 后来同事苹果手机也无法使用了&#xff0c;显示&#xff1a; 网上搜索结果&…

【数据结构】【项目】BitMap?40亿电话号码如何快速去重?

目录 前言实现完整代码 参考资料 前言 40亿电话号码如何快速去重&#xff1f;我们往往会想到bitmap 数据结构中的 Bitmap 是一种位图索引非常高效的数据结构&#xff0c;用于存储处理大规模数据的位信息&#xff0c;其中每个位对应于一个元素&#xff0c;如果位为1&#xff0…

笔记 | 非素数个数(朴素筛查 || 埃式筛查法)

非素数个数 题目描述朴素筛查方法题解 题目描述 求a-b之间的非素数个数 特别的&#xff0c;1也算作素数&#xff0c;区间是[a, b]。 输入输出格式 输入描述: 多组测试数据。 输入两个正整数数a,b&#xff0c;其中a<b<10^7。 输出描述: 输出答案。 输入输出样例 输入样例…

蓝牙资讯|三星Galaxy Wearable有望在国内发售,智能戒指成为新宠儿

博主 i 冰宇宙 此前爆料&#xff0c;明年 1 月 Galaxy S24 发布会上&#xff0c;智能戒指预计将成为明星产品。而在最新的三星 Galaxy Wearable 应用中&#xff0c;已经出现了一个戒指图标&#xff0c;进一步印证了产品的消息。 Galaxy Wearable 是由三星官方出品的一款针对旗…

geetest极验空间推理验证码破解

geetest极验空间推理验证码破解 > 本篇文章仅供学习使用&#xff0c;如侵权请联系删除。某验验证码3代&#xff0c;4代已经是老生常谈的问题了&#xff0c;本篇文章粗略的分析一波3代空间推理验证码识别与验证的整个过程。 1.参数破解 从一开始gt和challenge的参数的获取…

按键点亮led灯

原理图: K0这个按键按下时&#xff0c;开发板D1这个灯亮&#xff0c;松开&#xff0c;灯灭 代码如下: #include "stm32f4xx.h" void LED_Init(void) {//1.定义一个GPIO外设的结构体变量 GPIO_InitTypeDef GPIO_InitStructure;//RCC_AHB1PeriphClockCmd(RCC_AHB1Pe…

算法题笔记 1-5

目录 week 11. 找出数组中重复的数字题目数据范围样例题解(数组遍历) O(n) 2. 不修改数组找出重复的数字题目数据范围样例题解(分治&#xff0c;抽屉原理) O(nlogn) 3. 二维数组中的查找题目题解(单调性扫描) O(nm) 4.替换空格题目题解(线性扫描) O(n)(双指针扫描) O(n) 5.从尾…

uniapp开发小程序中实现骨架屏

第一步&#xff1a;小程序中实现骨架屏在微信开发者工具中点击生成骨架屏&#xff1a; 第二步&#xff1a;复制html代码&#xff0c;到骨架屏vue组件汇中再把之前写的样式代码引入进去&#xff1a; import ../../pages/user/user.css; 第三步&#xff1a;组件中引入骨架屏&am…