MyBatis——Java与数据库再续前缘

news2024/9/26 1:16:04


迭代更新,更新时代

时代发展,发展技术

技术进步,进步迭代


——Lungcen

目录

MyBatis的简介入门

        1、硬编码

         2、操作繁琐

MyBatis简单入门

       1、处理硬编码

        2、处理操作繁琐

        3、参数传递

 MyBatis核心配置文件

配置文档的顶层结构

环境配置(environments)

类型别名(typeAliases)

Mapper代理开发

小动作

1、自动封装

2、特殊字符

        通过Mapper代理开发的参数传递

        1、单参数

        2、多参数

        1、注解的方式

        2、传一个封装对象类

        3、传一个Map集合


MyBatis的简介入门

        什么是mybatis呢?它是一个持久层框架,用来简化JDBC开发。了解持久层就需要知道Java的三层架构(例如:SSM框架、SSH框架

        框架:是一个半成品的软件、一套可以重用、通用、软件基础代码模型

        SSM架构,是三层结合所成的框架,分别是SpringSpringMVCMyBatis所组成

        SSH框架,是JAVA EE中三种框架所集成,分别是Struts,Spring,Hibernate框架所组成

Java中三层架构:表现层、业务层、持久层

业务层(代码逻辑)
        处理业务逻辑、处理一个业务的过程逻辑(运行逻辑、过程设计)

  

表现层(前端显示)
        接收请求并且展示数据,将一个业务层的业务展现出来,通常使用MVC模型来设计(展示界面、界面设计)

持久层(数据库)
        数据库交互,对一个业务进行操作时数据的处理(数据存储和处理、数据设计)

                         


                        简化JDBC的开发,那JDBC有什么需要简化的呢?

                     我们来将之前用JDBC写的代码分解来看有一下两种问题


        1、硬编码

        建立与数据库的连接,都需要写下面这段重复的代码,而且如果需要更改用户名和用户密码就需要改动代码(维护性稍差)

        我们这种没有编译、打包的,到还好,可以直接上手改代码、那种已经编译、打包过的,就需要改为代码后重新编译、打包、运行。

        //获取配置文件的方法
        Properties prop = new Properties();
        //加载配置文件
        prop.load(new FileInputStream("src/druid.properties"));
        //获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取连接
        Connection conn = dataSource.getConnection();
        

         同上面修改密码一样的原因,SQL语句是写死的,改SQL语句就要需要动代码(那个int id = 1,是手动传的参,就没有从前端获取了,为了方便学习嘛)

        int = 1;
        //定义SQL
        String sql = "select * from tb_brand where id = ?";

         2、操作繁琐

        我们为了防止SQL注入,使用了预编译的方式运行SQL语句,所以就需要手动设置参数,传值替代问号。传值的个数少到还好、一旦多起来就很繁琐

        //获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //传入参数
        pstmt.setString(1, id);
        //执行SQL
        ResultSet rs = pstmt.executeQuery();
        

         手动封装结果集也是一个操作繁琐的步骤,这么多代码不仅难写还容易出错

        //处理结果
        List<Object> list = new ArrayList<>();
        while(rs.next()){
            int id = rs.getInt("id");
            String brandName = rs.getString("brand_name");
            String companyName = rs.getString("company_name");
            int ordered = rs.getInt("ordered");
            String description = rs.getString("description");
            int status = rs.getInt("status");
            Brand brand = new Brand();
            brand.setId(id);
            brand.setBrandName(brandName);
            brand.setCompanyName(companyName);
            brand.setOrdered(ordered);
            brand.setDescription(description);
            brand.setStatus(status);
            list.add(brand);
        }
        System.out.println(list);
        //释放资源
        rs.close();
        pstmt.close();
        conn.close();

MyBatis简单入门

mybatis – MyBatis 3 | 入门https://mybatis.org/mybatis-3/zh/getting-started.html

        通过Maven配置Mybatis的jar包

  <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.5</version>
    </dependency>

        连接数据库,需要导入Mysql的驱动

 <!--添加mysql依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.22</version>
    </dependency>

        需要导入 测试类 来测试代码

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

        编写mybatis-config.xml文件(配置文件)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

        这里是配置数据库连接信息

        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>

       1、处理硬编码

        指定SQL映射文件(上面处理了数据库连接信息的硬编码,这里处理SQL语句的硬编码)

  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>

        处理SQL语句的配置文件的命名也是有规范的,我们是使用Mapper代理开发的,假如操作User表,就取名为UserMapper.xml,同理,处理Xxxx表,就取名XxxxMapper.xml。我们目前需要操作User表,就命名为UserMapper.xml

        <mapper>标签中namespace是指名称空间,不可省略的,作用是:当存在多个XxxxMapper时,并且可能会存在同样的方法,那么就可以通过 XxxxMapper.id里的内容 来找到对应的SQL语句

        <select>标签中id是SQL语句的唯一标识、resulType是返回值的类型(例如列表、int、一个封装的对象啥的……)

<?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">
<mapper namespace="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

         既然存在了SQL的映射文件,那么我们就可以把mybatis-config.xml文件中关于配置SQL映射文件的地方给修改一下

        如果配置文件mybatis-config.xml和SQL映射文件UserMapper.xml在同一级,那么可以直接写UserMapper.xml,不过由于编码的一些原因,不建议这么写

    <mappers>
        <mapper resource="com/zpark/mapper/UserMapper.xml"/>
    </mappers>

       当SQL的映射文件多了起来的时候,就需要写很多条,这是一个很繁琐的步骤!

         加载SQL映射文件这块,除了这么写,当你使用了Mapper代理开发后,可以使用包扫描的方式来加载SQL语句,使用 包加载 后就可以直接扫描整个包,而不是像上面那个一个一个的加载

    <mappers>
        <package name="com.zpark.mapper"/>
    </mappers>

        到这一步,基本上就消除了JDBC的硬编码问题,通过配置文件来改变与数据库的连接、通过SQL映射文件来修改SQL语句写死的问题,那目前还有操作繁琐问题的勒!

        2、处理操作繁琐

对于操作繁琐的问题:

        1、定义POJO类,来封装从数据库的信息

        2、加载配置文件、获取SqlSessionFactory对象

        3、获取SqlSession对象、执行SQL语句

        4、释放前面获取的资源

        定义POJO类、设置get、set方法、重写toString方法、构造方法

package com.zpark.pojo;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String gender;
    private String addr;

    public User(Integer id, String username, String password, String gender, String addr) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.gender = gender;
        this.addr = addr;
    }

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

    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 String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
}

        有了User类后,那么我们就可以封装数据库获取的数据,那么对于SQL映射文件就可以改一下(这里就自动把数据封装了)

