MyBatis进阶:掌握MyBatis动态SQL与模糊查询、结果映射,让你在面试中脱颖而出!!

news2024/11/24 15:49:26

目录

一、引言

二、MyBatis动态SQL

2.1.if元素使用

2.2.foreach元素使用

三、MyBatis模糊查询

①使用#{字段名}

②使用${字段名}

③使用concat{'%',#{字段名},'%'}

总结

四、MyBatis结果映射

4.1.案例演示

4.1.1.resultType进行结果映射

4.1.2.resultMap进行结果映射



一、引言

在当今的软件开发环境中,数据库的使用已经成为了一项基础且必不可少的技能。而在处理数据库相关的任务时,SQL查询语句无疑是最为常用的工具之一。然而,随着应用程序的复杂性不断增加,我们往往需要编写更加复杂的SQL查询语句以满足需求。这就引出了我们今天要讨论的主题——MyBatis。

在这篇文章中,我们将深入探讨MyBatis的两个重要特性:动态SQL和模糊查询。动态SQL是MyBatis的一个强大功能,它允许我们在XML映射文件中编写动态生成的SQL语句。模糊查询则是我们在处理大量数据时常用的一种查询方式,它可以帮助我们快速地找出符合特定条件的记录。

此外,我们还将讨论MyBatis的结果映射功能。结果映射是将数据库查询结果映射到Java对象的过程,它是MyBatis的核心功能之一。通过结果映射,我们可以将复杂的数据库表结构转换为Java中的对象,使得程序的设计更加直观和简单。

掌握MyBatis的这些高级特性,不仅可以提高我们的开发效率,也可以让我们在面试中脱颖而出。因此,无论你是已经有一定经验的开发者,还是刚刚入门的学习者,都值得花时间去学习和理解这些知识。在接下来的文章中,我们将详细介绍这些特性的使用方法和注意事项,希望对你有所帮助。

二、MyBatis动态SQL

2.1.if元素使用

在以往的编写中我们肯定写过这样的代码

update t_mvc_book bname=?,btype=?,bprice=?,..... where bid=?

假如我们前台jsp没有传参数bname到后台,那么会怎么样?

update t_mvc_book bname=null,btype='科幻小说',bprice=9.9,..... where bid=7

就会造成这样的结果,原本我们不传递参数只是不想改变原有的字段值,没成想不传反而变为null

有些人就会想那我传个参数来行不行呢?行,但是没必要。如果我们使用Mybatis里面的动态SQL,这个问题就迎刃而解了,它会把我们的sql语句变为xml的方式,通过if标签判断,如果为空就不会拼接判断条件里的内容。

 <update id="updateByPrimaryKeySelective" parameterType="com.csdn.xw.model.Book" >
    update t_mvc_book
    <set >
      <if test="bname != null" >
        bname = #{bname,jdbcType=VARCHAR},
      </if>
      <if test="price != null" >
        price = #{price,jdbcType=REAL},
      </if>
    </set>
    where bid = #{bid,jdbcType=INTEGER}
  </update>

2.2.foreach元素使用

我们再来假设一个场景: 我们写代码的过程中肯定写过对某个事物的批量删除

可能是这样遍历数组然后调用删除方法

for int id :ids

      orderItemsDao.delete(id)

也可能是拼接的方式将需要删除的id做个拼接

delete from t_oa_order where id in(...)

如果是使用mybatis我们就可以这样写

<select id="selectByBids" resultType="com.csdn.xw.model.Book" parameterType="java.lang.Integer" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bid in
    <foreach collection="bids" item="bid" open="(" close=")" separator=",">
      #{bid}
    </foreach>
  </select>

现在来测试一下

BookMapper

List<Book> selectByBids(@Param("bids") List bids);

BookBiz

 List<Book> selectByBids(List bids);

BookBizImpl

 @Override
    public List<Book> selectByBids(List bids) {
         return  bookMapper.selectByBids(bids);
    }

demo测试类

@Test
    public void selectByBids() {
        System.out.println("测试的查询的方法");
        List<Integer> integers = Arrays.asList(new Integer[]{55, 56, 57, 58});
        bookBiz.selectByBids(integers).forEach(System.out::println);
    }

测试结果:

三、MyBatis模糊查询

为了突出我们的效果展示,我们增加一个配置文件log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- status : 指定log4j本身的打印日志的级别.ALL< Trace < DEBUG < INFO < WARN < ERROR
	< FATAL < OFF。 monitorInterval : 用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s. -->
<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <!-- 配置日志文件输出目录 ${sys:user.home} -->
        <Property name="LOG_HOME">/root/workspace/lucenedemo/logs</Property>
        <property name="ERROR_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/error</property>
        <property name="WARN_LOG_FILE_NAME">/root/workspace/lucenedemo/logs/warn</property>
        <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%n</property>
    </Properties>

    <Appenders>
        <!--这个输出控制台的配置 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
            <ThresholdFilter level="trace" onMatch="ACCEPT"
                             onMismatch="DENY" />
            <!-- 输出日志的格式 -->
            <!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称
                %m : 日志内容,即 logger.info("message") %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M
                : 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 -->
            <PatternLayout pattern="${PATTERN}" />
        </Console>

        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 -->
        <!--append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true -->
        <File name="log" fileName="logs/test.log" append="false">
            <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </File>
        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size, 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingFile name="RollingFileInfo" fileName="${LOG_HOME}/info.log"
                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
            <ThresholdFilter level="info" onMatch="ACCEPT"
                             onMismatch="DENY" />
            <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
            <Policies>
                <!-- 基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。 modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am. -->
                <!-- 关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval, 日期格式精确到哪一位,interval也精确到哪一个单位 -->
                <!-- log4j2的按天分日志文件 : info-%d{yyyy-MM-dd}-%i.log -->
                <TimeBasedTriggeringPolicy interval="1"
                                           modulate="true" />
                <!-- SizeBasedTriggeringPolicy:Policies子节点, 基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小. -->
                <!-- <SizeBasedTriggeringPolicy size="2 kB" /> -->
            </Policies>
        </RollingFile>

        <RollingFile name="RollingFileWarn" fileName="${WARN_LOG_FILE_NAME}/warn.log"
                     filePattern="${WARN_LOG_FILE_NAME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="warn" onMatch="ACCEPT"
                             onMismatch="DENY" />
            <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="2 kB" />
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="20" />
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="${ERROR_LOG_FILE_NAME}/error.log"
                     filePattern="${ERROR_LOG_FILE_NAME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd-HH-mm}-%i.log">
            <ThresholdFilter level="error" onMatch="ACCEPT"
                             onMismatch="DENY" />
            <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
            <Policies>
                <!-- log4j2的按分钟 分日志文件 : warn-%d{yyyy-MM-dd-HH-mm}-%i.log -->
                <TimeBasedTriggeringPolicy interval="1"
                                           modulate="true" />
                <!-- <SizeBasedTriggeringPolicy size="10 MB" /> -->
            </Policies>
        </RollingFile>

    </Appenders>

    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 -->
    <Loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息 -->
        <logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger>

        <!-- 第三方日志系统 -->
        <logger name="org.springframework" level="ERROR" />
        <logger name="org.hibernate" level="ERROR" />
        <logger name="org.apache.struts2" level="ERROR" />
        <logger name="com.opensymphony.xwork2" level="ERROR" />
        <logger name="org.jboss" level="ERROR" />


        <!-- 配置日志的根节点 -->
        <root level="all">
            <appender-ref ref="Console" />
            <appender-ref ref="RollingFileInfo" />
            <appender-ref ref="RollingFileWarn" />
            <appender-ref ref="RollingFileError" />
        </root>

    </Loggers>

</Configuration>

log4j2.xml文件应该位于项目的类路径根目录下,即src/main/resources目录中。

小贴士:

Log4j2的配置文件,用于配置日志输出的格式、级别、目标等信息。Log4j2不再支持Log4j 1.x中的.properties文件的配置方式,而是支持通过json、xml或者jsn的方式进行配置。

具体来说,log4j2.xml文件中包含了以下几个部分:

  1. Configuration:配置信息区域,包括Appenders、Loggers等。
  2. Appender:输出目标区域,包括控制台、文件、数据库等。
  3. Logger:日志记录区域,包括包名、类名、日志级别等。

在MyBatis中有三种模糊查询的方法分别是:

①使用#{字段名}

<select id="like1" resultType="com.csdn.xw.model.Book" parameterType="java.lang.String" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like #{bname}
  </select>

测试结果: 

②使用${字段名}

<select id="like2" resultType="com.csdn.xw.model.Book" parameterType="java.lang.String" >
    select
    <include refid="Base_Column_List" />
    from t_mvc_book
    where bname like ${bname}
  </select>

测试结果:  

③使用concat{'%',#{字段名},'%'}

<select id="like3" resultType="com.csdn.xw.model.Book" parameterType="java.lang.String" >
  select
  <include refid="Base_Column_List" />
  from t_mvc_book
  where bname like concat('%',#{bname},'%')
</select>

测试结果: 

总结

想必你也看出了,这三种的不同之处,下面我来给你总结一下。

mybatis中的$与#的区别

①$是占位符传参,#是预处理SQL

②外在形式:$传参不带引号,#自带引号

可能你还没感受到有没有引号没什么太大的区别,下面我来给你演示一下

假如我要根据部门编号查出该部门的所有人员信息,利用$与#来做测试

#:select*from t_oa_employee where deptid=#{deptid}

        select*from t_oa_employee where deptid='10011'

$:select*from t_oa_employee where deptid=${deptid}

          select*from t_oa_employee where deptid=10011

这么一看好像确实没有什么区别,那如果前台恶意传参呢?

http://localhost:8080/employee?deptid=10011 or 1=1

那这样不就把全公司的人员信息都查出来了

③$传参存在sql注入,#不存在

④$可以做动态列,完成动态sql的开发

我们开发过程中肯定有遇到过,当前字段不满足我们需求,然后我们修改数据库字段的时候,如果改成正确还好,如果错误那就芭比Q了,动态列就可以做到传入的参数当作需要查询的列来操作例如:

假设我们有一个表名为user_info,包含字段id、name、age、gender等,现在需要根据传入的参数来动态生成查询的列,可以使用如下的语句

<select id="getUserInfo" resultType="map">
  SELECT ${columnName}, ${columnAge}, ${columnGender}
  FROM user_info
</select>

其中,columnName、columnAge、columnGender分别代表需要查询的列名,可以在Java代码中定义一个Map变量,将列名作为key,对应的值作为value传入即可。例如

Map<String, Object> columnMap = new HashMap<>();
columnMap.put("columnName", "name");
columnMap.put("columnAge", 18);
columnMap.put("columnGender", "男");

然后将columnMap传入MyBatis的mapper中调用即可。

最后小编还是建议大家一般能用 # 的就别用 $ ,最常用的还是第三种。

四、MyBatis结果映射

在使用MyBatis中拥有多个场景,返回的结果是多样的,resultType/resultMap

①返回单表的对应的实体类,仅有一个查询结果,可以用resultType/resultMap。

②返回单表的对应的实体类,有多个查询结果,可以用resultType/resultMap。

③返回多表对应结果,仅有一个查询结果,通常用resultType也可以用resultMap。

④返回多表对应结果,有多个查询结果,通常用resultType也可以用resultMap。

⑤返回单个列段,仅有一个查询结果,就用resultType。

⑥返回单个列段,有多个查询结果,就用resultType。

  总结就是在Mybatis中结果集的处理分为两种:

resultMap:适合使用返回值是自定义实体类的情况

resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型

 如果是单表的情况下,resultType与resultMap都可以使用。
1 使用resultMap返回映射关系,指的是实体类与数据库字段的关系

2 使用resultType返回List<T>

3 使用resultType返回单个对象

4 使用resultType返回List<Map>【适用于多表查询返回结果集】

5 使用resultType返回Map<String,Object>【适用于多表查询返回单个结果集】

4.1.案例演示

4.1.1.resultType进行结果映射

假设我们有一个用户表user,包含以下字段:id、name、age、gender、email。现在需要根据这些字段查询用户信息并返回一个User对象。

首先,我们需要定义一个User类,用于存储查询结果:

public class User {
    private int id;
    private String name;
    private int age;
    private String gender;
    private String email;
    // getter和setter方法省略
}

然后,在MyBatis的mapper文件中,我们可以使用resultType来映射查询结果到User对象上。具体配置如下:

<select id="getUserById" resultType="com.example.User">
  SELECT id, name, age, gender, email
  FROM user
  WHERE id = #{id}
</select>

在上面的配置中,我们使用了resultType属性来指定查询结果映射到的Java对象的全限定名。这样,当执行查询语句时,MyBatis会自动将查询结果映射到指定的Java对象上。

4.1.2.resultMap进行结果映射

假设我们有一个订单表order,包含以下字段:id、user_id、product_id、price、quantity。现在需要根据这些字段查询订单信息并返回一个Order对象。

首先,我们需要定义一个Order类,用于存储查询结果:

public class Order {
    private int id;
    private int userId;
    private int productId;
    private double price;
    private int quantity;
    // getter和setter方法省略
}

然后,在MyBatis的mapper文件中,我们可以使用resultMap来映射查询结果到Order对象上。具体配置如下:

<resultMap id="OrderResultMap" type="com.example.Order">
  <id property="id" column="id" />
  <result property="userId" column="user_id" />
  <result property="productId" column="product_id" />
  <result property="price" column="price" />
  <result property="quantity" column="quantity" />
</resultMap>

<select id="getOrderById" resultMap="OrderResultMap">
  SELECT id, user_id, product_id, price, quantity
  FROM order
  WHERE id = #{id}
</select>

在上面的配置中,我们定义了一个名为"OrderResultMap"的resultMap,它的type属性指定了要映射的Java对象的全限定名。接下来,我们为每个字段指定了对应的属性名和数据库表中的列名。最后,在查询语句中引用这个resultMap即可将查询结果映射到Order对象上。

需要注意的是,如果查询结果中的某个字段在Java对象中没有对应的属性,那么该字段将被映射为null。此外,如果查询结果中的某个字段在Java对象中有多个对应的属性,那么该字段的值将被映射为一个列表或数组。

 

到这里我的分享就结束了,欢迎到评论区探讨交流!!

如果觉得有用的话还请点个赞吧 ♥  ♥

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

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

相关文章

【Java从入门到精通|1】从特点到第一个Hello World程序

写在前面 在计算机编程领域&#xff0c;Java是一门广泛应用的高级编程语言。它以其强大的跨平台性能、丰富的库和生态系统以及易于学习的语法而备受开发者欢迎。本文将引导您逐步了解Java的特点、如何安装和配置开发环境&#xff0c;以及如何编写您的第一个Java程序。 一、Java…

AI智能问答原来有这么多优点!

AI智能问答是最近一个比较新的概念&#xff0c;looklook今天打算从AI智能问答的优点出发&#xff0c;来和大家聊聊它的具体优势。到底为什么这么多企业都开始选择搭建这个AI智能问答&#xff0c;奥秘就在这里啦&#xff01; AI智能问答的优点 1.提高客户满意度——AI智能问答系…

my_CNN-FWI实验

CNN之后的模型结果&#xff1a; 2000epoch Rmse:0.0584 之前SMOOTH的结果 放一张对比图&#xff1a;

CST中lumped element中spice电路编写

CST中lumped element中spice电路编写 简述参考示例电路结构图注意 简述 在CST中lumped element中有自带的并联RLC、串联RLC、二极管、spice电路和Touchstone文件等。我们可以从help文档中看到自带的并联RLC、串联RLC不能完成一些复杂的电路电路的设置。 这时我们可以使用spi…

Django 简易PACS读片系统

1、Django中写一个后端接口&#xff0c;给HTML提供dicom文件接口的方式 1、首先创建django项目 1、下载安装跨域的包 pip3 install django-cors-headers2、使用pycharm创建一个Django项目 3、点击创建在另一个窗口&#xff0c;这个都无所谓&#xff0c;怎么都行&#xff0c;…

pdf转ppt在线的好工具有什么推荐?pdf转ppt方法介绍

在某些情况下&#xff0c;我们可能需要对PPT文件进行编辑、修改或重新排版&#xff0c;以满足特定的演讲需求或观众的需求。通过将PDF转换为PPT&#xff0c;我们可以方便地对文本、图片、布局等进行修改&#xff0c;使得演示内容更加贴合我们的目标&#xff0c;更能有效地传达我…

前端加springboot实现Web Socket连接通讯以及测试流程(包括后端实现心跳检测)

【2023】前端加springboot实现Web Socket连接通讯&#xff08;包括后端实现心跳检测&#xff09; 一级目录二级目录三级目录 前言一、Web Socket 简绍1 为什么用 websocket&#xff1f; 二、代码实现1、前端&#xff08;html&#xff09;1.1、无前端向后端发送消息1.2、有前端向…

当下软件测试员的求职困境

从去年被裁到现在&#xff0c;自由职业的我已经有一年没有按部就班打卡上班了。期间也面试了一些岗位&#xff0c;有首轮就挂的&#xff0c;也有顺利到谈薪阶段最后拿了offer的&#xff0c;不过最后选择了拒绝。 基于自己近一年的面试求职经历&#xff0c;我想聊聊当下大家在求…

半导体投资前景蒙阴,投资降幅或创下近十年最大纪录 | 百能云芯

对经济增速放缓的担忧&#xff0c;正逐渐影响半导体行业&#xff0c;使得一度火热的投资热情开始变得谨慎起来。预计2023年&#xff0c;全球前十大半导体制造商的设备投资额将首次在过去四年中出现下降趋势&#xff0c;而且这个下降幅度可能创下近十年来的最大纪录。 最近&…

AD域证书导入JDK

一、安装证书 服务器管理器找到仪表盘&#xff0c;点击添加角色和功能 点击下一步 再次点击下一步 下一步 选择Active Directory证书服务 点击添加功能&#xff0c;然后点击下一步 点击下一步 下一步 按照下图所示选择&#xff0c;默认证书颁发机构已经选择&#xff0c…

Vue3.X 创建简单项目(一)

一、环境安装与检查 首先&#xff0c;我们要确保我们安装了构建vue框架的环境&#xff0c;不会安装的请自行百度&#xff0c;有很多安装教程。检查环境 node -v # 如果没有安装nodejs请安装&#xff0c;安装教程自行百度 vue -V# 没有安装&#xff0c;请执行npm install -g v…

2023年如何运营TikTok账号?这些技巧你一定要知道

Tik Tok目前的全球月活已经突破7亿。作为全球最受欢迎的应用程序之一&#xff0c;它不仅为用户提供了记录分享生活中美好时刻、交流全球创意的阵地&#xff0c;也给全球的企业提供了一个直接触达用户的平台。 一、保持视频内容的真实性 当我们站在用户的角度去考虑时&#xf…

PMP如何备考?学习方式这里有

预习阶段&#xff1a;强烈建议跟着习课视频学习&#xff08;自己看书真的很难看懂&#xff09;&#xff0c;初步了解PMBOK&#xff0c;有个大致印象&#xff1b; 精讲阶段&#xff1a;这个时候就需要静下心来深入了解各个知识模块&#xff0c;不仅是看PMBOK&#xff0c;还要尽…

走进湖南大学麒麟信安|openEuler 嵌入式Meetup议程硬核来袭!

9月8日&#xff0c;openEuler社区将联合湖南大学、麒麟信安和湖南欧拉生态创新中心举办嵌入式Meetup&#xff0c;这将是一场集结智慧的开发者交流与愉快学习的盛宴&#xff0c;让我们的技术激情熊熊燃起&#xff01; 01 活动亮点 嵌入式技术新契机&#xff1a;本次Meetup将为…

深度学习入门(四):经典网络架构(Alexnet、Vgg、Resnet)

一、经典网络架构-Alexnet 2012年ImageNet竞赛冠军 8层神经网络、5层卷积层、3层全连接 二、经典网络架构-Vgg 2014 年ImageNet 竞赛冠军 VGG 最大的特点就是它在之前的网络模型上&#xff0c;通过比较彻底地采用 3x3 尺寸的卷积核来堆叠神经网络&#xff0c;从而加深整个神…

怎么样才能开期权账户

为了保护投资者权益&#xff0c;上交所设定了50万的准入门槛&#xff0c;挡着了很多想入手期权交易的小伙伴&#xff0c;如果资金不够50万&#xff0c;那么有什么办法能零门槛参与期权呢&#xff0c;下文给大家介绍怎么样才能开期权账户的知识点。本文来自&#xff1a;期权酱 一…

【玩三层交换机,关键得有这几个思路。】

今天要分享的主题还是跟交换机有关&#xff01;三层交换机。 当我们需要在不同的 LAN 或 VLAN 之间传输数据时&#xff0c;二层交换机就无法满足了。 这时&#xff0c;需要三层交换机登场了哈。 很多新来的朋友总在问&#xff0c;三层交换机到底要怎么配置&#xff0c;有哪些…

全国城市内涝排涝模拟技术及在市政、规划设计中应用教程

详情点击链接&#xff1a;全国城市内涝排涝模拟技术及在市政、规划设计中应用教程 一&#xff0c;数据准备 通过标准化的步骤&#xff0c;利用CAD数据、GIS数据&#xff0c;在建模的不同阶段发挥不同软件的优势&#xff0c;实现高效的数据处理、准确的参数赋值、模型的快速建…

Docker-Consul

Docker-Consul 一、介绍1.什么是服务注册与发现2.什么是consul3.consul提供的一些关键特性&#xff1a; 二、consul 部署1.环境准备2.consul服务器3.查看集群信息4.通过 http api 获取集群信息 三、registrator服务器1.安装 Gliderlabs/Registrator2.测试服务发现功能是否正常3…

开源TTS+gtx1080+cuda11.7+conda+python3.9吊打百度TTS

简介 开源项目&#xff0c;文本提示的生成音频模型 https://github.com/suno-ai/bark Bark是由Suno创建的基于变换器的文本到音频模型。Bark可以生成极为逼真的多语种演讲以及其他音频 - 包括音乐、背景噪音和简单的声音效果。该模型还可以产生非言语沟通&#xff0c;如笑声…