MyBatis框架2

news2024/12/25 8:58:19

目录

一、Sql编写高级特性-批量增删

1.SQL-foreach-批量删除

1.1.批量删除方法

 1.2编写SQL

1.3.编写测试

2.动态SQL-foreach-批量插入

2.1.映射器批量插入方法

2.2.编写SQL

2.3.编写测试

二、Sql编写高级特性-多对一

1.多对一保存

1.1.创建员工部门Domain

1.2.创建员工部门表

1.3.部门DeptMapper映射器

1.4.编写DeptMapper.xml映射文件

1.5.员工EmployeMapper映射器

1.6.员工EmployeeMapper.xml映射文件

3多对一查询-嵌套结果

4多对一查询-嵌套查询

5懒加载配置

三.Sql编写高级特性-一对多

1.一对多保存

四.缓存的使用

1.一级缓存

2.二级缓存


一、Sql编写高级特性-批量增删

当我们在删除多条数据,或者添加多条数据时,我们可能会选择for循环的方式调用mapper逐条删除或添加,如果有N条数据你就会调用N次mapper,这样的代码无疑是非常消耗性能的,我们可以通过MyBatis的动态SQL foreach来实现批量删除和批量添加,调用一次mapper就能添加n条数据,提升性能。

1.SQL-foreach-批量删除

有的时候我们需要对数据进行批量操作,如根据多个ID查询,或者根据多个ID删除,我们可以通过 in(1,2) 来实现,编写如下SQL

SELECT * from employee where id in (1,2);    //批量查询
DELETE   from employee where id in (3,4)    //批量删除

那么在MyBastis怎么批量删除呢?

1.1.批量删除方法

批量删除方法,参数是一个LIST,即:根据多个ID来删除。

public interface EmployeeMapper {
    //...
    int batchDelete(List<Long> ids);
}

 1.2编写SQL

<delete id="batchDelete" parameterType="list">
        DELETE FROM employee
        where id in
        <foreach collection="list" open="(" item="id" separator="," close=")" >
            #{id}
        </foreach>
    </delete>

这里稍微麻烦,我们的目的是要把 list参数中的多个 id值 动态的拼接成 where id in (1,2); 这种效果,这里用到了 foreach 循环

  • collection 指的是集合或者数组,这里接受两种值,如果是集合就写 “list”,如果是数组就写“array”

  • open 开始元素,我们需要使用“( ” 作为开始

  • item 循环的每一个元素,这里的每一个元素就是list中的每一个id

  • separator 分隔符,我们拼接后的sql需要使用“,”来分割多个ID

  • close 结束元素,我们需要使用“ )”作为结束

  • #{id} 循环的内容,这里是把id的值取出来了,比如循环三次就如同 : (#{id}#{id}#{id})

根据上面的配置,这个循环会在最前面加上 "(" , 后面加上“)” , 然后取出每个item的值即ID ,然后使用分隔符“,”进行分割,最终形成 (1,2) 这种效果。

1.3.编写测试

 

@Test
    public void batchDelete() {
        try(SqlSession sqlSession = MyBatisUtil.openSession()){
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
            employeeMapper.batchDelete(Arrays.asList(11L,12L));
            sqlSession.commit();
        }
    }

2.动态SQL-foreach-批量插入

批量插入和批量删除都可以使用foreach来实现

2.1.映射器批量插入方法

public interface EmployeeMapper {
    int batchInsert(List<Employee> employees);
    //....
}

2.2.编写SQL

我们来回顾一下我们以前批量insert的SQL语法

 INSERT INTO employee(username,age,sex) VALUES("ls",11,1),("ww",12,1),("cq",13,1)

那么这个语法在MyBatis中怎么实现呢?修改SQL映射文件,添加SQL:  

