后端学习 - MyBatis

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的 持久层框架

文章目录

  • 一 基于配置文件的 MyBatis 搭建
    • 1 搭建过程(增删改)
    • 2 查询操作
    • 3 特殊操作
  • 二 MyBatis 获取参数值的方式
    • 1 单个字面量类型的参数
    • 2 多个字面量类型的参数
    • 3 Map 类型的参数
    • 4 实体类类型的参数
    • 5 使用 @Param 注解的参数
  • 三 自定义查询结果 resultMap
    • 1 处理表的字段和属性的映射关系
    • 2 处理多对一关系
    • 3 处理一对多关系
  • 四 动态 SQL
    • 1 if 标签
    • 2 where 标签
    • 3 trim 标签
    • 4 choose, when, otherwise 标签
    • 5 foreach 标签
    • 6 sql 标签
  • 五 MyBatis 缓存
    • 1 一级缓存
    • 2 二级缓存
    • 3 查询顺序
  • 六 逆向工程


一 基于配置文件的 MyBatis 搭建

1 搭建过程(增删改)

配置过程:核心配置文件通过配置 mappers 找到映射文件,映射文件通过全类名和方法名定位到具体的接口和方法
在这里插入图片描述

  1. 创建 maven 工程,引入依赖
  2. src/main/resources 目录下创建核心配置文件 mybatis-config.xml:核心配置文件主要用于配置连接数据库的环境,以及 MyBatis 的全局配置信息(整合 Spring 之后,配置文件可以省略)
