MyBatis使用Demo

文章目录

  • 01、Mybatis 意义
  • 02、Mybatis 快速入门
  • 04、Mapper 代理开发
  • 05、Mybatis 配置文件
  • 07、查询所有&结果映射
  • 08、查询-查看详情
  • 09、查询-条件查询
  • 10、查询-动态条件查询
    • 多条件动态查询
    • 单条件动态查询
  • 11、添加&修改功能
    • 添加功能
    • 修改功能
  • 12、删除功能
    • 删除一个
    • 批量删除
  • 13、参数传递

当前项目里面的 CRUD 接口都是基于前人已经封装好的 API、或者直接使用 mybatis-generator 插件生成的,将其底层和数据库打交道的关键层 Mybatis 进行了封装。但是我认为了解持久层原理还是很有必要的,因此决定从 Mybatis 基本用法出发,进一步地剖析其底层的一些关键源码,对 Mybatis 有个比较清晰的把握。

01、Mybatis 意义

在这里插入图片描述

02、Mybatis 快速入门

在这里插入图片描述

先写了一堆 pom.xml 依赖

<?xml version="1.0" encoding="UTF-8"?>
<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.jxz</groupId><artifactId>mybatis-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><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></dependencies></project>

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。

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><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:///mybatis?useSSL=false"/><property name="username" value="xxx"/><property name="password" value="xxx"/></dataSource></environment></environments><mappers><mapper resource="org/mybatis/example/BlogMapper.xml"/></mappers>
</configuration>
  1. 编写 SQL 映射文件 UserMapper.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 命名空间-->
    <mapper namespace="test"><select id="selectAll" resultType="com.jxz.pojo.User">select * from tb_user;</select>
    </mapper>
    
  2. 定义和 SQL 映射文件有关的实体 User

  3. Mybatis-config.xml 加载映射文件

<!--        加载 sql 映射文件--><mappers><mapper resource="UserMapper.xml"/></mappers>
  1. 创建 SqlSession 对象,执行 sqlSession 查询方法
package com.jxz;import com.jxz.pojo.User;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;/*** @Author jiangxuzhao* @Description Hello World Demo* @Date 2024/6/14*/
public class MyBatisDemo {public static void main(String[] args) throws IOException {// 1. 创建 SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSession 对象SqlSession sqlSession = sqlSessionFactory.openSession();// 3. 执行 sqlList<User> result = sqlSession.selectList("test.selectAll");System.out.println(result);// 4. 释放资源sqlSession.close();}
}

04、Mapper 代理开发

上面执行 sql 的时候还是碰到了硬编码

在这里插入图片描述

改成 Mapper 代理可以基于接口开发,但是有些约定需要遵循

在这里插入图片描述

