Mybatis的基本使用

什么是Mybatis?

  1. Mybatis是一个简化JDBC的持久层框架,MyBatis是一个半自动化框架,是因为它在SQL执行过程中只提供了基本的SQL执行功能,而没有像Hibernate那样将所有的ORM操作都自动化了。在MyBatis中,需要手动编写SQL语句,但是它提供了很多便捷的操作,例如参数映射、结果集映射、缓存机制等等,使得开发者能够更加灵活地操作SQL。此外,MyBatis还提供了许多插件机制,可以对SQL执行流程进行拦截和修改,以满足各种不同的需求。这也是MyBatis相对于其他ORM框架的一个优点。
  2. 持久层:负责将数据保存到数据库的那一层代码
  3. JavaEE三层架构:表现层,业务层,持久层
  4. 框架:写好部分代码的半成品软件

JDBC的缺点:

  1. 硬编码:
    • 注册驱动,获取连接的那部分代码不灵活,改变的时候会很麻烦
    • 写死的SQL语句没有那么灵活
  2. 操作繁琐
    • 需要手动设置参数(prepareStatement)
    • 手动封装结果集(resultSet)

Mybatis的优点

  1. 硬编码–》利用**配置文件(xml)**可以减少硬编码的编写
  2. 操作繁琐–》底层自动完成参数的设置以及结果集的封装
  3. Mybatis 免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作

Mybatis快速入门(mybatis-demo)

  • 非maven项目要使用 MyBatis, 只需将 mybatis-x.x.x.jar文件置于类路径(classpath)中即可。
  • 如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中

Mapper代理开发:

使用Mapper代理方式,必须满足以下要求:

  1. 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下(紧对于使用包扫描方式映射xml文件)。如下图:
    在这里插入图片描述
    注意:这里的UserMapper.xml里面的内容可以到mybatis官网上面粘贴进来的,然后加以修改一下就能成为我们自己的代码了
<?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="com.knife.mapper.BrandMapper"><!--  只有这里namespace的路径是需要修改的  -->
</mapper>
  1. 设置SQL映射文件的namespace属性为Mapper接口全限定名(即对应mapper接口的路径)
    在这里插入图片描述
  2. 在 Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
    在这里插入图片描述
  • 注意:
    • 如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载(即在mybatis-config.xml文件下配置)。也就是将核心配置文件的加载映射配置文件的配置修改为
<mappers>
<!--加载sql映射文件-->
<!-- <mapper resource="com/itheima/mapper/UserMapper.xml"/>-->
<!--Mapper代理方式-->
<package name="com.itheima.mapper"/>
</mappers>

Mybatis的核心配置(mybatis-config.xml)

在这里插入图片描述

环境配置

  1. 在核心配置文件的 environments 标签中其实是可以配置多个 environment ,使用 id 给每段环境起名,在environments 中使用 default=‘环境id’ 来指定使用哪儿段配置。我们一般就配置一个 environment 即可。
<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?useSSL=false&amp;serverTimeZone=UTC"/>
		<property name="username" value="root"/>
		<property name="password" value="1234"/>
		</dataSource>
	</environment>
	
	<environment id="test">
		<transactionManager type="JDBC"/>
		<dataSource type="POOLED">
		<!--数据库连接信息-->
		 <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://localhost:3306/db1?useSSL=false&amp;serverTimeZone=UTC"/>
		<property name="username" value="root"/>
		<property name="password" value="1234"/>
		</dataSource>
	</environment>
</environments>

  1. 类型别名
    在映射配置文件中的 resultType 属性需要配置数据封装的类型(类的全限定名(即类的路径))。而每次这样写是特别麻烦的,Mybatis提供了 类型别名 (typeAliases) 可以简化这部分的书写。
    首先需要现在核心配置文件中配置类型别名,也就意味着给pojo包下所有的类起了别名(默认的别名就是:实体类名),不区分大小写。
    内容如下:
<typeAliases>
	<!--name属性的值是实体类所在包-->
	<package name="com.itheima.pojo"/>
</typeAliases>