<?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="test">
    <select id="selectAll" resultType="com.zpark.pojo.User">
        select * from tb_user
    </select>
</mapper>

        加载配置文件、获取对象(这里我们没有手动封装结果集,也能封装到对象中)

        public static void main(String[] args) throws IOException {
        //加载配置文件、获取sqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> users = sqlSession.selectList("test.selectAll");
        System.out.println(users);
        sqlSession.close();
    }

3、参数传递

        单参数:当 SQL语句需要参入一个参数时,需要添加一个parameterType属性表示传入参数的值类型,然后参数对应位置需要用 #{参数名} 表示

<mapper namespace="test">
    <select id="selectAll" parameterType="int" resultType="com.zpark.pojo.User">
        select * from tb_user where id = #{id}
    </select>
</mapper>

        传入参数则在执行SQL语句的时候

SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> users = sqlSession.selectList("test.selectAll", 2);

        多参数:由于mybatis的只支持设置一个paremeterType;所以如果要传递多个数值,单靠一个基础的数据类型是无法承载的

        遇到需要传递多个参数的时候,将parameterType设置成Map接口类型,利用对应的键值对,来设置多个参数

<mapper namespace="test">
    <select id="selectAll" parameterType="map" resultType="com.zpark.pojo.User">
        select * from tb_user where id = #{id} and username = #{username}
    </select>