<?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><!--设置连接数据库的环境--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url"value="jdbc:mysql://localhost:3306/learn"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!--引入UserMapper.xml的映射文件--><mappers><mapper resource="mappers/UserMapper.xml"/><!--其他映射文件...--></mappers>
</configuration>
  1. 创建实体类型,以及数据库中对应的表
  2. 创建 mapper 接口:mapper 接口相当于 dao,但是 mapper 仅仅是接口,不需要提供实现类,具体的 SQL 命令写在 映射文件 xxxMapper.xml 中(xxx和类名保持一致)
  3. 创建 MyBatis 映射文件,在对应的位置标注全类名和方法(两个一致:mapper接口的全类名和映射文件的 namespace 保持一致 ,mapper 接口中方法的方法名和映射文件中编写 SQL 的标签的 id 属性保持一致
<?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的全类名-->
<mapper namespace="hello.mapper.UserMapper"><!--对应的方法--><insert id="insertUser">insert into user values (null, "伍佰", "500", 50, "男", "500@gmail.com")</insert>
</mapper>
  1. 测试
    @Testpublic void helloTest() throws IOException {//读取MyBatis的核心配置文件InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//创建SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);//创建SqlSession对象,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务//SqlSession sqlSession = sqlSessionFactory.openSession();//创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//通过代理模式创建UserMapper接口的代理实现类对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//调用UserMapper接口中的方法,就可以根据UserMapper的全类名匹配元素文件,通过调用的方法名匹配映射文件中的SQL标签,并执行标签中的SQL语句int result = userMapper.insertUser();}

2 查询操作

映射文件 UserMapper.xml 中,为了设置实体类和数据库表的映射,查询功能的标签必须指定 resultType(自动映射,用于属性名和表中字段名一致的情况) 或 resultMap(自定义映射,用于一对多 / 多对一 / 字段名和属性名不一致 的情况) 属性

  • 查询单个对象(单个对象也可以使用 List)
	接口定义方法:User getUserById();映射文件:<select id="getUserById" resultType="hello.pojo.User">select * from user where id = 1</select>
  • 查询多个对象
	接口定义方法:List<User> getAllUser();映射文件:<select id="getAllUser" resultType="hello.pojo.User">select * from user</select>

3 特殊操作

  • 模糊查询
<select id="fuzzy" resultType="User">select * from user where username like "%"#{name}"%"
</select>
  • 批量删除:不能使用 #{ } 是因为它会自动添加单引号
<!--int deleteMore(@Param("ids") String ids);-->
<delete id="batchDelete">delete from user where id in (${ids})  <!--示例:delete from user where id in (1, 2, 3)-->
</delete>

二 MyBatis 获取参数值的方式

  • #{ } 对应占位符赋值;${ } 对应字符串拼接,外侧需要加单引号
  • 不关心接口中方法的形参命名

1 单个字面量类型的参数

  • 可以以任意的名称获取参数的值,不在乎接口中的方法形参的名字,但最好见名知意
接口方法:
public interface ParamMapper {// 根据用户名查询用户信息User getUserByName(String username);
}映射文件:
<select id="getUserByName" resultType="param.pojo.User">select * from user where username = #{notmatters}select * from user where username = '${notmatters}'  <!--等价-->
</select>

2 多个字面量类型的参数

  • 接口中的方法参数为多个,MyBatis 会自动将这些参数放在一个 map 集合中(以arg0, arg1…为键,以参数为值 或 以 param1, param2…为键,以参数为值),通过键访问参数
接口方法:
public interface ParamMapper {// 验证登录User checkLogin(String username, String password);
}映射文件:
<select id="checkLogin" resultType="param.pojo.User">select * from user where username = #{arg0} and password = #{arg1}select * from user where username = #{param1} and password = #{param2}  <!--等价-->
</select>

3 Map 类型的参数

  • 方法参数为一个 Map 时,使用自定义的 key 访问 value
接口方法:
public interface ParamMapper {// 验证登录 参数为MapUser checkLoginByMap(Map<String, Object> mapParam);
}映射文件:
<select id="checkLoginByMap" resultType="param.pojo.User">select * from user where username = #{usernameKey} and password = #{passwordKey}
</select>测试:
...
Map param = new HashMap<String, Object>();
param.put("usernameKey", "伍佰");
param.put("passwordKey", "500");
userMapper.checkLoginByMap(param);

4 实体类类型的参数

  • 通过访问实体类对象中的属性名获取属性值
接口方法:
public interface ParamMapper {// 添加用户int insertUser(User paramUser);
}映射文件:
<insert id="insertUser">insert into user values (#{id}, #{username}, #{password}, #{age}, #{sex}, #{email})
</insert>

5 使用 @Param 注解的参数

  • 可以替代情况1和2
  • 作用是指定 map 的键:通过 @Param 注解标识接口中的方法参数,会将这些参数放在 map 集合中,以 @Param 注解的 value 属性值为键,以参数为值,替换键 arg0, arg1…
接口方法:
public interface ParamMapper {// 验证登录 参数使用注解User checkLoginByAnnotation(@Param("u") String username, @Param("p") String password);
}映射文件:
<select id="checkLoginByAnnotation" resultType="param.pojo.User">select * from user where username = #{u} and password = #{p}
</select>

三 自定义查询结果 resultMap

  • resultMap:设置自定义映射
    包含属性:
    id:表示自定义映射的唯一标识
    type:查询的数据要映射的实体类的类型

  • resultMap 的子标签:
    id:设置主键的映射关系
    result:设置普通字段的映射关系
    association:设置多对一的映射关系
    collection:设置一对多的映射关系
    每个标签包含属性:
    property:设置映射关系中实体类中的属性名
    column:设置映射关系中表中的字段名

1 处理表的字段和属性的映射关系

  • 若字段名和实体类中的属性名不一致,则可以通过 resultMap 设置自定义映射
  • 所有映射需要全部设置
  • 略有臃肿,可以使用别名的方式,只对不一致的表字段起别名
    select id, user_name userName, password, age, sex from user where user_name like "%"#{mohu}"%"
<resultMap id="userMap" type="param.pojo.User"><id property="id" column="id"></id><result property="userName" column="user_name"></result><result property="password" column="password"></result><result property="age" column="age"></result><result property="sex" column="sex"></result>
</resultMap><select id="testFuzzy" resultMap="userMap">select * from user where user_name like "%"#{fuzzy}"%"
</select>

2 处理多对一关系

示例:根据员工id,查询员工信息和部门信息

  • POJO(省略 Lombok 注解)
public class Employee {private Integer eid;private String ename;private Department department;
}public class Department {private Integer did;private String dname;
}
  • 接口方法
public interface ResultMapMapper {Employee getEmpAndDept(@Param("eid") Integer eid);}
  • 映射文件:使用 association 子标签后,左表 employee 可以访问属性 didassociation 标签需要指明属性 javaType
<mapper namespace="glad.mapper.ResultMapMapper"><resultMap id="myResultMap" type="glad.pojo.Employee"><id property="eid" column="eid"></id><result property="ename" column="ename"></result><association property="department" javaType="glad.pojo.Department"><id property="did" column="did"></id><result property="dname" column="dname"></result></association></resultMap><select id="getEmpAndDept" resultMap="myResultMap"><!--使用 association 后,employee 可以访问属性 did-->select * from employee left join department on employee.did = department.did where employee.eid = #{eid}</select>
</mapper>
  • 查询结果
    在这里插入图片描述

3 处理一对多关系

示例:根据部门id,查询其员工信息

  • POJO(省略 Lombok 注解)
public class Employee {private Integer eid;private String ename;private Integer did;
}public class Department {private Integer did;private String dname;List<Employee> emps;
}
  • 接口方法
public interface ResultMapMapper {Deptartment getDeptAndEmp(@Param("did") Integer did);}
  • 映射文件:使用 collection 标签声明类的 List 属性,并设置标签的 ofType 属性(代表容器内元素的属性)
<mapper namespace="glad.mapper.ResultMapMapper"><resultMap id="myResultMap" type="glad.pojo.Department"><id property="did" column="did"></id><result property="dname" column="dname"></result><collection property="emps" ofType="glad.pojo.Employee"><id property="eid" column="eid"></id><result property="ename" column="ename"></result></collection></resultMap><select id="getDeptAndEmp" resultMap="myResultMap">select * from department left join employee on department.did = employee.did where department.did = #{did}</select>
</mapper>

四 动态 SQL

1 if 标签

满足指定条件时,才会将 if 标签中的 SQL 加入

  • POJO:省略 Lombok 注解,和表中的属性名以 X 区分,注意在映射文件的各处访问的是表还是传入的参数
public class User {private Integer idX;private String usernameX;private String passwordX;private Integer ageX;private String sexX;private String emailX;
}
  • 接口方法
public interface DynamicMapper {// 根据任意信息查询List<User> getInfo(User user);}
  • 映射文件:
    数据库表的字段,和类的属性名不一致时,使用 resultMap,否则查询结果一直为 null
    为了保证格式正确,需要在 where 后加一个恒成立条件
<mapper namespace="dynamic.mapper.DynamicMapper"><resultMap id="myResultMap" type="dynamic.pojo.User"><id property="idX" column="id"></id><result property="usernameX" column="username"></result><result property="passwordX" column="password"></result><result property="ageX" column="age"></result><result property="sexX" column="sex"></result><result property="emailX" column="email"></result></resultMap><select id="getInfo" resultMap="myResultMap">select * from user where 1 = 1<if test="idX != '' and idX != null">and id = #{idX}</if><if test="usernameX != '' and usernameX != null">and username = #{usernameX}</if><if test="passwordX != '' and passwordX != null">and password = #{passwordX}</if><if test="ageX != '' and ageX != null">and age = #{ageX}</if><if test="sexX != '' and sexX != null">and sex = #{sexX}</if><if test="emailX != null and emailX !=''">and email = #{emailX}</if></select>
</mapper>

2 where 标签

一般和 if 标签结合使用:
where 标签中的 if 子标签条件都不满足,则 where 标签没有任何功能,即不会添加 where 关键字;
where 标签中的 if 子标签条件满足,则 where 标签会自动添加 where 关键字,并将条件最前方多余的 and 去掉

<select id="getEmpListByMoreTJ2" resultType="Emp">select * from t_emp<where><if test="ename != '' and ename != null">ename = #{ename}</if><if test="age != '' and age != null">and age = #{age}</if><if test="sex != '' and sex != null">and sex = #{sex}</if></where>
</select>

3 trim 标签

trim 用于去掉或添加标签中的内容

属性作用
prefixtrim 标签中的内容的前面添加某些内容
prefixOverridestrim 标签中的内容的前面去掉某些内容
suffixtrim 标签中的内容的后面添加某些内容
suffixOverridestrim 标签中的内容的后面去掉某些内容
  • 映射文件
<select id="getEmpListByMoreTJ" resultType="Emp">select * from t_emp<!--在以下部分的开头添加where,末尾删去and--><trim prefix="where" suffixOverrides="and"><if test="ename != '' and ename != null">ename = #{ename} and</if><if test="age != '' and age != null">age = #{age} and</if><if test="sex != '' and sex != null">sex = #{sex}</if></trim>
</select>

4 choose, when, otherwise 标签

choosewhenotherwise 的父标签,组合使用的效果相当于 Java 的 if, else if, else

  • 映射文件
<!--List<Emp> getEmpListByChoose(Emp emp);-->
<select id="getEmpListByChoose" resultType="Emp">select * from t_emp<where><choose><when test="ename != '' and ename != null">ename = #{ename}</when><when test="age != '' and age != null">age = #{age}</when><when test="sex != '' and sex != null">sex = #{sex}</when><when test="email != '' and email != null">email = #{email}</when></choose></where>
</select>

5 foreach 标签

用于执行批量操作

属性作用
collection设置要循环的数组或集合
item表示集合或数组中的每一个数据
separator设置元素之间的分隔符
open设置 foreach 标签中的内容的开始符
close设置 foreach 标签中的内容的结束符
  • 映射文件
<!--int insertMoreEmp(@Param("emps") List<Emp> emps);-->
<insert id="insertMoreEmp">insert into t_emp values<foreach collection="emps" item="emp" separator=",">(null,#{emp.ename},#{emp.age},#{emp.sex},#{emp.email},null)</foreach>
</insert><!--int deleteMoreByArray(@Param("eids") int[] eids);-->
<delete id="deleteMoreByArray">delete from t_emp where eid in<foreach collection="eids" item="eid" separator="," open="(" close=")">#{eid}</foreach>
</delete>

6 sql 标签

提取 SQL 语句的公共部分

<sql id="empColumns">eid, ename, age, sex, did
</sql>引用:
select <include refid="empColumns"></include> from t_emp

五 MyBatis 缓存

1 一级缓存

  • 一级缓存是 SqlSession 级别的,通过同一个 SqlSession 查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
  • 使一级缓存失效的四种情况:
    1. 不同的 SqlSession 对应不同的一级缓存
    2. 同一个 SqlSession 但是查询条件不同
    3. 同一个 SqlSession 两次查询期间执行了任何一次增删改操作
    4. 同一个 SqlSession 两次查询期间手动清空了缓存

2 二级缓存

  • 二级缓存是 SqlSessionFactory 级别,通过同一个 SqlSessionFactory 创建的 SqlSession 查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
  • 使二级缓存失效的情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
  • 开启二级缓存的步骤:
    1. 在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
    2. 在映射文件中设置标签 <cache>
    3. 二级缓存必须在 SqlSession 关闭或提交之后有效:一个 SqlSession 写入二级缓存,当第一个 SqlSession 关闭或提交后,供相同 SqlSessionFactory 创建的另一个 SqlSession 使用
    4. 查询的数据所转换的实体类类型必须实现序列化的接口 Serializable

3 查询顺序

  • 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
  • 如果二级缓存没有命中,再查询一级缓存
  • 如果一级缓存也没有命中,则查询数据库
  • SqlSession 关闭之后,一级缓存中的数据会写入二级缓存

六 逆向工程

逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成 Java 实体类、Mapper 接口、Mapper 映射文件

  1. 引入依赖、配置核心配置文件
    <!-- 控制Maven在构建过程中相关配置 --><build><!-- 构建过程中用到的插件 --><plugins><!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 --><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.4.0</version><!-- 插件的依赖 --><dependencies><!-- 逆向工程的核心依赖 --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.4.0</version></dependency><!-- 数据库连接池 --><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.2</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version></dependency></dependencies></plugin></plugins></build>
  1. 创建逆向工程的配置文件,必须命名为 generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!--targetRuntime: 执行生成的逆向工程的版本MyBatis3Simple: 生成基本的CRUDMyBatis3: 生成带条件的CRUD--><context id="DB2Tables" targetRuntime="MyBatis3"><!-- 数据库的连接信息 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/learn?serverTimezone=UTC"userId="root"password="123456"></jdbcConnection><!-- javaBean的生成策略--><javaModelGenerator targetPackage="mybatis.bean"targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /><property name="trimStrings" value="true" /></javaModelGenerator><!-- SQL映射文件的生成策略 --><sqlMapGenerator targetPackage="mybatis.mapper"targetProject=".\src\main\resources"><property name="enableSubPackages" value="true" /></sqlMapGenerator><!-- Mapper接口的生成策略 --><javaClientGenerator type="XMLMAPPER"targetPackage="mybatis.mapper" targetProject=".\src\main\java"><property name="enableSubPackages" value="true" /></javaClientGenerator><!-- 逆向分析的表 --><!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName --><!-- domainObjectName属性指定生成出来的实体类的类名 --><table tableName="employee" domainObjectName="Employee"/><table tableName="department" domainObjectName="Department"/></context>
</generatorConfiguration>
  1. 运行插件,生成的 xxExample 用于添加约束,具体使用方法见4
    在这里插入图片描述
    在这里插入图片描述
  2. 执行 CRUD
public class MyTest {@Testpublic void reverseTest() throws IOException {// ...InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class);// 使用QBC形式添加条件DepartmentExample departmentExample = new DepartmentExample();departmentExample.createCriteria().andDidEqualTo(1).andDnameEqualTo("保卫处");// 将之前添加的条件通过or拼接其他条件departmentExample.or().andDidIsNotNull();// 传入条件,执行sqlSystem.out.println(departmentMapper.countByExample(departmentExample));}
}

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

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

相关文章

国产操作系统发展离不开人才和市场

日前&#xff0c;中国 1024 程序员节盛大举行&#xff0c;一大批开源大咖齐聚千年岳麓&#xff0c;围绕开源标准、生态、人才发展等主题分享&#xff0c;共议开源软件与操作系统未来。其中&#xff0c;统信软件总经理刘闻欢表示&#xff0c;“有了市场才会被真正的用起来”&…

后端学习 - Redis

文章目录一 Redis 概述Redis 为什么是单线程&#xff0c;单线程为什么这么快&#xff1f;数据存储结构二 常用数据类型1 String2 HashHash 的扩容机制&#xff1a;渐进式 rehash*3 List4 Set5 Zset三 Redis 事务1 乐观锁与 watch 命令2 事务的三个特性四 Redis 持久化1 RDB(Red…

再被补刀!Flash又遭抛弃,你会怀念它吗?

喜欢就关注我们吧&#xff01;微软近日发布通知&#xff0c;称更新了关于 Adobe Flash Player 的删除。微软更新目录站点可下载更新 KB4577586&#xff0c;用于删除 Flash Player。此更新适用于所有受支持的操作系统版本。重要版本 Windows 10 和 Windows 8.1 的可选更新也将在…

4位加法器的设计代码verilog_HDLBits:在线学习Verilog(六 · Problem 25-29)

本系列文章将和读者一起巡礼数字逻辑在线学习网站 HDLBits 的教程与习题&#xff0c;并附上解答和一些作者个人的理解&#xff0c;相信无论是想 7 分钟精通 Verilog&#xff0c;还是对 Verilog 和数电知识查漏补缺的同学&#xff0c;都能从中有所收获。附上传送门&#xff1a;M…

译 | 将数据从Cosmos DB迁移到本地JSON文件

点击上方蓝字关注“汪宇杰博客”原文&#xff1a;Azure Tips and Tricks翻译&#xff1a;汪宇杰在Cosmos DB中使用数据迁移工具有一项重复的任务是将数据从一种数据库格式迁移到另一种数据库格式。我最近使用Cosmos DB作为数据库来存储Ignite大会发出的所有推文。然而一旦获得了…

在线教育后端开发项目总结

文章目录一 数据库访问接口1 MyBatis2 Spring Data JPA3 Spring Data MongoDB二 数据库1 MySQL2 MongoDB3 Redis三 开发规范化、响应格式与异常处理1 开发规范2 响应格式3 异常处理四 RabbitMQ五 Spring Cloud 相关工具1 Eureka2 Ribbon3 Feign4 Zuul 网关六 搜索服务1 Elastic…

通讯故障_掌握PLC必备知识,人机界面和 PLC 出现通讯故障如何分析解决

此次主要在阐述人机界面和 PLC 通讯时的模式状态&#xff0c;并列举了通讯故障实例。帮助大伙加深对这俩者的了解&#xff0c;掌握起来也不再是难题&#xff0c;解决掉拦路虎。一 台数 显 四 辊 卷 板 机PLC 控 制 系 统 核 心 与 人机界面在使用过程中&#xff0c;出现人机界面…

后端学习 - 设计模式与设计原则

文章目录设计原则1 单一职责原则2 开闭原则3 Liskov 替换原则4 依赖倒置原则5 接口隔离原则6 迪米特法则设计模式&#xff1a;创建型模式1 工厂模式2 抽象工厂模式3 单例模式设计模式&#xff1a;行为型模式1 观察者模式2 模板模式3 备忘录模式设计模式&#xff1a;结构型模式1…

ai的预览模式切换_AI字体制作,用AI制作创意阶梯式文字

本篇教程通过AI制作一款创意阶梯式文字&#xff0c;教程中有很多知识点需要掌握&#xff0c;比如路径分割为网络&#xff0c;3D效果应用等&#xff0c;我们要利用他们创造出我们需要的文字出来&#xff0c;具体是如何制作的&#xff0c;我们通过教程一起来学习一下吧。效果图&a…

新版本 Swashbuckle swagger 组件中的 坑

新版本 Swashbuckle swagger 组件中的 Servers 坑Intro上周做了公司的项目升级&#xff0c;从 2.2 更新到 3.1&#xff0c; swagger 直接更新到了最新&#xff0c;swagger 用的组件是 Swashbuckle.AspNetCore&#xff0c;然后遇到一个 swagger 的问题&#xff0c; 在本地测试是…

后端学习 - MySQL存储引擎、索引与事务

文章目录一 存储引擎1 MyISAM 与 InnoDB 的差异二 索引1 主键索引与二级索引、索引覆盖、延迟关联2 聚簇索引与非聚簇索引3 数据结构3.1 哈希表3.2 B树3.3 B树3.4 跳表3.5 为什么不使用红黑树3.6 为什么不使用B树**4 索引下推 ICP **5 索引失效&#xff08;索引不命中&#xff…

. NET5正式版本月来袭,为什么说gRPC大有可为?

当前企业正在慢慢改用微服务架构来构建面向未来的应用程序&#xff0c;微服务使企业能够有效管理基础架构&#xff0c;轻松部署更新或改进&#xff0c;并帮助IT团队的创新和学习。它还可以帮助企业能够设计出可以轻松按需扩展的应用程序&#xff0c;此外&#xff0c;随着企业转…

后端学习 - 操作系统

文章目录一 基本概念1 操作系统的特征2 操作系统的位置3 计算机的硬件组成4 中断与异常5 系统调用二 进程管理1 进程控制块 PCB&#xff08;Process Control Block&#xff09;2 进程的状态与转换3 进程间的通信4 线程5 调度算法6 死锁7 PV 操作三 内存管理1 内存的非连续分配2…

西门子触摸屏脚本程序_通过驿唐PLC501远程下载Smart Line触摸屏

通过驿唐PLC-501远程下载Smart Line触摸屏一、触摸屏设置将PLC-501和Smart 700 IE V3通过网线连到一起。触摸屏上电后&#xff0c;点击Control Panel进入控制面板界面。进入控制面板后&#xff0c;点击Ethernet设置IP地址&#xff0c;与PLC-501联网宝在同一个网段。联网宝的IP地…

.NET for Apache Spark 1.0 版本发布

.NET for Apache Spark 1.0 现已发布&#xff0c;这是一个用于 Spark 大数据的 .NET 框架&#xff0c;可以让 .NET 开发者轻松地使用 Apache Spark。该软件包由微软和 .NET Foundation 牵头&#xff0c;经过大约两年的开发。在 2019 年的 Spark AI 峰会上&#xff0c;微软曾宣…

fillrect不填充被覆盖的区域 mfc_quot;条带覆盖quot;猜想的中二证明:quot;球面条线覆盖或点覆盖quot;积分π...

注销&#xff1a;“黎曼猜想”复平面质数单向“虚”圆柱螺旋&#xff1a;几何法证明&#xff0c;技术应用​zhuanlan.zhihu.com假设有这样一部针点打印机从球心对球面打印&#xff0c;外部有一台蓝牙打印&#xff0c;球面打印蓝牙条带打印同步&#xff0c;球面被覆盖&#xff0…

让你变厉害的7个底层思维

职场&认知洞察 丨 作者 / findyi这是findyi公众号分享的第89篇原创文章如果把你的思维比做操作系统&#xff0c;那思维模型就是一个个App。这些App会给你提供新的视角&#xff0c;快速帮你决策&#xff0c;提升你的工作效率。顶级的思维模型能提高你成功的可能性&#xff0…

后端学习 - 计算机网络

文章目录一 基本概念1 计算机网络体系结构2 时延二 应用层&#xff1a;HTTP1 请求和响应报文、常见 header2 URL & RESTful API3 HTTP 协议通信过程4 HTTP 方法5 HTTP 状态码6 短连接、长连接与流水线7 Cookie8 Session三 应用层&#xff1a;HTTPS1 加密方式2 证书认证四 应…

跟我一起学Redis之Redis配置文件啃了一遍之后,从尴尬变得有底气了(总结了一张思维图)...

前言秋高气爽的一天&#xff0c;那时候年轻帅气的我正在参照着搜索引擎写代码&#xff0c;迷之微笑般的敲着键盘(又从搜索引擎上找到代码案例啦)&#xff0c;突然领导在小隔间里传来了呼唤声&#xff0c;然后有了以下场景&#xff1a;领导&#xff1a;小Z&#xff0c;你过来一下…

1093芯片做正弦波逆变器_长途自驾游“缺电”如何选购正确车载逆变器,避开商家套路...

让车友三分钟就能看明白如何选择车用逆变器&#xff0c;节约车友时间。长途自驾游充电是一个难题&#xff0c;手机充电还好办&#xff0c;其他笔记本、电饭煲、车载冰箱或者无人机电池等充电就会用到220V电源&#xff0c;那就必须用到逆变器(逆变器就是将12V或24V直流电&#x…