通过上述的配置,我们就可以简化映射配置文件中 resultType 属性值的编写

<mapper namespace="com.itheima.mapper.UserMapper">
	<select id="selectAll" resultType="user">
	select * from tb_user;
	</select>
</mapper>

配置各个标签需要遵循前后顺序(即上面图片的那个顺序)

一、查询

1、查询所有

实体类属性名和数据库表的列名不一致,则idea不能自动封装数据

解决方法:

 * 方法一: 起别名 :对不一样的字段名起别名,让别名和实体类的属性名一样
           - 缺点:每次查询都要定义一次别名
<select id="selectAll" resultType="brand">
        select id , brand_name as brandName, company_name as companyName, ordered,description,status  from tb_brand;
</select>
              * 解决方法:使用sql片段
                <sql id="brand_column">
                   id , brand_name as brandName, company_name as companyName, ordered,description,status
                </sql>
                <select id="selectAll" resultType="brand">
                    select  <include refid="brand_column"></include> from tb_brand;
                </select>
                * 缺点:sql片段不灵活
                   -解决:方法二

        * 方法二:resultMap:
          1. 在<mapper namespace="com.itheima.mapper.BrandMapper"></mapper>标签中定义resultMap标签
          2. 在<select>标签中使用resultMap属性替换resultType属性
 
 <!--
      id: 唯一标识
      type:映射的类型(支持别名)
    -->
    <resultMap id="brandResultMap" type="brand">
        <!--
          id:完成主键字段的映射
          result:完成一般字段的映射
              column: 该字段在数据库中的列名
              property: 该字段在实体类pojo的属性名
             <id column="brand_name" property="brandName"/>//主键字段的映射
        -->
         <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>

2、Id查询

<!--
       *参数占位符:
        1. #{};会替换为 ?, 为了防止SQl注入
        2. ${}; 拼sql语句,会存在sql注入问题
        3. 使用时机:
            * 参数传递的时候,使用#{}
            * 数据库表名或者列名不固定的时候,使用${}
            
            
         * 参数类型:
             parameterType="int";可以省略
             <select id="selectById" parameterType="int" resultMap="brandResultMap">
                 select * from tb_brand where id = ${id};
             </select>
         * 特殊字符处理:
            1. 转移字符:
             <select id="selectById" resultMap="brandResultMap">
                     select * from tb_brand where id &lt; ${id};
              </select>
            2. CDATA区://其实就相当于文本框;<![CDATA[ 这里就是填数据的地方 ]]>
             <select id="selectById" resultMap="brandResultMap">
                 select * from tb_brand where id <![CDATA[ < ]]> ${id};
              </select>
    -->

3、多条件查询