</mapper>
qlSession sqlSession = sqlSessionFactory.openSession();
Map map = new HashMap();
map.put("id",1);
map.put("username", "三");
List<User> users = sqlSession.selectList("test.selectAll", map);

 MyBatis核心配置文件

         MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息

配置文档的顶层结构

  • configuration(配置)
    • properties(属性)
    • settings(设置)
    • typeAliases(类型别名)
    • typeHandlers(类型处理器)
    • objectFactory(对象工厂)
    • plugins(插件)
    • environments(环境配置)
      • environment(环境变量)
        • transactionManager(事务管理器)
        • dataSource(数据源)
    • databaseIdProvider(数据库厂商标识)
    • mappers(映射器)

在配置各个标签时,需要严格的遵守前后顺序 

环境配置(environments)

        MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。

        简单理解就是,先配置好多个可能用到的数据库,但你需要使用哪个数据库就将 <environments default="development"> 中的default值 改成 你所需要的数据库的 id

<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db1>
                <property name="username" value="Lungcen"/>
                <property name="password" value="123123"/>
            </dataSource>
        </environment>
        <environment id="kaifa">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db2"/>
                <property name="username" value="Lungcen"/>
                <property name="password" value="232323"/>
            </dataSource>
        </environment>
    </environments>

        不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境, 每个数据库对应一个 SqlSessionFactory 实例。所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推。

  

类型别名(typeAliases)

        类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。这样就可以在使用 domain.blog.Author 的地方用 Authour 来替代

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
</typeAliases>

        可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 com.zpark.pojo.User

的别名为 user

<typeAliases>
  <package name="com.zpark.pojo.User"/>
</typeAliases>

        其他的标签可以进入这个网址了解详情

mybatis – MyBatis 3 | 配置https://mybatis.org/mybatis-3/zh/configuration.html

Mapper代理开发

解决了在Mybatis中出现的两个问题

       1、 解决MyBatis的硬编码问题

        2、简化后期执行SQL

使用Mapper代理开发需要满足下面几点要求

        1、定义一个与SQL映射文件同名的Mapper接口,并且需要将Mapper接口和SQL映射文件在同一个目录下

        2、设置SQL映射文件的namespace属性为Mapper接口全限定名

        3、在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保存参数类型和返回值类型一致(插件MyBatisX可以更加轻松的解决)

        4、通过SqlSession的getMapper方法获取Mapper接口的代理对象,然后完成SQL的执行

要求1:在同一个文件目录下

        需要将Mapper接口 和 SQL映射文件在同一个目录

                1、直接放在同一个包下

                2、在resource中建一个和Mapper接口一样的包结构来放SQL映射文件(编译的时候会合并同的)

图中java包中的UserMapper就是Mapper接口

图中resource包中的UserMapper.xml就是SQL映射文件

图中resource包中的mybatis-config.xml就是mybatis配置文件

  

要求2:SQL映射文件中的命名空间(namespace属性)为Mapper接口全限定名 

<mapper namespace="com.zpark.mapper.UserMapper">
    <select id="selectAll" resultType="com.zpark.pojo.User">
        select * from tb_user
    </select>
</mapper>

要求3:在Mapper接口中定义方法 

        例如上面图片那个方法,定义了SQL的一个selectAll方法、返回值是User对象,那么在Mapper接口中就需要一个名为 selectAll ,返回值为 User 的方法 

        MyBatisX插件可以 实现XML中的SQL方法 和 接口中的方法 之间进行跳转,就不用来回翻;可以根据在接口中写的方法来 在XML中自动生成 statement 框架,SQL语句还是要自己写的

public interface UserMapper {
    List<User> selectAll();
}

  

使用Mapper代理开发的运行代码

public static void main(String[] args) throws IOException {
        //加载配置文件、获取sqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //获取sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.selectAll();
        System.out.println(users);
        sqlSession.close();
    }

  

小动作

1、自动封装

