尚硅谷-MyBatis3.5.7-非零基础-笔记篇-01

Mybatis笔记_教程_最新2022_JAVA_ORM --- title: Mybatis笔记 --- # Mybatis学习笔记 ## Mybatis简介 一句话介绍:Mybatis是Java的ORM框架,通过写Mapper接口和XML文件【或者注解】来操作数据库。 ### MyBatis历史 - MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下,iBatis3.x正式更名为MyBa. 阅读详情

为什么是非零基础呢?因为本笔记不包括一些概念介绍、历史介绍、还有持久化层技术的对比了,概念那部分对我们直接去开发、或者说想快速做一些项目的童鞋是没有很大必要了吧,我们要的就是实践出真知!!!

官方-用户使用手册

看了下截止到目前MyBatis的最新版本是3.5.16,而尚硅谷发布MyBatis3.5.7零基础入门教程视频是2022年2月,最新版本的压缩包里就没有MyBatis法宝了,这里只能奉上3.5.7的法宝了。

那就是:官方发布的用户使用手册

借花献佛:通过网盘分享的文件:mybatis-3.5.7.pdf
链接: https://pan.baidu.com/s/1uI2gupmRiKVsFWWqbPg42A?pwd=gq52 提取码: gq52

正式开练 

教程开发环境

开发中很多问题可能都是环境配置不一致导致的,这里尚硅谷老师给出的教程环境列一下:

Idea2019、maven3.5.4、mysql5.7、jdk1.8

Maven – Maven Releases Historymaven与jdk的版本对照关系可参考:Maven – Maven Releases History

MyBatis初识

这里演示一下通过MyBatis实现增删改操作,这部分官方用户手册写得非常清楚了,一步一步怎么获取sqlSession、获取mapper接口实现类对象的。

准备实体类和数据库实体表

package com.coffeeship.pojo;

/**
 * @description: 实体类
 * @author: coffeeship
 * @date: 2024/10/24 15:01
 */
public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private String sex;
    private String email;

    public User() {
    }

    public User(Integer id, String username, String password, Integer age, String sex, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
        this.sex = sex;
        this.email = email;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

导入依赖

<!-- Mybatis核心 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>

从XML配置文件获取SqlSessionFactory

对应测试类

SqlSession代表和数据库的一次会话,用完必须释放。

SqlSession和Connection一样都是非线程安全的,不能作为成员变量,否则会产生资源竞争。每次使用都应该去获取新的对象。

@Test
public void testMyBatisInsert() throws IOException {

    //加载核心配置文件
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    //获取sqlSessionFactoryBuilder
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    //获取sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
    //获取SqlSession 默认不自动提交事务
//        SqlSession sqlSession = sqlSessionFactory.openSession();
    //设置事务自动提交
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    //获取Mapper对象 底层技术:代理
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    int result = mapper.insertUser();

    //手动提交事务
//        sqlSession.commit();
    System.out.println(result);
}

核心配置文件

包括数据库连接环境(事务管理器、数据连接池)

        transactionManager可选项:JDBC | MANAGED

        dataSource可选项:POOLED | UNPOOLED | JNDI

关于核心配置文件中的标签介绍,更详细的可以参考尚硅谷在2018年发布的mybatis教程。

        数据库连接池中的配置信息可通过properties文件注参;eg.

mapper 

引入dtd约束:http://mybatis.org/dtd/mybatis-3-config.dtd

<?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>
    <!--配置数据库连接的环境-->
    <environments default="development">
        <environment id="development">
            <!--事务管理器,JDBC:最原始的方式,事务的操作回滚需要手动配置-->
            <transactionManager type="JDBC"/>
            <!--数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:13306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="qts0922"/>
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件  来自源根的路径-->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

 编写Mapper XML文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace等于接口类的全限定名-->
<mapper namespace="com.coffeeship.mapper.UserMapper">

    <insert id="insertUser">
        insert into t_user values(null, 'admin', '123456', 18, '女', 'zh091699@163.com')
    </insert>
    <update id="updateUser">
        update t_user set username = 'administrator' where id = 2;
    </update>
    <delete id="deleteUser">
        delete from t_user where id = 3
    </delete>
</mapper>

执行测试类中的方法

然后查询部分,涉及到返回对象,可以参考spring对JDBC的封装,即JdbcTemplate,就是需要在XML配置文件中指定一下resultType或resultMap,就是一点点不一样哈。比如:

<!--指定SQL返回类型
resultType:设置默认的映射关系
resultMap:设置自定义的映射关系
-->
<select id="getUserById" resultType="com.coffeeship.pojo.User">
    select * from t_user where id = 2
</select>
<select id="getAllUser" resultType="com.coffeeship.pojo.User">
    select * from t_user
</select>
@Test
public void testMyBatisSelectOne() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = mapper.getUserById();
    System.out.println(user);
}