<insert id="batchInsert" parameterType="list">
        INSERT INTO employee(username,age,sex) VALUES
        <foreach collection="list" item="emp" separator=",">
            (#{emp.username},#{emp.age},#{emp.sex})
        </foreach>
    </insert> 

这里跟批量删除有点不一样 ,我们需要的效果是 VALUES ("ls",11,1),("ww",12,1),("cq",13,1) 这种,你观察它其实没有开始符号和结束符号,因为每个值前面都有 ”(“以及”)“ ,所以不能使用 open和close 。这里的循环内容为 (#{emp.username},#{emp.age},#{emp.sex}) ,比如循环两次,用“ , ”分割就是:

(#{emp.username},#{emp.age},#{emp.sex}) , (#{emp.username},#{emp.age},#{emp.sex}) 效果。这里的item的值是emp,其实是一个Employee对象,因为list中装的就是Employee对象,当 #{xx}被替换成对应的值之后就形成了VALUES ("ls",11,1),("ww",12,1)这种效果

2.3.编写测试

 

 @Test    
public void batchInsert() {        
try(SqlSession sqlSession = MyBatisUtil.openSession()){          
  EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);    
        //批量插入           
                 employeeMapper.batchInsert(Arrays.asList(                    
                        new Employee("ww",11,true),
                        new Employee("cq",12,true), 
                        new Employee("zl",13,true)
                ));              
                  sqlSession.commit();       
       }  
  }

二、Sql编写高级特性-多对一

对象关联关系理解

  • 一对一:一个用户对应一个身份证号 , 一个支付宝账号对应一个余额宝账号

    任意 一方放一个外键

  • 多对一:多个员工属于同一个部门

    在多方设计一个外键关联就OK

  • 一对多:一个部门下面有多个员工

    还是在多方设计一个外键来处理

  • 多对多:一个学生可以有多个老师,一个老师也可以有多个学生 。站在任何一方思考都是一对多,那就是多对多。



    关联查询方式-ResultMap(关联映射) 

 

什么叫做关联查询!就是我们在查询数据的时候,把关联对象一起查询出来。 比如查询员工的时候要查询他所对应部门信息,首先来说查询出来要有对象来放。所以需要设计关联对象类来访,案例如下

public class Employee

{

//自己信息

private Long id;

private String name;

private Department dept;

}

查询方式有两种:

-- 方案1:嵌套查询,发送N+1条,效率低

select * from t_employee -- where id =1; select * from t_department where id =1

-- 方案2:嵌套结果 一条sql,效率高 SELECT e.*, d.id did, d.NAME dname FROM t_employee e LEFT JOIN t_department d ON e.dept_id = d.id

1.多对一保存

1.1.创建员工部门Domain

建立对象之间的关系,Employee中包含Dept对象  

public class Dept {
    private Long id;
    private String name;
    private String sn;

//--------------------    

public class Employee {

    private Long id;
    private String username;
    private String password;
    private Integer age;
    //关系:多对一
    private Dept dept;

    public Employee() {
    }

    public Employee(String username, String password, Integer age, Dept dept) {
        this.username = username;
        this.password = password;
        this.age = age;
        this.dept = dept;
    }

1.2.创建员工部门表

建立表之间的关系,employee中有detp_id外键ID  

CREATE TABLE `dept` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `sn` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;


--------------------------------------------

CREATE TABLE `employee` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `dept_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

 

1.3.部门DeptMapper映射器

编写DeptMapper,insert方法  

 public interface DeptMapper {
    void insert(Dept dept);
}

1.4.编写DeptMapper.xml映射文件

编写DeptMapper.xml,insert方法  

<?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">

<!--
    namespace:命名空间 ,sql坐标(SQL在哪儿)
-->
<mapper namespace="cn.lzh.mapper.DeptMapper">

    <insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        INSERT INTO dept(name,sn) values (#{name},#{sn})
    </insert>
</mapper>

 

1.5.员工EmployeMapper映射器

EmployeMapper,insert方法  


public interface EmployeeMapper {
    void insert(Employee employee);

1.6.员工EmployeeMapper.xml映射文件

编写EmployeeMapper.xml的insert方法的SQL  

 <!--    1.多对一保存:#{dept.id} 取员工对象中关联的的 dept对象的id属性-->
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
    INSERT INTO
    employee(username,password,age,dept_id)
    VALUES
    (#{username},#{password},#{age},#{dept.id})
</insert>

 

2.多对一修改

 <update id="updateById" parameterType="cn.lzh.mybatis._03_many_2_one.domain.Employee">
    update employee
    <set>
        <if test="username != null and username != ''">
            username = #{username}
        </if>
        <if test="dept != null and dept.id != null">
            dept_id = #{dept.id}
        </if>
    </set>
</update>

 

3多对一查询-嵌套结果

  <select id="selectAll" resultType="cn.lzh.mybatis._03_many_2_one.domain.Employee">
        select id,username,age,sex,dept_id
        from employee
    </select> 

<select id="selectAll" resultType="cn.lzh.mybatis._03_many_2_one.domain.Employee">
        select
            e.id,
            e.username,
            e.age,
            e.sex,

            d.id,
            d.name
        from employee e join dept d on d.id = e.dept_id
    </select>

 

但是这个SQL也查询不到关联对象 ,ResultType只能根据查询的列把对应的值封装到实体类的属性中,Employee中的Dept是一个自定义的字段,如果查询的列明和对象中的属性名不一致,就需要用到resultMap。如下:  

<resultMap id="baseResultMap" type="cn.lzh.mybatis._03_many_2_one.domain.Employee">
        <id column="e_id" property="id" />
        <result column="age" property="age" />
        <result column="username" property="username" />
        <result column="sex" property="sex" />
        <result column="age" property="age" />
        <!-- 处理关联对象的映射
            property="dept"  :对employee.dept属性的映射
            javaType="..Dept" :  employee.dept的类型 -->
        <association property="dept" javaType="cn.lzh.mybatis._03_many_2_one.domain.Dept">
            <id column="d_id" property="id" />
            <result column="name" property="name" />
        </association>
</resultMap>
<select id="selectAll" resultMap="baseResultMap">
    select
    e.id as e_id,
    e.username,
    e.age,
    e.sex,

    d.id as d_id,
    d.name
    from employee e join dept d on d.id = e.dept_id
</select>

 


4多对一查询-嵌套查询

上面的方式是第一种查询方式,我们叫着嵌套结果,意思就是查询的SQL使用JSON连表的方式把要查询的内容employee和dept全部查询出来 ,然后使用ResultMap来处理结果。

还有一种方式叫嵌套查询,这种方式在查询SQL的时候,只需要查询employee表即可,不需要去连表查询Dept,而是在ResultMap中额外发一个子SQL去查询emloyee关联的dept的数据,然后映射给Employee。

总结一下区别:前者是在SQL连表查询出两个表的内容,然后在ResultMap处理关系,映射结果。而后者是在SQL查询不连表,而是在ResultMap额外发SQL查询管理的对象。

1.修改xml,使用嵌套查询

<resultMap id="baseResultMap2" type="cn.lzh.mybatis._03_many_2_one.domain.Employee">
        <id column="e_id" property="id" />
        <result column="age" property="age" />
        <result column="username" property="username" />
        <result column="sex" property="sex" />
        <result column="age" property="age" />
        <association property="dept"
                     javaType="cn.lzh.mybatis._03_many_2_one.domain.Dept"
                     column="dept_id"                  select="cn.lzh.mybatis._03_many_2_one.mapper.DeptMapper.selectById"
                     
        />
    </resultMap>

    <select id="selectAll2" resultMap="baseResultMap">
        select
            e.id as e_id,
            e.username,
            e.age,
            e.sex,
            e.dept_id
        from employee
    </select>

 

 

这里我们的SQL并没有去关联dept,但是在resultMap处理结果集的时候,使用了<association 来映射 dept,

  • select="....DeptMapper.selectById" : 这里的意思是额外发一条SQL去查询当前employee关联的dept

  • column="dept_id" :额外SQL的参数使用 employee表中的dept_id,

在deptMapper.xml编写查询的SQL

 

<mapper namespace="cn.lzh.mybatis._03_many_2_one.mapper.DeptMapper">

    <select id="selectById" resultType="cn.lzh.mybatis._03_many_2_one.domain.Dept">
        select id,name from dept where id = #{id}
    </select>
    //....

5懒加载配置

 开启懒加载配置

<settings>
    <!--延迟加载总开关  true 开启延迟加载  false关闭延迟加载,即关联查询的时候会立刻查询关联对象-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!--侵入式延迟加载开关:
    侵入式延迟: 执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情属性时,就会马上执行关联对象的select查询
    默认是false
    查询主加载对象的任何属性时,都要执行关联对象的查询-->
    <setting name="aggressiveLazyLoading" value="false"/>
    <!-- lazyLoadTriggerMethods:指定对象的方法触发一次延迟加载。默认值:equals() clone() hashCode() ) toString() -->
    <setting name="lazyLoadTriggerMethods" value=""/>
</settings>

 

三.Sql编写高级特性-一对多

1.一对多保存

1.建立对象之间关系

//一对多,一方
public class ProductType {
    private Long id;
    private String name;

    //维护关系
    private List<Product> productList = new ArrayList<>();
----------------------------------------------------------------
//一对多,多
public class Product {
    private Long id;
    private String productName;
    private Long productTypeId;

 

 

并且建立表的关系

2.编写ProductTypeMapper接口,insert方法

3.编写ProductMapper接口,insert方法

4.编写ProductTypeMapper.xml,insert方法

<?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">

<!--
    namespace:命名空间 ,sql坐标(SQL在哪儿)
-->
<mapper namespace="cn.lzh.mapper.ProductTypeMapper">
    <insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        INSERT INTO product_type(name) values (#{name})
    </insert>
</mapper>

 

5.编写ProductMapper.xml,insert方法  

<?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">

<!--
    namespace:命名空间 ,sql坐标(SQL在哪儿)
-->
<mapper namespace="cn.lzh.mapper.ProductMapper">


    <insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        INSERT INTO product(product_name,product_type_id)

        values (#{productName},#{productTypeId})
    </insert>
</mapper>

 

6.编写Dao  

public class ProductDaoImpl implements IProductDao {
    @Override
    public void insert(Product product) {
        try(SqlSession sqlSession = MyBatisUtil.openSession()){
            ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);
            mapper.insert(product);
            sqlSession.commit();
        }
    } 

7.编写测试  

public class One2ManyTest {

    private IProductTypeDao productTypeDao = new ProductTypeDaoImpl();
    private IProductDao productDao = new ProductDaoImpl();

    @Test
    public void testAddProductType(){

        ProductType productType = new ProductType();
        productType.setName("鼠标");
        productTypeDao.insert(productType);

        productType.setProductList(Arrays.asList(
                new Product("鼠标2",productType.getId()),
                new Product("鼠标3",productType.getId()),
                new Product("鼠标4",productType.getId())
        ));

        productType.getProductList().forEach( product -> {
            productDao.insert(product);
        });
    }

}
 

 

四.缓存的使用

 

 

1.一级缓存

 一级缓存默认开启,在SqlSession中,要命中一级缓存需要使用同一个SqlSession发送相同的SQL。

 //通过ID查询
    @Override
    public Product selectById(Long id) throws IOException {
        try(
            //4.得到SqlSession : sql回话对象,用来执行Sql语句,包括事务的提交,回滚等
            SqlSession sqlSession = MyBatisUtil.openSession();
        ){

            ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);
            //一级缓存: 相同的SqlSession,相同的SQL
            //第一次查询 ,走MySql 把结果 以    sql=对象  的方式缓存到SqlSession
            //第二次查询,还是这个SqlSesion,还是这个SQL,那么就会命中缓存 , 直接返回值
            mapper.selectById(id);
            mapper.selectById(id);
        }
        return null;
    }

2.二级缓存

二级缓存在SqlSessionFactory中,要命中的条件是同一个SqlSessionFactory,发送相同的SQL。缓存是以namespace为单位的,不同namespace下的操作互不影响。

mapper.xml增加:

<cache />  开启二级缓存 

mybatis-config.xml :开启二级缓存  

<settings>
      <setting name="cacheEnabled" value="true"></setting>
</settings> 

 实体类实现序列化接口

class Employee implement Serilizable{
...

测试二级缓存 ,测试的时候,sqlSession执行完之后要提交事务,才能看到二级缓存效果。

1 一级是Sqlsession级别,一般我们不会直接使用,框架为了关联查询提高效率

2 二级缓存是SqlSessionFactory(整个应用中只有一份),可以使用来增强效率。

 

 

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

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

相关文章

远程同声传译如何实现?哪里提供专业的远程同声传译?

远程同传声传译&#xff0c;即线上同传翻译&#xff0c;是指翻译员通过非现场的网络方式进行的同声传译(实时翻译)。远程同声传译的实现依赖于一系列先进的技术手段和高效的协作流程。这一服务模式的出现&#xff0c;不仅打破了传统同声传译的地域限制&#xff0c;还为全球范围…

【JavaEE Spring 项目】消息队列的设计

消息队列的设计 一、消息队列的背景知识二、需求分析核心概念⼀个⽣产者, ⼀个消费者N 个⽣产者, N 个消费者Broker Server 中的相关概念核⼼ API交换机类型 (Exchange Type)持久化⽹络通信消息应答 三、 模块划分四、 项⽬创建五、创建核心类创建 Exchange创建 MSGQUeue创建 B…

9个免费游戏后端平台

在这篇文章中&#xff0c;您将看到 九个免费的游戏服务平台提供商&#xff0c;这可以帮助您开始在线多人游戏&#xff0c;而无需预先投入大量资金。 每个提供商都有非常独特的功能&#xff0c;因此成本应该只是决定时要考虑的方面之一。 我还从低预算项目的角度对免费提供商进…

基于单片机的篮球计分器设计

在当今的体育赛事中,比赛的计分系统对观众和运动员尤为重要,观众可以根据比分的实时显示为自己支持的队伍呐喊助威,运动员更是要靠着计分器来把握比赛的节奏,包括攻防转换、替补换人以及赛间休息等等。因此,为了让比赛进行得更加专业化和流畅化,我们有必要对比赛的计分系…

基于深度学习的鱼类分类检测系统(含UI界面、yolov8、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8 yolov8主要包含以下几种创新&#xff1a;         1. 可以任意更换主干结构&#xff0c;支持几百种网络主干。 数据集&#xff1a;     网上下载的数据集&#x…

MongoDB性能最佳实践:硬件和操作系统配置

欢迎阅读有关MongoDB性能最佳实践的系列博文。在往期文章中&#xff0c;我们已经讨论过查询模式和性能分析、事务和读/写关注等实现大规模性能的关键考虑因素。在本篇文章中&#xff0c;我们将讨论硬件和操作系统配置。 如果您在阿里云上部署MongoDB&#xff0c;那么阿里云会为…

网站做好这些准备后,上线SEO效果最佳

做网站很多年&#xff0c;也就最近两年理解这个精髓吗。网站上线之前&#xff0c;先在本地做好调试&#xff0c;修改&#xff0c;内容填充。这样后续做SEO会有意想不到的惊喜。 以前我自己做网站&#xff0c;都是直接解析域名到程序安装&#xff0c;上线就是一个空网站&#xf…

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器

本篇博客记录从0到1实现一个仿mudo库的One Thread One Loop式主从Reactor模型的高并发服务器组件。 在此之前我们要明确的是&#xff0c;该项目仅作为一个高并发服务器组件&#xff0c;因此该项目并不包含实际的业务需求处理内容。 前置知识背景 一、HTTP服务器 概念&#xf…

双指针算法练习

27. 移除元素 题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑…

conda安装playwright

进入conda安装目录激活环境 D:\Anacoda3>conda activate base 安装playwright &#xff08;base&#xff09;D:\Anacoda3>pip3 install playwright -i https://pypi.tuna.tsinghua.edu.cn/simple &#xff08;base&#xff09;D:\Anacoda3>python -m playwright insta…

学习Java的第八天

本节我们重点研究对象和类的概念。 对象&#xff08;Object&#xff09;是一个应用系统中的用来描述客观事物的实体&#xff0c;是有特定属性和行为&#xff08;方法&#xff09;的基本运行单位。是类的一个特殊状态下的实例。对象可以是一个实体、一个名词、一个可以想象为有…

【C++】AVL树的插入、旋转

目录 一、AVL树介绍1.1 概念1.2 定义 二、AVL树的实现2.1 插入2.2 旋转2.2.1 左单旋2.2.2 右单旋2.2.3 左右双旋2.2.4 右左双旋 一、AVL树介绍 1.1 概念 AVL树是高度平衡的二叉搜索树&#xff0c;相比普通的二叉搜索树&#xff0c;它防止了变成单支树的情况。因为AVL树每插入…

YOLO系列研究

研究YOLO系列 目录 COCO数据集YOLO-v3下载coco数据集 COCO数据集 coco数据集是一个大型的物体检测、分割和字幕数据集 COCO数据集是一个大型的、丰富的物体检测&#xff0c;分割和字幕数据集。这个数据集以scene understanding为目标&#xff0c;主要从复杂的日常场景中截取&a…

Vue:Steam同款登录验证数字输入框

一、效果展示 二、思路 使用多个Input&#xff0c;在输入和回撤时改变焦点 三、代码 <template><div class"page"><div class"mainBox"><div class"numberBox"><div class"inputBox" v-for"(item,…

Python实现企业微信自动打卡程序二:跳过节假日,随机打卡时间,定时任务,失败通知

实现打卡时间随机范围 既然我们程序写完后需要定时执行&#xff0c;那定时执行打卡就会导致每次上班或下班打卡时都是同一时间&#xff0c;这并不好&#xff0c;为了避免被发现&#xff0c;每次打卡时间都是同一时间&#xff0c;这里我们优化程序&#xff0c;增加随机等待时间来…

【C语言】strcpy函数的超细节详解(什么是strcpy,如何模拟实现strcpy?)

目录 一、观察strcpy()库函数的功能与实现 二、模仿实现strcpy()函数 &#x1f50d;优化代码 &#x1f50d;assert断言拦截 &#x1f50d;const修饰常量指针 &#x1f50d;返回值的加入 三、共勉 一、观察strcpy()库函数的功能与实现 首先我们先来观察一下库函数strcpy去实现…

基于SpringBoot的“农机电招平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“农机电招平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统首页界面图 农机机主注册界面图 农机界面图 …

【深度学习笔记】7_4 动量法momentum

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 7.4 动量法 在7.2节&#xff08;梯度下降和随机梯度下降&#xff09;中我们提到&#xff0c;目标函数有关自变量的梯度代表了目标函数…

Vue+OpenLayers7入门到实战:OpenLayers的Popup弹出框如何内嵌Vue组件内容和内嵌iframe网页,根据所点击要素动态切换弹框内容

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战 前言 本章介绍如何使用OpenLayers7在地图上实现OpenLayers的弹出框与VUE组件联动的能力。在Popup弹出框内容中嵌入vue的组件,以及iframe第三方网页和html元素等内容。 本章支持根据所点击要素动态切换弹框内容。…

今日AI:Midjourney角色一致性功能上线、Grok即将开源、OpenAI永远提供免费版ChatGPT

欢迎来到【今日AI】栏目!这里是你每天探索人工智能世界的指南&#xff0c;每天我们为你呈现AI领域的热点内容&#xff0c;聚焦开发者&#xff0c;助你洞悉技术趋势、了解创新AI产品应用。 新鲜AI产品点击了解:AIbase - 智能匹配最适合您的AI产品和网站 &#x1f4e2;一分钟速…