  1. 定义同名的 Mapper Interface 并和 SQL 映射文件放在同一目录下(java 包和 resources 包最后编译都会放在一块),我项目中放在 com/jxz/mapper 目录下
  2. 修改 UserMapper.xml 中的 namespace = 接口全限定名 com.jxz.mapper.UserMapper
<?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 命名空间-->
<mapper namespace="com.jxz.mapper.UserMapper"><select id="selectAll" resultType="com.jxz.pojo.User">select * from tb_user;</select>
</mapper>
  1. Mapper 接口中定义方法,与SQL 映射文件 id、参数类型、返回值一致。
package com.jxz.mapper;import com.jxz.pojo.User;import java.util.List;/*** @Author jiangxuzhao* @Description* @Date 2024/6/14*/
public interface UserMapper {List<User> selectAll();
}
  1. Mybatis-config 配置文件加载 SQL 映射文件的路径需要修改,改成 UserMapper 接口以及 SQL 映射文件共同所在的包路径
    <mappers>
<!--        Mapper 代理方式--><package name="com.jxz.mapper"/></mappers>
  1. 从 SqlSession 中拿到代理对象查询
package com.jxz;import com.jxz.mapper.UserMapper;
import com.jxz.pojo.User;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;/*** @Author jiangxuzhao* @Description Mapper 代理方式* @Date 2024/6/14*/
public class MybatisDemo2 {public static void main(String[] args) throws IOException {// 1. 创建 SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSession 对象SqlSession sqlSession = sqlSessionFactory.openSession();// 3. 获取 UserMapper 代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);List<User> users = userMapper.selectAll();System.out.println(users);// 4. 释放资源sqlSession.close();}
}

执行路径就是 SqlSession 根据 mybatis-config.xml 中 下配置的包路径找到 UserMapper Interface,相同目录下找到 UserMapper.xml SQL 配置文件;在调用 selectAll 方法时对应到 SQL 配置文件中的 id = ,也就找到了配置的 SQL 语句。

05、Mybatis 配置文件

就是前面为了生成 SqlSessionFactoryBuilder 的 mybatis-config.xml 文件

在这里插入图片描述

我在这里配置了个别名

<typeAliases><package name="com.jxz.pojo"/>
</typeAliases>

这样子在 UserMapper.xml SQL 配置文件中,resultType 就可以直接使用别名了,即 Pojo 类的首字母小写的非限定类名

<!--Mappper 代理模式为接口全限定名-->
<mapper namespace="com.jxz.mapper.UserMapper"><select id="selectAll" resultType="user">select * from tb_user;</select>
</mapper>

07、查询所有&结果映射

像 04 的 UserMapper 代理开发一样,这章使用 BrandMapper 进行更复杂场景的开发,包含结果映射的相关知识。

数据库表的字段名称 和 实体类的属性名称不一样,不能自动封装数据。

<resultMap id="brandResultMap" type="brand">
<!--
id: 完成主键字段映射
column: 表的别名
property: 实体类的属性名
result: 完成一般字段映射
column: 表的别名
property: 实体类的属性名
--><result column="brand_name" property="brandName"/><result column="company_name" property="companyName" />
</resultMap>
<select id="selectAll" resultMap="brandResultMap">select *from tb_brand;
</select>
resultMap:1. 定义 <resultMap> 标签2. 在<select> 标签中,使用 resultMap 属性替换 resultType 属性

08、查询-查看详情

Brand selectById(int id);
<select id="selectById" resultMap="brandResultMap">select *from tb_brandwhere id = #{id}
</select>

09、查询-条件查询

多条件查询

总共有3种传参方式
在这里插入图片描述

<!--条件查询
--><select id="selectByCondition" resultMap="brandResultMap">select *from tb_brandwhere status = #{status}and company_name like #{companyName}and brand_name like #{brandName}</select>
/***  条件查询*  参数接收*  1. 散装参数:如果方法中有多个参数,需要使用 @Param("SQL占位符名称")*  2. 对象参数:对象的属性名称要和参数的占位符一致*  3. map 集合参数* @return*/
List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);List<Brand> selectByCondition(Brand brand);List<Brand> selectByCondition(Map map);

10、查询-动态条件查询

多条件动态查询

上面的条件查询在 SQL 配置文件中写死了,如果 status,companyName,brandName任意一个条件没传递,类似 status = null,最终就会查询不出来东西,因此需要配置动态 SQL 查询语句,判断 status 是否为 null。

<select id="selectByCondition" resultMap="brandResultMap">select *from tb_brandwhere<if test="status != null">status = #{status}</if><if test="companyName !=null and companyName !=''">and company_name like #{companyName}</if><if test="brandName !=null and brandName !=''">and brand_name like #{brandName}</if>
</select>

但这样有个问题,如果仅用到了 companyName 这个条件,拼接的查询语句就是 “where and company_name like #{companyName}”,不符合 SQL 语法了。

为了解决这个问题,可以使用两种方法

1. 恒等式
2. <where> 替换 where 关键字

用 标签比较优雅,替换掉 SQL 语句中的 where 关键字

<select id="selectByCondition" resultMap="brandResultMap">select *from tb_brand<where><if test="status != null">status = #{status}</if><if test="companyName !=null and companyName !=''">and company_name like #{companyName}</if><if test="brandName !=null and brandName !=''">and brand_name like #{brandName}</if></where>
</select>

单条件动态查询

和多条件实现的结果差不多,相当于是用户去选了某个 where 属性来生效

11、添加&修改功能

添加功能

在这里插入图片描述

void add(Brand brand);

这里并没有 insert into id 这个属性

<insert id="add">insert into tb_brand(brand_name, company_name, ordered, description, status)values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
</insert>
    @Testpublic void testAdd() throws IOException {int status = 1;String companyName = "阿里巴巴";String brandName = "阿里巴巴";int ordered = 1;String description = "des";Brand brand = new Brand();brand.setStatus(status);brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setOrder(ordered);brand.setDescription(description);// 1. 创建 SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSession 对象SqlSession sqlSession = sqlSessionFactory.openSession();// 3. 获取代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);brandMapper.add(brand);// 提交事务sqlSession.commit();// 4. 释放资源sqlSession.close();}

其中别忘了手动提交事务

主键返回:

添加订单以后,想继续往订单里面添加对应的订单项,就需要拿到添加订单的主键 id
在这里插入图片描述

设置 useGeneratedKeys 和 keyProperty 两个属性进行回绑

 <insert id="add" useGeneratedKeys="true" keyProperty="id">insert into tb_brand(brand_name, company_name, ordered, description, status)values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status})</insert>