@Test
public void testMyBatisSelectAll() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> allUser = mapper.getAllUser();
    allUser.forEach(user -> System.out.println(user));
}

 设置别名

typeAliases标签

 MyBatis核心配置文件中的标签顺序

The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".

mybatis-config.xml :类型别名不区分大小写

type:需要设置别名的类的全路径

alias属性值可选,若设置了以设置的值为准,不区分大小写;

若未设置,则默认是类名,不区分大小写

<typeAliases>
    <typeAlias type="com.coffeeship.pojo.User" alias="user"/>
</typeAliases>

 UserMapper.xml

<!--    <select id="getUserById" resultType="com.coffeeship.pojo.User">
    select * from t_user where id = 2
</select>-->
<!--设置别名后...-->
<select id="getUserById" resultType="user">
    select * from t_user where id = 2
</select>
<!--    <select id="getAllUser" resultType="com.coffeeship.pojo.User">
    select * from t_user
</select>-->
<!--设置别名后...-->
<select id="getAllUser" resultType="user">
    select * from t_user
</select>

以包为单位设置默认别名,即类名、不区分大小写

<typeAliases>
<!--        <typeAlias type="com.coffeeship.pojo.User" alias="user"/>-->
    <package name="com.coffeeship.pojo"/>
</typeAliases>

以包为单位引入映射文件

<!--引入映射文件  来自源根的路径-->
<mappers>
    <!--<mapper resource="mappers/UserMapper.xml"/>-->
    <!--以包为单位引入映射文件
    要求: 1.mapper接口所在的包要和映射文件所在的包一致
    2.mapper接口要和映射文件的名字一致
    -->
    <package name="com.coffeeship.mapper"/>
</mappers>

MyBatis获取参数值的两种方式(重点)

MyBatis获取参数值的两种方式:${}和#{}     (JDBC原生方式)

${}的本质就是字符串拼接,#{}的本质就是占位符赋值