1、封装对象设置的属性名称和数据库中的列名不一致会导致无法自动封装,需要一些小动作

        1、设置别名(处理SQL)

                通过SQL语句的as 将设置的别名和封装对象中的属性名一致

        2、进行映射(处理MyBatis)

                写在BrandMapper.xml文件中,因为SQL语句是在SQL映射文件中执行,而BrandMapper.xml就是SQl映射文件,所以才写在其中

        <resultMap>中有两个子标签

                        一个是<id>对应主键的映射

                        另一个是<result>对应普通字段的映射

    <resultMap id="brandMap" type="brand">
        <result column="brand_name" property="brandName"></result>
        <result column="company_name" property="companyName"></result>
    </resultMap>

id :是唯一标识、指向这个映射

type :是映射的类型,指向封装对象

colum :是列名,指向数据库的列名

property :是属性名,指向封装对象的属性

        设置了映射,就在使用到的SQL语句中使用,将原来的  resultType="com.zpark.pojo.Brand"  替换成 resultMap="brandMap"

    <select id="selectAll" resultMap="brandMap">
        select *
        from tb_brand
    </select>

2、特殊字符

2、在SQL语句中,会存在一些特殊字符的问题,例如需要写 id < 2,如果只看SQL是没有问题的,但是我们是写在XML文件中,他会识别 < 为 标签 的一部分,所以需要进行特殊处理

        1、老办法、或者潜意识的办法,进行转义,例如 < 转义为 &lt;

        2、CDATA区,以"<![CDATA[ "开始,以" ]]>" 结束,在两者之间写不想被解析程序解析的代码,解析器是不对CDATA区中的内容进行解析

  

通过Mapper代理开发的参数传递

        1、单参数

                用#{id} 来接收id

                除了#{id}外,还可以用${id},前者可以看成预编译,后者则是SQL语句进行拼接

    <select id="selectAll" resultMap="brandMap">
        select *
        from tb_brand where id = #{id}
    </select>

        SQL映射文件更改后需要一个参数,那么在Mapper接口中设置一个形式参数

public interface BrandMapper {
    List<Brand> selectAll(int id);
}

        如此,调用的时候,只需要在后面添加一个实参就行

BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        List<Brand> users = mapper.selectAll(1);

        2、多参数

        类比单参数的过程,修改SQL语句再添加几个参数,Mapper接口中填入多个形参,调用的时候传入多个实参。但是这个是错误的,Mapper代理开发不支持这样使用

        1、注解的方式

SQL映射文件:关于SQL语句的书写,用多个占位符来给参数占位子

    <select id="selectOne" resultMap="brandMap">
        select *
        from tb_brand where id = #{id} and status = #{status}
    </select>

Mapper接口文件:利用Param注解就进行注解

public interface BrandMapper {
List<Brand> selectOne(@Param("id") int id, @Param("status") int status);  //注解
//    List<Brand> selectOne(Brand brand);  //对象
//    List<Brand> selectOne(Map map);  //集合
}

测试文件:获取SqlSessionFactory对象,然后获取SqlSession对象

SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectOne(1, 1);
System.out.println(brands);

        2、传一个封装对象类

注意:对象的属性名称需要和参数占位符一样

        SQL语句不需要改变、只要改动Mapper接口 和 调用方法的地方,修改实参和形参

public interface BrandMapper {
    List<Brand> selectAll(int id);
    List<Brand> selectOne(Brand brand);  //对象
//    List<Brand> selectOne(Map map);  //集合
}

        调用方法,由于是传入一个对象,所以需要先实例一个对象,然后按照SQL来设置值,最后在传入方法中去执行

        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        Brand brand = new Brand();
        brand.setId(1);
        brand.setStatus(1);
        List<Brand> brands = mapper.selectOne(brand);
        System.out.println(brands);

        3、传一个Map集合

注意:

SQL语句依旧不需要进行改动,只需要改动其他两个文件