也不需要再去回查 brand 对象了,直接拿到原来构造的插入对象 brand.getId() 获取就可以了

// 3. 获取代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
brandMapper.add(brand);
Integer id = brand.getId();
System.out.println(id);

修改功能

修改全部字段:

将需要修改的对象作为入参,传入 id 就是 SQL 配置文件中的 where id = #{id},最终返回修改成功的行数

int update(Brand brand);
<update id="update" >update tb_brandsetbrand_name = #{brandName},company_name = #{companyName},ordered = #{ordered},description = #{description},status = #{status}where id = #{id}</update>
  @Testpublic void testUpdate() throws IOException {// idint id = 6;int status = 1;String companyName = "阿里巴巴n";String brandName = "阿里巴巴";int ordered = 1;String description = "des牛逼牛逼";Brand brand = new Brand();// 直接将 id 填充进 brandbrand.setId(id);brand.setStatus(status);brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setOrder(ordered);brand.setDescription(description);// 1. 创建 SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSession 对象SqlSession sqlSession = sqlSessionFactory.openSession();// 3. 获取代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);// 会根据 id 去填充 SQL 语句int count = brandMapper.update(brand);System.out.println(count);// 提交事务sqlSession.commit();// 4. 释放资源sqlSession.close();}

12、删除功能

删除一个

int deleteById(int id);
<delete id="deleteById">delete from tb_brandwhere id = #{id}
</delete>
@Test
public void testDeleteById() throws IOException {// idint id = 7;// 1. 创建 SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSession 对象SqlSession sqlSession = sqlSessionFactory.openSession();// 3. 获取代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);int count = brandMapper.deleteById(id);System.out.println(count);// 提交事务sqlSession.commit();// 4. 释放资源sqlSession.close();
}

批量删除

delete from tb_brand

where id

in (?,?,?)

int deleteByIds(@Param("ids") int[] ids);
<!--  mybatis 会将数组参数,封装为一个 Map 集合* 默认: key = array  value = 数组* 使用 @Param 注解改变 Map 集合的默认 key 的名称-->
<delete id="deleteByIds">delete from tb_brandwhere id in<foreach collection="array" item = "id" separator="," open="(" close=")">#{id}</foreach>
</delete><delete id="deleteByIds">delete from tb_brandwhere id in<foreach collection="ids" item = "id" separator="," open="(" close=")">#{id}</foreach>
</delete>
@Test
public void testDeleteByIds() throws IOException {// idint[] ids = {10};// 1. 创建 SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSession 对象SqlSession sqlSession = sqlSessionFactory.openSession();// 3. 获取代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);int count = brandMapper.deleteByIds(ids);System.out.println(count);// 提交事务sqlSession.commit();// 4. 释放资源sqlSession.close();
}

13、参数传递

多个参数进行传递查询的时候

List<User> selectByCondition(String username, String password);

如果不通过 @Param 注解对其进行标注,直接使用类似下面的语句进行查询

<select id="selectByCondition" resultType="user">select *from tb_userwhere username = #{username}and password = #{password}
</select>

会抛出如下异常:

Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]

简单来说就是找不到传递入参的映射关系了

但是 SQL 配置文件查询语句改成如下就可以查询出来的东西

<select id="selectByCondition" resultType="user">select *from tb_userwhere username = #{param1}and password = #{param2}
</select>

其主要原因在于多个参数传递的时候,Mabatis 在进行参数解析的时候,会将入参封装为 Map 集合,比如两个入参则会做如下操作

map.put("arg0", 参数值1)
map.put("param1", 参数值1) 
map.put("arg1", 参数值2)
map.put("param2", 参数值2) 

源代码在 org.apache.ibatis.reflection.ParamNameResolver#getNamedParams 中