${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。

${}、#{}可通过任意名称赋值,获取参数只与参数位置有关,但建议见名知意。

分别对应JDBC Template中的字符串拼接(有SQL注入的风险)和占位符赋值:?

单个字面量类型的参数

若mapper接口中的方法参数为单个的字面量类型,此时可以使用${}和#{}

以任意的名称获取参数的值,注意${}需要手动加单引号。

多个字面量类型的参数

若mapper接口中的方法参数为多个时,此时MyBatis会自动将这些参数放在一个map集合中,

以arg0,arg1...为键,以参数为值;

以param1,param2...为键,以参数为值;

因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值,

注意${}需要手动加单引号。

map集合类型的参数

若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,

将这些数据放在map中,只需要通过${}和#{}访问map集合的键就可以获取相对应的值,

注意${}需要手动加单引号。

实体类类型的参数

若mapper接口中的方法参数为实体类对象时,此时可以使用${}和#{},

通过访问实体类对象中的属性名获取属性值,

注意${}需要手动加单引号。

使用@Param标识参数

可以通过@Param注解标识mapper接口中的方法参数,

此时,会将这些参数放在map集合中,

以@Param注解的value属性值为键,以参数为值;

以 param1,param2...为键,以参数为值;

只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号。


UserMapper接口

public interface UserMapper {

    User getUserById(Integer id);

    User getUserByNamePwd(String username, String password);

    User getUserByNameAge(Map<String, Object> map);

    User getUser(User user);

    User getUserByParam(@Param("paramName") String username, @Param("paramPwd") String password);
}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace等于接口类的全限定名-->
<mapper namespace="com.coffeeship.mapper.UserMapper">

    <!--单个字面量的参数,可以以任意名称获取参数的值,但建议”见名知意“-->
    <select id="getUserById" resultType="com.coffeeship.pojo.User">
        <!--select * from t_user where id = #{id}-->
        select * from t_user where id = #{anyName}
    </select>

    <!--多个字面量的参数,以arg0,arg1...为键或以param1,param2...为键-->
    <!--Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]-->
    <select id="getUserByNamePwd" resultType="com.coffeeship.pojo.User">
        <!--错误写法:select * from t_user where username = #{username} and password = #{password}-->
        <!--以下均为正确写法-->
        <!--select * from t_user where username = #{arg0} and password = #{arg1}-->
        <!--select * from t_user where username = #{param1} and password = #{param2}-->
        select * from t_user where username = #{arg0} and password = #{param2}
    </select>

    <!--map集合类型的参数,访问map集合的键就可以获取相对应的值-->
    <select id="getUserByNameAge" resultType="com.coffeeship.pojo.User">
        select * from t_user where username = #{name} and age = #{age}
    </select>

    <!--实体类类型的参数,访问实体类对象中的属性名获取属性值-->
    <select id="getUser" resultType="com.coffeeship.pojo.User">
        select * from t_user where id = #{id} and username = #{username}
    </select>

    <!--使用@Param标识参数,以@Param注解的value属性值为键或以 param1,param2...为键-->
    <select id="getUserByParam" resultType="com.coffeeship.pojo.User">
        <!--select * from t_user where username = #{paramName} and password = #{paramPwd}-->
        <!--select * from t_user where username = #{param1} and password = #{param2}-->
        select * from t_user where username = #{paramName} and password = #{param2}
    </select>


</mapper>

工具类

public class SqlSessionUtil {
    public static SqlSession getSqlSession() {
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        return sqlSession;
    }
}

测试类

public class ParamTest {
    
    @Test
    public void test01() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserById(2);
        System.out.println(user);
    }

    @Test
    public void test02() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserByNamePwd("admin", "123456");
        System.out.println(user);
    }

    @Test
    public void test03() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<>();
        map.put("name", "admin");
        map.put("age", 18);
        User user = mapper.getUserByNameAge(map);
        System.out.println(user);
    }

    @Test
    public void test04() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User(2, "administrator", "123456", 18, "女", "zh091699@163.com");
        User returnUser = mapper.getUser(user);
        System.out.println(returnUser);
    }

    @Test
    public void test05() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserByParam("admin", "123456");
        System.out.println(user);
    }
}

@Param源码解析

User getUserByParam(@Param("paramName") String username, @Param("paramPwd") String password);
<!--使用@Param标识参数,以@Param注解的value属性值为键或以 param1,param2...为键-->
<select id="getUserByParam" resultType="com.coffeeship.pojo.User">
    <!--select * from t_user where username = #{paramName} and password = #{paramPwd}-->
    <!--select * from t_user where username = #{param1} and password = #{param2}-->
    select * from t_user where username = #{paramName} and password = #{param2}
</select>

从这里进入

 mybatis创建了接口的实现类代理对象——接口式编程

原生:DAO接口、DAOImpl接口实现类

mybatis:mapper、mapper.xml

进入cachedInvoker的invoke方法