public interface BrandMapper {
    List<Brand> selectAll(int id);
    List<Brand> selectOne(Map map);  //集合
}
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
Map map = new HashMap();
map.put("id", 1);
map.put("status", 1);
List<Brand> brands = mapper.selectOne(map);
System.out.println(brands);


迭代更新,更新时代

时代发展,发展技术

技术进步,进步迭代


——Lungcen

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

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

相关文章

MMsegmentaion自定义数据集运行出错AssertionError: failed to load image

问题 我的数据集中图像是TIF格式&#xff0c;4通道&#xff0c;想用mmsegmentation模型跑一下看看效果&#xff0c;按照官方手册里的方法自定义完数据集后&#xff0c;运行出错&#xff0c;错误截图如下。 解决 1.错误原因 通过上面的截图&#xff0c;发现错误出在红色框框…

vue动态引入静态资源

vue动态引入静态资源 静态资源位置&#xff08;../../assets/piecture/page404.jpg&#xff09;或者&#xff08;/assets/piecture/page404.jpg&#xff09; 错误引入方式 错误引入方式&#xff08;一&#xff09; <template><div><img :src"../../asset…

Spark-hadoop集群中8020:Connection refused

一、使用CentOs7虚拟机运行spark案例报出8020端口出现错误 前提条件&#xff0c;使用standalone模式下的Spark&#xff0c;使用spark-shell运行example中的相关测试案例spark-examples_2.12-3.0.0.jar&#xff0c;来计算pi。当spark-shell 停止掉后&#xff0c;集群监控base:40…

macos下安装john the ripper并配置zip2john+破解加密zip文件

为了破解加密的zip文件&#xff0c;需要用到john进行爆破密码。 1、首先使用homebrew安装john&#xff0c;可以安装它的增强版john-jumbo: brew install john-jumbo 2、安装后可以使用 john 命令验证&#xff1a; john 3、配置zip2john的环境——.zshrc下&#xff0c;&#x…

Linux Mint 21.2 ISO 镜像开放下载

导读Linux Mint 21.2 ISO 镜像于 2023 年 6 月 21 日公测&#xff0c;开发者在这段时间内收集并修复了用户反馈的诸多问题。 代号为“Victoria”的 Linux Mint 21.2 ISO 镜像于今天正式开放下载&#xff0c;新版本基于 Ubuntu 22.04 LTS&#xff0c;提供 Cinnamon 5.8、Xfce 4.…

CNN卷积详解

转载自&#xff1a;https://blog.csdn.net/yilulvxing/article/details/107452153 仅用于自己学习过程中经典文章讲解的记录&#xff0c;防止原文失效。 1&#xff1a;单通道卷积 以单通道卷积为例&#xff0c;输入为&#xff08;1,5,5&#xff09;&#xff0c;分别表示1个通道…

Flutter 添加 example流程

一、已有Flutter工程&#xff08;命令&#xff09;添加 example 1、cd 工程(flutter_plugin ,是自己创建的)根目录 例: flutter create example 执行命令创建example PS&#xff1a;cd example 后执行flutter doctor 后就可以看到效果 2、如果需要指定iOS/Android 语言,请添加…

从0到1,无代码开发如何简化产品创新流程

在当今竞争激烈的市场环境中&#xff0c;产品创新已经成为企业成功的关键因素之一。为了在市场上保持竞争力&#xff0c;企业需要不断地推出新产品或改进现有产品。然而&#xff0c;传统的开发流程往往耗时费力&#xff0c;且成本高昂。因此&#xff0c;简化产品创新流程成为了…

Could not locate supplied template: react+ts搭建

1. reactts创建 我们在是用下create-react-app之前要下载一下 npm install create-react-app -g使用一下命令创建ts的react框架 create-react-app my-app --scripts-versionreact-scripts-ts 2. 遇见问题 我们用以上创建之后会提示一段代码选择“Y”之后发现我们创建的项目…

分析npm run serve之后发生了什么?