//    多条件查询

    /**
     *  * 参数接收:
     *      1. 散装参数:如果方法中有!!!多个参数!!!,需要使用@Param("sql参数占位符名称")
     *      2. 对象参数: 对象的属性名称要和参数占位符名称一致
     *      3. map集合: 只需保证sql中的参数名和map集合的键的名称对应上
     * @param status
     * @param companyName
     * @param brandName
     * @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);

一、动态查询

  • 动态sql:sql语句会随着用户的输入或者外部条件的变化而变化
<!--动态条件查询
       * if : 条件查询
        * test : 逻辑表达式
          * 产生的问题:第一个条件不需要逻辑运算符
           <if test="companyName !=null and companyName !='' ">
                and company_name like #{companyName}
            </if>
            
               *解决1: 多写一个恒等式: 1=1
                   <select id="selectByCondition" resultMap="brandResultMap">
                        select * from tb_brand
                        where 1=1
                            <if test="status != null">
                                and 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>
              *解决二:where标签替换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>
    </select>
//上面的一段代码单单用一个if标签是不能满足需求的),存在的问题是where后面的第一个条件不需要and,所以很难满足
//使用动态sql就可以解决

  <select id="selectByCondition" resultMap="brandResultMap">
        select * from tb_brand
        <where>
            <if test="status != null">
               and  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>

一、动态查询——单条件查询

<select id="selectByConditionSingle" resultMap="brandResultMap">
        select * from tb_brand
   where
       <choose> <!--相当于swith-->

           <when test="status !=null"><!--相当于case-->
               status =#{status}
           </when>

           <when test="companyName !=null and companyName !=''"><!--相当于case-->
               company_name like #{companyName}
           </when>

           <when test="brandName !=null and brandName !=''"><!--相当于case-->
               brand_name like #{brandName}
           </when>
           <otherwise> <!--相当于default-->
               1=1
           </otherwise>
       </choose>
    </select>


//查询单个的
<select id="selectByConditionSingle" resultMap="brandResultMap">
        select * from tb_brand
   where
       <choose> <!--相当于swith-->

           <when test="status !=null"><!--相当于case-->
               status =#{status}
           </when>

           <when test="companyName !=null and companyName !=''"><!--相当于case-->
               company_name like #{companyName}
           </when>

           <when test="brandName !=null and brandName !=''"><!--相当于case-->
               brand_name like #{brandName}
           </when>
           <otherwise> <!--相当于defaut-->
               1=1
           </otherwise>
       </choose>
    </select>
//使用where标签的改进
<select id="selectByConditionSingle" resultMap="brandResultMap">
        select * from tb_brand
        <where>
            <choose> <!--相当于swith-->

                <when test="status !=null"><!--相当于case-->
                    status =#{status}
                </when>

                <when test="companyName !=null and companyName !=''"><!--相当于case-->
                    company_name like #{companyName}
                </when>

                <when test="brandName !=null and brandName !=''"><!--相当于case-->
                    brand_name like #{brandName}
                </when>

            </choose>
        </where>
    </select>

二、添加数据

添加

public void testAdd() throws IOException {
//        1.接收参数
        int status=1;
        String companyName="华为";
        String brandName ="波导";
        String description="手机中的战斗机";
        int ordered=100;

//        封装参数
        Brand brand = new Brand();
        brand.setStatus(status);
        brand.setBrandName(brandName);
        brand.setCompanyName(companyName);
        brand.setDescription(description);
        brand.setOrdered(ordered);

//        Map集合
//        Map map = new HashMap();
//        map.put("status",status);
//        map.put("companyName",companyName);
//        map.put("brandName",brandName);


//        1. 获取SqlSessionFactory对象

        String resource = "mybatis-config.xml";//配置文件的路径
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//        2. 获取SqlSession对象
//        SqlSession sqlSession = sqlSessionFactory.openSession(); //默认开启事务,进行增删改查需要使用sqlSession.commit();手动提交事务
        SqlSession sqlSession = sqlSessionFactory.openSession(true);//设置自动提交事务 
//        3. 获取Mapper对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        brandMapper.add(brand);
//        手动提交事务
        sqlSession.commit();
//        5. 释放资源
        sqlSession.close();

    }

添加-----主键返回

  • 默认没有主键返回的(即id)
<insert id="add">
        insert into tb_brand(brand_name, company_name,ordered,description,status)
         values (#{companyName},#{brandName},#{ordered},#{description},#{status});
    </insert>
    //其实当我们指向这个sql语句的时候,id值就已经存在的了,只是没有直接绑定到该对象里面,我们没有去获取而已,下面的代码就是获取id值(这里id是主键)
  • 有主键返回
//获取到主键值后,将来就可以通过该实体类对象对应的get方法得到
<!--keyProperty指向主键名-->
    <insert id="add" useGeneratedKeys="true" keyProperty="id">
        insert into tb_brand(brand_name, company_name,ordered,description,status)
        values (#{companyName},#{brandName},#{ordered},#{description},#{status});
    </insert>

三、修改

三、1、修改全部字段

<!--    修改全部字段-->
    <update id="update">
        update tb_brand
         set brand_name = #{brandName},
             company_name = #{companyName},
             ordered = #{ordered},
             description = #{description},
             status = #{status}
         where id =#{id};
    </update>

三、2、修改动态字段(将来修改哪个字段是不固定的)

  • 原来的:
 <update id="update">
        update tb_brand
         set brand_name = #{brandName},
             company_name = #{companyName},
             ordered = #{ordered},
             description = #{description},
             status = #{status}
         where id =#{id};
    </update>
  • 使用动态sql
<!--    修改动态sql-->
    <update id="update">
        update tb_brand
         <set>
            <if test="brandName != null and brandName !='' ">
                brand_name = #{brandName},
            </if>
            <if test="companyName != null and companyName !=''">
                company_name = #{companyName},
            </if>
            <if test="ordered != null">
                ordered = #{ordered},
            </if>
            <if test="description != null and description != ''">
                description = #{description},
            </if>
            <if test="status != null">
                status = #{status}
            </if>
         </set>
        where id =#{id};
    </update>

四、删除

四、1、删除一条记录

<!--   根据id进行 删除-->
    <delete id="deleteById">
        delete from tb_brand where id = #{id};
    </delete>

四、2、批量删除

  1. 使用数组进行作为参数
<!--    批量删除-->
<!--    mybatis会将数组参数封装到一个Map集合
            * 默认key名字:array
            * 可以用  @Param("ids")注解改变map集合的默认key(map里面的键)名称

		* 1.collection:要遍历的目标集合
		* open:循环开始时的字符;close:循环结束时的字符
		* item:遍历出的集合成员,自己定义的变量
		* separator:结合成员之间的分隔符
		* #{item}:注意与item="item"中的的值相同(即变量名要相同)
-->
    <delete id="deleteByIds">
        delete from tb_brand where id
          in (
              <foreach collection="ids" item="id" separator="," open="(" close=")">
                  #{id}
              </foreach>
               );
    </delete>

Mybatis参数传递

Mybatis接口方法中可以接收各种各样的参数,Mybatis底层对于这些参数进行不同的封装处理方式

1.单个参数的封装:

-参数是 POJO类型:直接使用,实体类属性名和参数占位符名称一致

  • 参数是 Map集合:直接使用,键名 和参数占位符一致
  • 参数是 Collection:封装为Map集合
//两种方法
map.put("collection",collection集合);
map.put("arg0",collection集合);
  • 参数是 List:封装为Map集合
map.put("collection",list集合);
map.put("list",list集合);
map.put("arg0",list集合);
  • 参数是 Array:封装为Map集合
map.put("array",数组);
map.put("arg0",数组);
  • 参数是 其它类型:直接使用

2.多个参数:

多个参数会被封装为map集合,可以使用@param()注解,来替换map集合中默认的arg键名

//两种
map.put("arg0",参数值1);
map.put("arg1",参数值2);


map.put("param1",参数值1);
map.put("param2",参数值2);
  • 建议:将来都使用@Param注解来修改Map集合(多个参数,系统会默认把参数封装成集合)中的默认键名,并使用修改后的名称来获取值,这样可读性更高
    • 首先明确这个@Param注解是为SQL语句中参数赋值而服务的。
      @Param的作用就是给参数命名,比如在mapper里面某方法A(int id),当添加注解后A(@Param(“userId”) int id),也就是说外部想要取出传入的id值,只需要取它的参数名userId就可以了。将参数值传如SQL语句中,通过#{userId}进行取值给SQL的参数赋值。

实例一:@Param注解基本类型的参数

    1. mapper中的方法:
public User selectUser(@Param("userName") String name,@Param("password") String pwd);

映射到xml中的标签

<select id="selectUser" resultMap="User">  
   select * from user  where user_name = #{userName} and user_password=#{password}  
</select>
  • 其中where user_name = #{userName} and user_password = #{password}中的userName和password都是从注解@Param()里面取出来的,取出来的值就是方法中形式参数 String name 和 String pwd的值。
当使用了@Param注解来声明参数的时候,SQL语句取值使用#{}, ${}取值都可以。
当不使用@Param注解声明参数的时候,必须使用的是#{}来取参数。使用${}方式取值会报错。

注解开发

  1. 使用注解开发会比配置文件开发更加简单方便
  • 查询:@Select
  • 添加:@Insert
  • 修改:@Update
  • 删除:@Delete
    提示:注解开发完成简单功能,配置文件开发完成复杂功能
  1. xml开发,需要配置xml文件中设置
 <select id="selectById" resultType="user">
        select * from tb_user where id =#{id};
  </select>

在这里插入图片描述
注解开发:
在这里插入图片描述

  • 使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪。 因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。
  • 选择何种方式来配置映射,以及认为是否应该要统一映射语句定义的形式,完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松的在基于注解和 XML 的语句映射方式间自由移植和切换。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Android】布局优化—include,merge,ViewStub的使用方法

引言 1.重要性 在Android应用开发中&#xff0c;布局是用户界面的基础。一个高效的布局不仅能提升用户体验&#xff0c;还能显著改善应用的性能。随着应用功能的复杂性增加&#xff0c;布局的优化变得尤为重要。优化布局能够减少渲染时间&#xff0c;提高响应速度&#xff0c…

Docker安装consul + go使用consul + consul知识

1. 什么是服务注册和发现 假如这个产品已经在线上运行&#xff0c;有一天运营想搞一场促销活动&#xff0c;那么我们相对应的【用户服务】可能就要新开启三个微服务实例来支撑这场促销活动。而与此同时&#xff0c;作为苦逼程序员的你就只有手动去 API gateway 中添加新增的这…

探索分布式IO模块的介质冗余:赋能工业自动化的稳健之心

在日新月异的工业自动化领域&#xff0c;每一个细微环节的稳定性都直接关系到生产线的效率与安全。随着智能制造的深入发展&#xff0c;分布式IO&#xff08;Input/Output&#xff09;模块作为连接现场设备与控制系统的关键桥梁&#xff0c;其重要性日益凸显。我们自主研发的带…

五子棋双人对战项目(3)——匹配模块

一、分析需求 二、约定前后端接口 三、实现游戏大厅页面&#xff08;前端代码&#xff09; 四、实现后端代码 五、线程安全问题 六、忙等问题 一、分析需求 需求&#xff1a;多个玩家&#xff0c;在游戏大厅进行匹配&#xff0c;系统会把实力相近的玩家匹配到一起。 要想实…

Redis 简单的消息队列

使用redis 进行简单的队列很容易&#xff0c;不需要使用较为复杂的MQ队列&#xff0c;直接使用redis 进行&#xff0c;不过唯一不足的需要自己构造生产者消费者&#xff0c;这里使用while True的方法进行消费者操作 目录 介绍数据类型StringHash 重要命令消息队列 介绍 key-v…

钉钉H5微应用Springboot+Vue开发分享

文章目录 说明技术路线注意操作步骤思路图 一、创建钉钉应用二、创建java项目三、创建vue项目&#xff08;或uniapp项目&#xff09;&#xff0c;npm引入sdk的依赖四、拥有公网域名端口。开发环境可以使用&#xff08;贝锐花生壳等工具&#xff09;五、打开钉钉开发者平台&…

Selenium与数据库结合:数据爬取与存储的技术实践

目录 一、Selenium与数据库结合的基础概念 1.1 Selenium简介 1.2 数据库简介 1.3 Selenium与数据库结合的优势 二、Selenium爬取数据的基本步骤 2.1 环境准备 2.2 编写爬虫代码 2.3 数据提取 2.4 异常处理 三、数据存储到数据库 3.1 数据库连接 3.2 数据存储 3.3 …

软件设计师——计算机网络

&#x1f4d4;个人主页&#x1f4da;&#xff1a;秋邱-CSDN博客☀️专属专栏✨&#xff1a;软考——软件设计师&#x1f3c5;往期回顾&#x1f3c6;&#xff1a;&#x1f31f;其他专栏&#x1f31f;&#xff1a;C语言_秋邱 一、OSI/ RM七层模型(⭐⭐⭐) ​ 层次 名称 主要功…

docker下载mysql时出现Unable to pull mysql:latest (HTTP code 500) server error 问题

报错 Unable to pull mysql:latest (HTTP code 500) server error - Get “https://registry-1.docker.io/v2/”: EOF 解决方法 将VPN开到Global模式 解决啦

Could not retrieve https://npm.taobao.org/mirrors/node/index.json. 报错解决

Could not retrieve https://npm.taobao.org/mirrors/node/index.json. 报错解决 1.问题原因及解约 今天使用nvm下载不同版本的nodejs的时候报错了 C:\Users\1> nvm list availableCould not retrieve https://npm.taobao.org/mirrors/node/index.json.提示无法检索地址&…

Oracle控制文件全部丢失如何使用RMAN智能恢复?

1.手动删除所有控制文件模拟故障产生 2.此时启动数据库发现控制文件丢失 3.登录rman 4.列出故障 list failure; 5.让RMAN列举恢复建议 advise failure; 6.使用RMAN智能修复 repair failure;

基于Springboot+Vue的基于协同过滤算法的个性化音乐推荐系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统中…

Ubuntu Server 20.04 64bit定时备份MySQL8.0.36数据库数据

一、编写sh脚本 常见备份命令介绍 我选用的是mysqldump命令&#xff0c;命令使用简介 [root]> mysqldump -helpUsage: mysqldump [OPTIONS] database_name [tables] OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] OR mysqldump [OPTIONS] --all…

足球青训俱乐部管理:Spring Boot技术驱动

摘 要 随着社会经济的快速发展&#xff0c;人们对足球俱乐部的需求日益增加&#xff0c;加快了足球健身俱乐部的发展&#xff0c;足球俱乐部管理工作日益繁忙&#xff0c;传统的管理方式已经无法满足足球俱乐部管理需求&#xff0c;因此&#xff0c;为了提高足球俱乐部管理效率…

VMware Aria Automation Orchestrator 8.18 发布,新增功能概览

VMware Aria Automation Orchestrator 8.18 - 现代工作流程自动化平台 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-aria-automation-orchestrator/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 现代工作流程…

超强大的 Nginx 可视化管理工具

今天给大家介绍一款 Nginx 可视化管理界面&#xff0c;非常好用&#xff0c;小白也能立马上手。 nginx-proxy-manager 是一个反向代理管理系统&#xff0c;它基于 NGINX&#xff0c;具有漂亮干净的 Web UI。还可以获得受信任的 SSL 证书&#xff0c;并通过单独的配置、自定义和…

SUP-NeRF-ECCV2024数据集: 单目3D对象重建的新突破

2024-09-25&#xff0c;由Bosch Research North America和Michigan State University联合发布的SUP-NeRF&#xff0c;是一个基于单目图像进行3D对象重建的新型方法。一个无缝集成姿态估计和物体重建的统一网格。 ECCV&#xff1a;欧洲计算机视觉会议的缩写&#xff0c;它是计算…

2024年配置YOLOX运行环境+windows+pycharm24.0.1+GPU

1.配置时间2024/9/25 2.Anaconda-python版本3.7&#xff0c;yolox版本0.2.0 YOLOX网址: https://github.com/Megvii-BaseDetection/YOLOX 本人下载的这个版本 1.创建虚拟环境 conda create -n yolox37 python37 激活 conda activate yolox37 2.安装Pytorch cuda等&…

CSS 效果:实现动态展示双箭头

最近写了一段 CSS 样式&#xff0c;虽然不难&#xff0c;但实现过程比较繁琐。这个效果结合了两个箭头&#xff0c;一个突出&#xff0c;一个内缩&#xff0c;非常适合用于步骤导航或选项卡切换等场景。样式不仅仅是静态的&#xff0c;还可以通过点击 click 或者 hover 事件&am…

肺癌影像智能诊断项目

1 项目背景 肺癌是发病率和死亡率增长最快、对人类健康和生命威胁最大的恶性肿瘤之一,近50年来许多国家都报道肺癌的发病率和死亡率均明显增高。据国家癌症中心统计,我国肺癌发病人数和死亡人数已连续10年位居恶性肿瘤之首,每年新发肺癌约78.7万人,因肺癌死亡约63.1万人。早…