进入execute,匹配到当前是SELECT类型 

  public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    switch (command.getType()) {
      case INSERT: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      case SELECT:
        if (method.returnsVoid() && method.hasResultHandler()) {
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) {
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) {
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) {
          result = executeForCursor(sqlSession, args);
        } else {
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
          if (method.returnsOptional()
              && (result == null || !method.getReturnType().equals(result.getClass()))) {
            result = Optional.ofNullable(result);
          }
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
      throw new BindingException("Mapper method '" + command.getName()
          + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
    }
    return result;
  }

先看参数映射关系是如何放到map中的

再来看sql执行过程

MappedStatement对象中有属性statementType,属性值为PREPARED,表示预编译的;resultMaps,有一个值就是Mapper接口方法中指明的返回值User类;还有就是sqlCommandType,SQL的操作类型,即SELECT。

获取BoundSql对象,包含属性:1.解析后的sql,可以看到原生sql是用的?表示占位符

2.parameterMappings,记录占位符处对应的映射关系

3.parameterObject, 传入的参数及对应的参数值;键与parameterMappings中的property对应

委托代理,返回一个CacheKey

通过CacheKey 来封装缓存的 key 值,CacheKey 可以封装多个影响缓存项的因素。

缓存的作用就是提高查询速度,数据库中的sql也有对应的缓存机制,当你使用绑定变量的时候,判断sql执行的频率,可以考虑将sql缓存起来,也可以类比java中的热代码使用JIT编译一样。

将热点SQL缓存起来,下次只是改变传参而已,sql其实没变,这样查询速率就会很快。 

又到了激动人心的环节

这里MappedStatement对象中的cache是null,注意这里的cache与上面的CacheKey不是一回事!那MappedStatement里的这些属性都是啥意思呢?

可以参考这篇博主的介绍,cache是二级缓存策略,默认就是null。

https://juejin.cn/post/6886805132936216583

建立数据库连接,并通过反射执行了autoCommit的设置,再通过反射执行了preparedStatement方法,这里熟悉JDBC原生方式访问数据库的童鞋就知道了。

@Override
  public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, params);
      }
      if (EXECUTE_METHODS.contains(method.getName())) {
        if (isDebugEnabled()) {
          debug("Parameters: " + getParameterValueString(), true);
        }
        clearColumnInfo();
        if ("executeQuery".equals(method.getName())) {
          ResultSet rs = (ResultSet) method.invoke(statement, params);
          return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack);
        } else {
          return method.invoke(statement, params);
        }
      } else if (SET_METHODS.contains(method.getName())) {
        if ("setNull".equals(method.getName())) {
          setColumn(params[0], null);
        } else {
          setColumn(params[0], params[1]);
        }
        return method.invoke(statement, params);
      } else if ("getResultSet".equals(method.getName())) {
        ResultSet rs = (ResultSet) method.invoke(statement, params);
        return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack);
      } else if ("getUpdateCount".equals(method.getName())) {
        int updateCount = (Integer) method.invoke(statement, params);
        if (updateCount != -1) {
          debug("   Updates: " + updateCount, false);
        }
        return updateCount;
      } else {
        return method.invoke(statement, params);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }

method.invoke(statement, params)终于要通过反射给sql赋值了

赋完值后再看SQL语句

再赋第2个参数 

Executor接口的实现类对象delegate执行。 

这里就很熟悉了 ps.execute()也是通过反射去执行

resultSetHandler.handleResultSets(ps)应该是在封装返回结果

 好吧,这篇笔记就到这里结束吧,不然都看困了。。。

扒源码的路漫漫,其修远兮,吾将上下而求索~~~

mybatis-3.5.7.zip 立即下载

相关推荐

数理金融学笔记 Chap2 二叉树模型Binomial

2 二叉树模型与期权定价 Binomial Model and Option Pricing 文章目录2 二叉树模型与期权定价 Binomial Model and Option Pricing单期二叉树模型 One-step Binomial Model风险与无风险资产单期二叉树模型与无套利条件无套利定价 No Arbitrage Pricing风险中性定价 Risk Neutral PricingDelta套期保值 Delta Hedging两期二叉树模型 Two-Step Binomial Model

weixin_66831131的博客 2388

MyBatis_Learning_3.5.7

师从尚硅谷杨博超老师

三分明月落的博客 1363

从零构建物联网监控系统:STM32+迪文屏+WiFi模组的实战解析

本文详细解析了基于STM32微控制器、迪文串口屏和WiFi模组构建物联网监控系统的完整方案。从硬件选型、系统架构设计到数据交互实现,提供了包括迪文屏GUI开发、STM32通信协议、低功耗优化等实战经验,帮助开发者快速掌握物联网监控系统的核心技术。

docker7nomad的博客 730

MyBatis下载和环境搭建

MyBatis介绍 MyBatis官网 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。 下载MyBatis 进入官网,点击入门,再点击jar包地址,或者访问项目地址:http://github

花伤情犹在的博客 2709

B站DRM视频解密流程实战解析:从密钥获取到播放全流程