首先需要明白的是&#xff0c;当你在终端去运行 npm run ****&#xff0c;会是什么过程。 根据上图的一个流程&#xff0c;就可以衍生出很多问题。 1&#xff0c;为什么不直接运行vue-cli-service serve? 因为直接运行 vue-cli-service serve&#xff0c;会报错&#xff0c…

浏览器的同源策略 - 跨域问题

1.什么是跨域 跨域问题的实质是浏览器的同源策略造成的。浏览器同源策略是浏览器为 JavaScript 施加的限制。简单点说就是非同源会出现如下等限制&#xff1a; 无法访问其他源下的网页的 Cookies&#xff0c;Storage等&#xff1b;无法访问其他源下的DOM对象和 JS 对象;无法使…

Verilog语法学习——LV7_求两个数的差值

LV7_求两个数的差值 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 根据输入信号a,b的大小关系&#xff0c;求解两个数的差值&#xff1a;输入信号a,b…

SpringBoot使用jetty和tomcat还有undertow以及ssl配置支持https请求

一般使用SpringBoot开发应用程序都是使用的tomcat 稍微注意点性能就使用undertow&#xff0c;配置支持https请求常用nginx来做代理&#xff0c;直接用SpringBoot配置还是很少的&#xff0c;八成用不到&#xff0c;就怕需要用到的时候又不能及时弄出来&#xff0c;于是记录一下。…

3d激光slam建图与定位(1)_基于ndt算法定位

一.代码实现流程 二.ndt算法原理 一.该算法定位有三个进程文件 1.map_loader.cpp用于点云地图的读取&#xff0c;从文件中读取点云后对这个点云地图进行旋转平移后发布点云地图到ros #include "map_loader.h"MapLoader::MapLoader(ros::NodeHandle &nh){std::st…

Cisco 路由器配置管理

大多数网络中断的最常见原因是错误的配置更改。对网络设备配置的每一次更改都伴随着造成网络中断、安全问题甚至性能下降的风险。计划外更改使网络容易受到意外中断的影响。 Network Configuration Manager 网络更改和配置管理 &#xff08;NCCM&#xff09;解决方案&#xff…

操作符(超详解)

操作符详解 1. 操作符分类2. 算术操作符3. 移位操作符3.1 左移操作符3.2 右移操作符 4. 位操作符5. 赋值操作符6. 单目操作符6.1 单目操作符介绍6.2 sizeof和数组 7. 关系操作符8. 逻辑操作符9. 条件操作符10.逗号表达式11.下标引用&#xff0c;函数调用和结构成员12.表达式求值…

【TypeScript】接口类型 Interfaces 的使用理解

导语&#xff1a; 什么是 类型接口&#xff1f; 在面向对象语言中&#xff0c;接口&#xff08;Interfaces&#xff09;是一个很重要的概念&#xff0c;它是对行为的抽象&#xff0c;而具体如何行动需要由类&#xff08;classes&#xff09;去实现&#xff08;implement&#x…

基于IP地址的证书实现https

基于IP地址实现传递数据的&#xff0c;默认的HTTP很容易被不法分子劫持数据&#xff0c;网络防洪是当下的互联网为确保安全&#xff0c;要用HTTPS协议更为妥当。 使用IP地址申请证书的主要条件&#xff0c;必须在申请认证过程&#xff0c;开放IP地址外网可以访问&#xff0c;包…

web漏洞-java安全(41)

这个重点是讲关于java的代码审计&#xff0c;看这些漏洞是怎么在java代码里面产生的。 #Javaweb 代码分析-目录遍历安全问题 这个漏洞原因前面文章有&#xff0c;这次我们看看这个漏洞如何在代码中产生的&#xff0c;打开靶场 解题思路就是通过文件上传&#xff0c;上传文件…

文件按关键字分组-切割-染色-写入excel

1. 背景 针对下面的文件data.csv&#xff0c;首先根据fid进行排序&#xff0c;然后分组&#xff0c;使相同fid的记录放到同一个excel文件中&#xff0c;并对每列重复的数据元素染上红色。 fid,user_id -1000078398032092029,230410010036537520 -1000078398032092029,23042301…