public Object getNamedParams(Object[] args) {final int paramCount = names.size();if (args == null || paramCount == 0) {return null;} else if (!hasParamAnnotation && paramCount == 1) {Object value = args[names.firstKey()];return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);} else {final Map<String, Object> param = new ParamMap<>();int i = 0;for (Map.Entry<Integer, String> entry : names.entrySet()) {// map.put("arg0", 参数值1)param.put(entry.getValue(), args[entry.getKey()]);// add generic param names (param1, param2, ...)final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);// ensure not to overwrite parameter named with @Paramif (!names.containsValue(genericParamName)) {// map.put("param1", 参数值1) param.put(genericParamName, args[entry.getKey()]);}i++;}return param;}}

如果使用 @Param 注解

List<User> selectByCondition(@Param("username") String username, String password);

arg0 会被替换为 username

map.put("username", 参数值1)
map.put("param1", 参数值1) 
map.put("arg1", 参数值2)
map.put("param2", 参数值2) 

在这里插入图片描述

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

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

相关文章

ubuntu 18.04 安装vnc

如何在Ubuntu 18.04安装VNC | myfreax sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt install tigervnc-standalone-server tigervnc-common vncserver sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils sudo apt ins…

滴滴出行 大数据研发实习生【继任】

大数据研发实习生JD 职位描述 1、负责滴滴核心业务的数据建设&#xff0c;设计并打造适应滴滴一站式出行平台业务特点的数仓体系。 2、负责抽象核心业务流程&#xff0c;沉淀业务通用分析框架&#xff0c;开发数仓中间层和数据应用产品。 3、负责不断完善数据治理体系&#xff…

Excel报表

(Apache POI) 入门案例 P164 使用POI需要导入下面2个坐标&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId> </dependency> <dependency><groupId>org.apache.poi</groupId>&…

uni-app 小程序:显示图片并且点击图片展示大图

效果如图所示&#xff1a; 在页面显示一张图片&#xff0c;然后点击该张图片后显示大图。点击大图就可以关闭大图。 实现的主要代码如下&#xff1a; <image :src"imgpath" mode"aspectFill" click"imgPreview(imgArr)"></image> 其…

Spring Web MVC之过滤器Filter和拦截器HandlerInterceptor的区别和用法

作用时机不一样 Spring 框架有一个很重要的类DispatcherServlet。这个类继承了HttpServlet&#xff0c;HttpServlet实现了Servlet接口。相当于图片中的Servlet。所有和Spring框架相关配置&#xff0c;例如注解、xml配置、其他数据库连接配置、bean配置、拦截器配置等其他配置&…

CleanMyMacX4.15.4如何优化苹果电脑系统缓存,告别MacBook卡顿,提升mac电脑性能

你是否曾为苹果电脑存储空间不够而烦恼&#xff1f;是否曾因系统运行缓慢而苦恼&#xff1f;别担心&#xff0c;今天我要给大家种草一个神器——CleanMyMac&#xff01;这款软件可以帮助你轻松解决苹果电脑的种种问题&#xff0c;让你的电脑焕然一新&#xff01; 让我来给大家介…

【iOS】编译二进制文件说明

编译二进制文件说明 如何生成文件路径文件说明第一部分&#xff1a;.o文件第二部分&#xff1a;link第三部分&#xff1a;Segment第四部分&#xff1a;Symbol 如何生成 使用Xcode进行编译 &#xff0c;会生成二进制相关文件&#xff0c;可以更详细看产物的布局 项目Target -&…

Android中的消息异步处理机制及实现方案

基本介绍 当我们需要执行复杂的计算逻辑&#xff0c;网络请求等耗时操作时&#xff0c;服务器可能不会立即响应请求&#xff0c;如果不将这类操作放在子线程中运行&#xff0c;就会导致主线程被阻塞住&#xff0c;从而影响用户的使用体验如果想要更新应用程序中的UI控件&#…

ASM字节码操纵框架实现AOP

前言 使用ASM改写字节码实现Aop&#xff0c;是最快的Aop实现方式。 我猜你肯定懂AOP 凡是学习Spring框架&#xff0c;必然会深入了解AOP的原理以及实现。这里做下简单总结 Spring默认采取的是动态代理机制实现AOP&#xff0c;当动态代理不可用时&#xff08;代理类无接口&a…

Mac M3 Pro安装Hadoop-3.3.6

1、下载Hadoop安装包 可以到官方网站下载&#xff0c;也可以使用网盘下载 官网下载地址&#xff1a;Hadoop官网下载地址 网盘地址&#xff1a;https://pan.baidu.com/s/1p4BXq2mvby2B76lmpiEjnA?pwdr62r提取码: r62r 2、解压并添加环境变量 # 将安装包移动到指定目录 mv …

FPGA - 数 - 加减乘除

一&#xff0c;数的表示 首先&#xff0c;将二进制做如下解释&#xff1a; 2的0次方1 2的1次方2 2的2次方4 2的3次方8 ..... 以此类推&#xff0c;那么任何整数&#xff0c;或者说任意一个自然数均可以采用这种方式来表示。 例如&#xff0c;序列10101001&#xff0c;根据上述…

Unity贪吃蛇改编【详细版】

Big and small greedy snakes 游戏概述 游戏亮点 通过对称的美感&#xff0c;设置两条贪吃蛇吧&#xff0c;其中一条加倍成长以及加倍减少&#xff0c;另一条正常成长以及减少&#xff0c;最终实现两条蛇对整个界面的霸占效果。 过程中不断记录两条蛇的得分情况&#xff0c…

【Unity】RPG2D龙城纷争(二)关卡、地块

更新日期&#xff1a;2024年6月12日。 项目源码&#xff1a;后续章节发布 索引 简介地块&#xff08;Block&#xff09;一、定义地块类二、地块类型三、地块渲染四、地块索引 关卡&#xff08;Level&#xff09;一、定义关卡类二、关卡基础属性三、地块集合四、关卡初始化五、关…

VCG显示——汉字,数字,图像

详细的介绍资料&#xff1a; 【从零开始走进FPGA】 玩转VGA http://www.cnblogs.com/spartan/archive/2011/08/16/2140546.html 【FPGA实验】基于DE2-115平台的VGA显示_vga接口实验 de2-115-CSDN博客 【FPGA】VGA显示文字、彩条、图片——基于DE2-115-CSDN博客 一.VCG原理 1.1…

时序预测 | MATLAB实现TCN-Transformer时间序列预测

时序预测 | MATLAB实现TCN-Transformer时间序列预测 目录 时序预测 | MATLAB实现TCN-Transformer时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-Transformer时间序列预测&#xff1b; 2.运行环境为Matlab2023b及以上&#xff1b; 3.data为数…

Python **运算符(python**kwargs:参数解包)(kwargs:keyword arguments)

文章目录 Python中的 ** 运算符&#xff1a;参数解包参数解包基础语法和示例 在函数定义中使用 **示例代码 使用场景和好处1. 灵活性&#xff1a;使用 **kwargs 允许函数设计得更加灵活&#xff0c;可以接受未来可能增加的新参数而无需修改函数定义。2. 可读性和可维护性&#…

Kali中安装和使用docker的学习笔记

一、常见命令 ctrl 、shift、 &#xff1a; 窗口变大&#xff1b; ctrl 、- &#xff1a;窗口变小&#xff1b; ctrl L&#xff1a; 清屏 &#xff1b; sudo su : 切换root 用户&#xff1b; ip addr / ifconfig: 获取IP地址&#xff1b; systemctl start ssh…

B端颜值无所谓?麻痹自己可以,麻痹业务人员和客户试一试。

很多老铁觉得B端系统颜值和体验无所谓&#xff0c;功能好就行了&#xff0c;我不认同这种说法&#xff0c;我觉得优秀的B端系统应该是内外兼修的&#xff0c;而不是偏科的。你想一想你费尽研发的系统&#xff0c;就是因为颜值问题&#xff0c;你的业务人员没信息推销&#xff0…

北方工业大学24计算机考研情况,学硕专硕都是国家线复试!

北方工业大学&#xff08;North China University of Technology&#xff0c;NCUT&#xff09;&#xff0c;简称“北方工大”&#xff0c;位于北京市&#xff0c;为一所以工为主、文理兼融&#xff0c;具有学士、硕士、博士培养层次的多科性高等学府&#xff0c;是中华人民共和…

GitLab教程(四):分支(branch)和合并(merge)

文章目录 1.分支&#xff08;branch&#xff09;&#xff08;1&#xff09;分支的概念&#xff08;2&#xff09;branch命令 2.合并&#xff08;merge&#xff09;&#xff08;1&#xff09;三个命令pullfetchmergegit fetchgit mergegit pull &#xff08;2&#xff09;合并冲…