本文详细解析了B站DRM视频的解密全流程,从识别加密视频、捕获关键网络请求(如playurl接口的widevine_pssh数据),到逆向分析DRM SDK的JavaScript执行逻辑,最终手动模拟EME流程获取解密密钥,并使用mp4decrypt和ffmpeg工具完成视频文件的解密与合并。文章为开发者提供了从密钥获取到播放的完整实战指南。

weixin_29290379的博客 841

【Matlab/simulink/carsim】再生制动

【Matlab/simulink/carsim】再生制动

weixin_62311849的博客 621

尚硅谷-Mybatis笔记

尚硅谷ssm视频学习之Mybatis

GANTENJ的博客 864

dToF直方图之美

上面视频里如果你能看懂,那么就能理解对于dToF单点的测距问题,对于大部分的描述在AMS和ST里的手册都非常的详细,有疑问的可以后台来找我探讨,今天我们单纯从上层讨论成像的问题。作为dToF算法工程师,应该是对直方图敏感的,直方图的每个Count峰都会表征出问题,因为dToF的输出只有直方图,观察直方图能够逆推出dToF的很多东西,这也是大多数公司不愿意开放直方图和Raw data的缘故。以上是一个小面阵的分辨率,第一张是直方图,后面是基于直方图寻峰出来的成像ToF图,Peak图,以及噪声Noise图。

dream it possible 2995

Mybatis从3.4.0版本到3.5.7版本的迭代历程

mybatis从3.4.0版本到3.5.7版本的迭代历程。

乐只悠悠 3284

Altium Designer 20/21/22/23版本汉化与库管理全攻略(附避坑指南)

本文系统梳理了Altium Designer 20/21/22/23等多个版本的汉化方案与库管理全流程。针对不同版本的中文支持差异,提供了安全的汉化设置指南与版本选择建议。重点详解了原理图库、PCB封装库及集成库的创建、管理与团队协作最佳实践,并附有常见问题避坑指南,帮助硬件工程师高效搭建稳定的设计环境。

rgv234567的博客 1114

锂电池SOH预测 | 基于BP神经网络的锂电池SOH预测(附matlab完整源码)

锂电池SOH预测 | 基于BP神经网络的锂电池SOH预测(附matlab完整源码)

天天酷科研的博客 1114

尚硅谷MyBatis-Plus笔记001【简介、入门案例、基本CRUD】

MyBatisPlus

upward 1325

WPF在特定领域的应用:打造一款专业的图像编辑工具

WPF在特定领域的应用:打造一款专业的图像编辑工具,在软件开发的广阔领域中,Windows Presentation Foundation(WPF)以其强大的图形渲染能力和丰富的用户界面控件,为开发者提供了构建高性能、美观应用程序的平台。图像编辑工具作为一种对图形处理要求极高的应用类型,WPF 的特性使其成为理想的选择。本文将深入探讨如何使用 WPF 打造一款专业的图像编辑工具,涵盖从基础概念到实际代码实现的各个方面。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 6万+

MyBatis简介与环境搭建(尚硅谷)

MyBatis的简介 一、MyBatis历史 MyBatis框架里面是封装了JDBC,用于连接数据库,但是它比原先的JDBC更快速,更高效! MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁 移到了Google Code。随着开发团队转投Google Code旗下, iBatis3.x正式更名为MyBatis。 代码于 2013年11月迁移到Github。 iBatis一词来源于“internet”和“aba

金鳞踏雨 1352

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

尚硅谷项目 谷粒学院

尚硅谷项目 谷粒学院 Day01 项目介绍和Mybatis-plus 项目介绍: 1 什么是在线教育 1.1 基本概述 在线教育顾名思义,是以网络为介质的教学方式,通过网络,学员与教师即使相隔万里也可以开展教学活动;此外,借助网络课件,学员还可以随时随地进行学习,真正打破了时间和空间的限制,对于工作繁忙,学习时间不固定的职场人而言网络远程教育是最方便不过的学习方式。 1.2 发展潜力 所有人离不开教育:早期教育、课外辅导、少儿英语、职业教育、出国留学、商学院、移民服务……而在信息化爆发式发展的趋势下,在线教

qq_51443459的博客 2674

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

尚硅谷 MyBatis 新版视频教程发布

人是这样的—— 一旦有了对别人的期待, 就可能承受期待带给你的痛苦。 真实的世界很残酷, 永远不要把期待放在别人身上, 因为别人没有义务要实现你的期待。 除非…… 这个“别人”是尚硅谷! 总有人间一两风,填我十万八千梦。 众多谷粉期盼已久, 神超老师闭门狂撸, 等了好久终于等到今天, 盼了好久终于把梦实现: 他, 江湖上人称神超。 烫伤之后去搓澡,腿摔折了撑杆跳。 尚硅谷著名狠人: “觉得我帅的扣 1, “觉得佟刚老师帅的扣眼珠子。” 他, 先谷粉

m0_67698950的博客 639

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

尚筹网项目系列笔记01[转尚硅谷https://www.bilibili.com/video/BV1bE411T7oZ]

尚筹网尚筹网项目环境搭建1 环境搭建总体目标2 创建工程2.1 项目架构图2.2 工程创建2.3 Maven工程和Maven模块的介绍 尚筹网项目环境搭建 1 环境搭建总体目标 2 创建工程 2.1 项目架构图 2.2 工程创建 name groupId artifactId packaging atcrowdfunding01-admin-parent com.atguigu.crowd atcrowdfunding01-admin-parent pom atcrowdfundin

sweet987250的博客 1134

Springboot学习笔记 | 尚硅谷雷神

springboot学习笔记 这是我看b站雷神的springboot2做的

weixin_54232666的博客 1172

尚硅谷-尚庭公寓知识点

ThreadLocal的主要作用是为每个使用它的线程提供一个独立的变量副本,使每个线程都可以操作自己的变量,而不会互相干扰,其用法如下图所示。

weixin_68576312的博客 1088

【Java面试题】《尚硅谷经典Java面试题第一季(java面试精讲)》学习笔记

常用的是前两种REQUIRED:A和B都定义事务,A调用B,则B的事务不生效:A和B都定义事务,A调用B,B的事务生效。

liangjiayy的博客 1782

MyBatis笔记目录

视频教程链接:【尚硅谷】2022版MyBatis教程(细致全面,快速上手) 视频p数 笔记链接 简介 p01-05 1 - MyBatis简介 MyBatis历史、MyBatis特性、MyBatis下载、和其它持久化层技术对比(这部分和官方笔记内容差不多) p06-14 2 - 搭建MyBatis示例 开发环境、创建maven工程、建立sql表单、创建MyBatis核心配置文件、创建Mapper接口、创建MyBatis的映射文件、通过junit进行测试、加入log4j日志功能 p.

CherryChenieth的博客 1万+

学习: 尚硅谷Java项目之尚庭公寓(1)

导入在Result和中使用@Data@Getter注解,需要再common模块中引入lombok依赖启动项目。

Nan_Shu_614的博客 1057

SSM-CRUD SSM+VUE版本 (尚硅谷教程)

SSM-CRUD SSM+VUE版本 (尚硅谷教程) 项目说明: 后端: Spring、SpringMVC、Mybatis、Tomcat9 前端: Vue3、Element-plus 工具:IDEA2021、Navicat 1.创建Maven项目 2.整合SSM 见ssm整合步骤_CrazyAugust的博客-优快云博客! 3.CRUD 项目搭建 1.后端代码 1.导入相关依赖 pom.xml <?xml version="1.0" encoding="UTF-8"?> <projec

CrazyAugust的博客 1875

尚硅谷面试第一季说明

视频地址: 链接:https://pan.baidu.com/s/1OE5BwLK9p5aHJRYYCByraQ提取码:27hh 码云测试代码地址: https://gitee.com/ZhangShunHai/interview_atguigu_seasonone 博客目录地址: 01、自增变量 https://www.cnblogs.com/zsh-blogs/p/1059798...

weixin_34406086的博客 603

尚筹网 -- 1️⃣后台 -- 环境搭建

        本系列文章记录尚硅谷官网的尚筹网开发过程以及遇到的问题!

Syntactic Sugar 1075

尚筹网 —— 1、环境搭建

1、环境搭建总目标

Mr_zhangyj的博客 2693
上一篇: 尚硅谷-Spring6.0.2-手写IoC篇
下一篇: 尚硅谷-MyBatis3.5.7-非零基础-笔记篇-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值