0基础学习Mybatis系列数据库操作框架——Mysql的Geometry数据处理之WKT方案

大纲

  • 几何结构构建
    • 点集合
    • 线
    • 线集合
    • 面集合
    • 几何信息集合
  • TypeHandler
  • SQL操作
    • 写入操作
    • 读取操作
    • 完整XML
  • Mapper
  • 测试代码
  • 建表SQL
  • 总结
  • 代码
  • 参考资料

WKT全称是Well-Known Text。它是一种表达几何信息的字符串内容。比如点可以用WKT表示为POINT (3 3);线可以用WKT表示为LINESTRING (1 1, 2 2)。
Mysql数据库可以存储一些几何类型数据,比如点、线、多边形等。这在一些基于地理信息的服务上比较有用,比如在地图上的商店地理坐标(点),或者路径规划中的行进路线(线)等。
目前我使用的Mysql是8.4.0版本,它支持如下几何类型数据结构。

类型说明样例图例
POINT (3 3)在这里插入图片描述
点集合MULTIPOINT ((1 1), (2 2), (3 3))
线LINESTRING (1 1, 2 2)在这里插入图片描述
线集合MULTILINESTRING ((1 1, 2 2), (3 3, 4 4))
多边形POLYGON ((1 1, 2 2, 3 3, 1 1))在这里插入图片描述
多边形集合MULTIPOLYGON (((1 1, 2 2, 3 3, 1 1)), ((4 4, 5 5, 6 6, 4 4)))
多种几何类型集合GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (1 1, 2 2), POLYGON ((1 1, 2 2, 3 3, 1 1)))

一般我们会使用org.locationtech.jts的Geometry类来表达几何信息。

<dependency>
    <groupId>org.locationtech.jts</groupId>
    <artifactId>jts-core</artifactId>
    <version>1.19.0</version>
</dependency>

然后使用下面的方法构建各种结构

几何结构构建

GeometryFactory geometryFactory = new GeometryFactory();
Geometry geometry = geometryFactory.createPoint(new Coordinate(3, 3));

点集合

GeometryFactory geometryFactory = new GeometryFactory();
LineString lineString = geometryFactory
        .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) });

线

GeometryFactory geometryFactory = new GeometryFactory();
LineString lineString = geometryFactory
        .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) });

线集合

GeometryFactory geometryFactory = new GeometryFactory();
MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[] {
        geometryFactory
                .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
        geometryFactory
                .createLineString(new Coordinate[] { new Coordinate(3, 3), new Coordinate(4, 4) })
});

GeometryFactory geometryFactory = new GeometryFactory();
Polygon polygon = geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1),
 					new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) });

面集合

GeometryFactory geometryFactory = new GeometryFactory();
MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[] {
        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
                new Coordinate(3, 3), new Coordinate(1, 1) }),
        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(4, 4), new Coordinate(5, 5),
                new Coordinate(6, 6), new Coordinate(4, 4) })
});

几何信息集合

GeometryFactory geometryFactory = new GeometryFactory();
GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[] {
        geometryFactory.createPoint(new Coordinate(1, 1)),
        geometryFactory.createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
                new Coordinate(3, 3), new Coordinate(1, 1) })
});

下面我们需要将这些结构保存到Mysql数据库中。
由于org.locationtech.jts.geom.Geometry和Mysql内部存储的Geometry不配,所以需要转换操作,于是就要引入typehandler。

TypeHandler

package org.example.typehandlers;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class GeometryTypeWKTHandler extends BaseTypeHandler<Geometry>  {
    private static GeometryFactory factory = new GeometryFactory(new PrecisionModel(PrecisionModel.FLOATING), 4326);

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Geometry parameter, JdbcType jdbcType) throws SQLException {
        String str = serializeGeometry(parameter);
        ps.setString(i, str);;
    }

    @Override
    public Geometry getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String str = rs.getString(columnName);
        try {
            return deserializeGeometry(str);
        } catch (ParseException e) {
            throw new SQLException(e);
        }
    }

    @Override
    public Geometry getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String str = rs.getString(columnIndex);
        try {
            return deserializeGeometry(str);
        } catch (ParseException e) {
            throw new SQLException(e);
        }
    }

    @Override
    public Geometry getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String str = cs.getString(columnIndex);
        try {
            return deserializeGeometry(str);
        } catch (ParseException e) {
            throw new SQLException(e);
        }
    }

    private static String serializeGeometry(Geometry geometry) {
        WKTWriter writer = new WKTWriter(2);
        return writer.write(geometry);
    }

    private static Geometry deserializeGeometry(String wkt) throws ParseException {
        return new WKTReader(factory).read(wkt);
    }

}

WKTWriter会将org.locationtech.jts.geom.Geometry转换为String,然后交由SQL语句处理;
WKTReader会将SQL语句读取出来的String转换为org.locationtech.jts.geom.Geometry对象。
在这里插入图片描述

SQL操作

在上图我们看到,TypeHandler主要使用String类型作为媒介来和SQL语句联系。那么SQL语句是如何把String转成Mysql的Geometry内部结构的呢?
这就需要引入ST_GeomFromText和ST_AsText。
ST_GeomFromText可以将WKT格式的几何信息转换为Mysql内部的Geometry结构。比如

ST_GeomFromText('MULTIPOINT (1 1, 2 2, 3 3)')

ST_AsText则可以将Mysql内部的Geometry结构转换为WKT格式的几何信息
在这里插入图片描述

在Mybatis的SQL XML中

写入操作

对org.locationtech.jts.geom.Geometry结构(即geometry字段)使用org.example.typehandlers.GeometryTypeWKTHandler处理成WTK(字符串)几何信息格式后,用ST_GeomFromText转换成Mysql内部的Geometry结构,然后存储。

    <insert id="insertOne" parameterType="org.example.model.GeometryData"  useGeneratedKeys="true" keyProperty="id">
        insert into geometry_data(id, geometry, update_time, create_time) values
        (#{id}, ST_GeomFromText(#{geometry, jdbcType=BLOB, typeHandler=org.example.typehandlers.GeometryTypeWKTHandler}), now(), now())
    </insert>

这儿需要注意的是ST_GeomFromText不是万能的。比如针对“几何信息集合”(GeometryCollection)则需要使用ST_GeomCollFromText来转换

    <insert id="insertGeometryCollection" parameterType="org.example.model.GeometryData"  useGeneratedKeys="true" keyProperty="id">
        insert into geometry_data(id, geometry, update_time, create_time) values
        (#{id}, ST_GeomCollFromText(#{geometry, jdbcType=BLOB, typeHandler=org.example.typehandlers.GeometryTypeWKTHandler}), now(), now())
    </insert>

读取操作

由于需要对geometry字段特殊处理,所以不能使用Select * From geometry_data,而需要把每个参数都写好。
ST_AsText会将Mysql的内部的Geometry结构转换成WKT格式(字符串)的几何信息,然后交由org.example.typehandlers.GeometryTypeWKTHandler转换成org.locationtech.jts.geom.Geometry结构。

    <resultMap id="GeometryDataResultMap" type="org.example.model.GeometryData">
        <result property="id" column="id"/>
        <result property="geometry" column="geometry" typeHandler="org.example.typehandlers.GeometryTypeWKTHandler" jdbcType="BLOB"/>
        <result property="updateTime" column="update_time"/>
        <result property="createTime" column="create_time"/>
    </resultMap>

    <select id="findAll" resultMap="GeometryDataResultMap">
        select id, ST_AsText(geometry) AS geometry, update_time, create_time from geometry_data
    </select>

完整XML

<?xml version="1.0" encoding="UTF-8"?>
<!-- AllTypeMapper-1.xml -->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.GeometryDataWKTMapper">
    <resultMap id="GeometryDataResultMap" type="org.example.model.GeometryData">
        <result property="id" column="id"/>
        <result property="geometry" column="geometry" typeHandler="org.example.typehandlers.GeometryTypeWKTHandler" jdbcType="BLOB"/>
        <result property="updateTime" column="update_time"/>
        <result property="createTime" column="create_time"/>
    </resultMap>

    <select id="findAll" resultMap="GeometryDataResultMap">
        select id, ST_AsText(geometry) AS geometry, update_time, create_time from geometry_data
    </select>

    <select id="find" resultMap="GeometryDataResultMap">
        select id, ST_AsText(geometry) AS geometry, update_time, create_time from geometry_data where id = #{id}
    </select>

    <insert id="insertOne" parameterType="org.example.model.GeometryData"  useGeneratedKeys="true" keyProperty="id">
        insert into geometry_data(id, geometry, update_time, create_time) values
        (#{id}, ST_GeomFromText(#{geometry, jdbcType=BLOB, typeHandler=org.example.typehandlers.GeometryTypeWKTHandler}), now(), now())
    </insert>

    <insert id="insertList" parameterType="list">
        insert into geometry_data(id, geometry, update_time, create_time) values
        <foreach item="item" collection="list" separator=",">
            (#{item.id}, ST_GeomFromText(#{item.geometry, jdbcType=BLOB, typeHandler=org.example.typehandlers.GeometryTypeWKTHandler}), now(), now())
        </foreach>
    </insert>

    <update id="updateOne" parameterType="org.example.model.GeometryData">
        update geometry_data set geometry = ST_GeomFromText(#{geometry, jdbcType=BLOB, typeHandler=org.example.typehandlers.GeometryTypeWKTHandler}), update_time = now() where id = #{id} 
    </update>

    <insert id="insertGeometryCollection" parameterType="org.example.model.GeometryData"  useGeneratedKeys="true" keyProperty="id">
        insert into geometry_data(id, geometry, update_time, create_time) values
        (#{id}, ST_GeomCollFromText(#{geometry, jdbcType=BLOB, typeHandler=org.example.typehandlers.GeometryTypeWKTHandler}), now(), now())
    </insert>

</mapper>

Mapper

package org.example.mapper;

import java.util.List;

import org.example.model.GeometryData;

public interface GeometryDataWKTMapper {
    public List<GeometryData> findAll();
    public GeometryData find(Long id);
    public Long insertOne(GeometryData geometryData);
    public Long insertList(List<GeometryData> geometryDataList);
    public Long updateOne(GeometryData geometryData);
    public Long insertGeometryCollection(GeometryData geometryData);
} 

测试代码

package org.example;

import static org.junit.jupiter.api.Assertions.fail;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.example.mapper.GeometryDataWKTMapper;
import org.example.model.GeometryData;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Polygon;

public class GeometryDataWKTTest {
    private static SqlSessionFactory sqlSF;

    @BeforeAll
    static void CreateSessionFactory() throws IOException {
        InputStream in = Resources.getResourceAsStream("mybatis/config/mybatis-config-geometry-wkt.xml");
        sqlSF = new SqlSessionFactoryBuilder().build(in);
    }

    @Test
    public void testFindAll() {
        List<GeometryData> all = null;
        try (SqlSession session = sqlSF.openSession()) {
            all = session.getMapper(GeometryDataWKTMapper.class).findAll();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        for (GeometryData a : Objects.requireNonNull(all)) {
            System.out.println(a.getGeometry());
        }
    }

    @Test
    public void testFind() {
        try (SqlSession session = sqlSF.openSession()) {
            GeometryDataWKTMapper GeometryDataWKTMapper = session.getMapper(GeometryDataWKTMapper.class);
            GeometryData one = GeometryDataWKTMapper.find(1L);
            System.out.println(one.getGeometry());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Test
    public void testInsert() {
        try (SqlSession session = sqlSF.openSession()) {
            GeometryDataWKTMapper GeometryDataWKTMapper = session.getMapper(GeometryDataWKTMapper.class);
            GeometryData geometryData = new GeometryData();
            GeometryFactory geometryFactory = new GeometryFactory();
            Coordinate coordinate = new Coordinate(1, 1);
            Geometry geometry = geometryFactory.createPoint(coordinate);
            geometryData.setGeometry(geometry);
            long count = GeometryDataWKTMapper.insertOne(geometryData);
            System.out.println(count);
            session.commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            fail();
        }
    }

    @Test
    public void testUpdate() {
        try (SqlSession session = sqlSF.openSession()) {
            GeometryDataWKTMapper GeometryDataWKTMapper = session.getMapper(GeometryDataWKTMapper.class);
            GeometryData geometryData = new GeometryData();
            GeometryFactory geometryFactory = new GeometryFactory();
            Coordinate coordinate = new Coordinate(2, 2);
            Geometry geometry = geometryFactory.createPoint(coordinate);
            geometryData.setId(1L);
            geometryData.setGeometry(geometry);
            long count = GeometryDataWKTMapper.updateOne(geometryData);
            System.out.println(count);
            session.commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            fail();
        }
    }

    @Test
    public void testInsertList() {
        try (SqlSession session = sqlSF.openSession()) {
            GeometryDataWKTMapper GeometryDataWKTMapper = session.getMapper(GeometryDataWKTMapper.class);

            List<GeometryData> geometryDataList = new ArrayList<>();
            {
                GeometryData geometryData = new GeometryData();
                GeometryFactory geometryFactory = new GeometryFactory();
                Coordinate coordinate = new Coordinate(3, 3);
                Geometry geometry = geometryFactory.createPoint(coordinate);
                geometryData.setGeometry(geometry);
                geometryDataList.add(geometryData);
            }

            {
                GeometryData geometryData = new GeometryData();
                GeometryFactory geometryFactory = new GeometryFactory();
                LineString lineString = geometryFactory
                        .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) });
                geometryData.setGeometry(lineString);
                geometryDataList.add(geometryData);
            }

            {
                GeometryData geometryData = new GeometryData();
                GeometryFactory geometryFactory = new GeometryFactory();
                MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[] {
                        geometryFactory
                                .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
                        geometryFactory
                                .createLineString(new Coordinate[] { new Coordinate(3, 3), new Coordinate(4, 4) })
                });
                geometryData.setGeometry(multiLineString);
                geometryDataList.add(geometryData);
            }

            {
                GeometryData geometryData = new GeometryData();
                GeometryFactory geometryFactory = new GeometryFactory();
                MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[] {
                        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
                                new Coordinate(3, 3), new Coordinate(1, 1) }),
                        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(4, 4), new Coordinate(5, 5),
                                new Coordinate(6, 6), new Coordinate(4, 4) })
                });
                geometryData.setGeometry(multiPolygon);
                geometryDataList.add(geometryData);
            }

            // {
            //     GeometryData geometryData = new GeometryData();
            //     GeometryFactory geometryFactory = new GeometryFactory();
            //     LinearRing linearRing = geometryFactory.createLinearRing(new Coordinate[] { new Coordinate(1, 1),
            //             new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) });
            //     geometryData.setGeometry(linearRing);
            //     geometryDataList.add(geometryData);
            // }

            {
                GeometryData geometryData = new GeometryData();
                GeometryFactory geometryFactory = new GeometryFactory();
                MultiPoint multiPoint = geometryFactory.createMultiPointFromCoords(
                        new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2), new Coordinate(3, 3) });
                geometryData.setGeometry(multiPoint);
                geometryDataList.add(geometryData);
            }

            {
                GeometryData geometryData = new GeometryData();
                GeometryFactory geometryFactory = new GeometryFactory();
                Polygon polygon = geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1),
                        new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) });
                geometryData.setGeometry(polygon);
                geometryDataList.add(geometryData);
            }

            // {
            //     GeometryData geometryData = new GeometryData();
            //     GeometryFactory geometryFactory = new GeometryFactory();
            //     GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[] {
            //             geometryFactory.createPoint(new Coordinate(1, 1)),
            //             geometryFactory.createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
            //             geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
            //                     new Coordinate(3, 3), new Coordinate(1, 1) })
            //     });
            //     geometryData.setGeometry(geometryCollection);
            //     geometryDataList.add(geometryData);
            // }

            long count = GeometryDataWKTMapper.insertList(geometryDataList);
            System.out.println(count);
            session.commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            fail();
        }
    }

    @Test
    public void testInsertGeometryCollection() {
        try (SqlSession session = sqlSF.openSession()) {
            GeometryDataWKTMapper GeometryDataWKTMapper = session.getMapper(GeometryDataWKTMapper.class);
            GeometryData geometryData = new GeometryData();
            GeometryFactory geometryFactory = new GeometryFactory();
            GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[] {
                    geometryFactory.createPoint(new Coordinate(1, 1)),
                    geometryFactory.createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
                    geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
                            new Coordinate(3, 3), new Coordinate(1, 1) })
            });
            geometryData.setGeometry(geometryCollection);
            Long index = GeometryDataWKTMapper.insertGeometryCollection(geometryData);
            System.out.println(index);
            session.commit();
        } catch(Exception e) {
            System.out.println(e.getMessage());
            fail();
        }
    }
}

在这里插入图片描述

建表SQL

CREATE TABLE `geometry_data` (
    `id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
    `geometry` GEOMETRY NOT NULL COMMENT '几何信息',
    `create_time` timestamp  NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_time` timestamp  NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
    `deleted` boolean DEFAULT false COMMENT '是否已被删除',
    PRIMARY KEY (`id`),
    SPATIAL INDEX `spatial_geometry` (`geometry`)
) COMMENT='几何数据表';

总结

很多数据库为了兼容Mysql,针对Geometry类型,在WKT模式下是兼容的。因为如何将WKT转换成自己数据库内部的结构,即对ST_GeomFromText等方法的实现是可以自己内部处理,让用户不会感知。这让WKT方案在跨数据库时有比较好的兼容性。
但是如果只是针对Mysql数据库,或者像OceanBase这类对Mysql底层也兼容很好的数据库,则可以考虑WKB方案。这块的内容我们会在《0基础学习Mybatis系列数据库操作框架——Mysql的Geometry数据处理之WKB方案》中介绍。

代码

https://github.com/f304646673/mybatis_demo

参考资料

  • https://dev.mysql.com/doc/refman/8.0/en/gis-data-formats.html#gis-wkb-format
  • https://dev.mysql.com/doc/refman/8.0/en/gis-wkt-functions.html#function_st-geomfromtext
  • https://www.keene.edu/campus/maps/tool/

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

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

相关文章

uniapp使用内置的switch组件的问题

说明 开关选择器 属性说明 属性名类型默认值说明平台差异说明checkedBooleanfalse是否选中disabledBooleanfalse是否禁用不支持&#xff1a;抖音小程序、飞书小程序typeStringswitch 样式 有效值&#xff1a;switch、checkbox colorColorswitch的颜色&#xff0c;通css的co…

【Text2SQL 经典模型】X-SQL

论文&#xff1a;X-SQL: reinforce schema representation with context ⭐⭐⭐⭐ Microsoft, arXiv:1908.08113 X-SQL 与 SQLova 类似&#xff0c;使用 BERT style 的 PLM 来获得 representation&#xff0c;只是融合 NL question 和 table schema 的信息的方式不太一样&#…

响应式处理-一篇打尽

纯pc端响应式 pc端平常用到的响应式布局 大致就如下三种&#xff0c;当然也会有其他方法&#xff0c;欢迎评论区补充 将div height、width设置成100% flex布局 flex布局主要是将flex-wrap: wrap&#xff0c; 最后&#xff0c;你可以通过给子元素设置 flex 属性来控制它们的…

基于STM32实现智能风扇控制系统

目录 文章主题环境准备智能风扇控制系统基础代码示例&#xff1a;实现智能风扇控制系统 PWM控制风扇速度温度传感器数据读取串口通信控制应用场景&#xff1a;智能家居与环境调节问题解决方案与优化收尾与总结 1. 文章主题与命名 文章主题 本教程将详细介绍如何在STM32嵌入式…

Docker仅需3步搭建免费私有化的AI搜索引擎-FreeAskInternet!

简介 FreeAskInternet 是一个完全免费、私有且本地运行的搜索引擎&#xff0c;并使用 LLM 生成答案&#xff0c;无需 GPU。用户可以提出问题&#xff0c;系统会进行多引擎搜索&#xff0c;并将搜索结果合并到ChatGPT3.5 LLM中&#xff0c;并根据搜索结果生成答案。 什么是 Fr…

Windows11的这个地方暴露着你的隐私,把它关掉避免尴尬

前言 现在的电脑真的是越来越智能化&#xff01;现在有很多小伙伴都是用着Windows11的吧&#xff01;用习惯了Windows11之后&#xff0c;突然发现它还是挺顺手的。 但不知道你有没有发现&#xff0c;Windows11上面有个地方暴露着你的隐私。这个隐私可能是某个小姐姐的图片&am…

【EasyX】快速入门——消息处理,音频

1.消息处理 我们先看看什么是消息 1.1.获取消息 想要获取消息,就必须学会getmessage函数 1.1.1.getmessage函数 有两个重载版本,它们的作用是一样的 参数filter可以筛选我们需要的消息类型 我们看看参数filter的取值 当然我们可以使用位运算组合这些值 例如,我们…

sequence cache太小导致enq: SQ – contention

当业务卡的时候&#xff0c;发现大量等待事件为enq: SQ – contention&#xff0c;检查awr的top 5事件&#xff1a; sql语句对sequence的调用非常频繁&#xff1a; 对这些语句排查发现sequence cache值均为默认20&#xff0c;调大cache到1000值&#xff1a; SQL> select SE…

sql select获取mysql所有数据库,指定数据库下的所有表名

介绍一下 MySQL 8.0 中默认安装的几个系统数据库/模式。 当我们安装 MySQL 8.0 并初始化数据库之后&#xff0c;默认会创建以下系统数据库&#xff1a; mysql&#xff0c;存储了 MySQL 服务器正常运行所需的各种信息。 information_schema&#xff0c;提供了访问数据库元数据…

HarmonyOS之ArkUI布局设计常见细节

这里写目录标题 1. Button设置带有渐变色的背景图片无效1.1 问题分析1.2 成功案例 2. 路由跳转失败2.1 问题分析 1. Button设置带有渐变色的背景图片无效 1.1 问题分析 说明&#xff1a;设置颜色渐变需先设置backgroundColor为透明色。 Button($r(app.string.login), { type…

海外仓储管理系统:提升效率,标准化海外仓管理,科技赋能业务

海外仓作为跨境物流的关键一环&#xff0c;完全可以说海外仓的效率直接决定了后续物流的整体运作效率。 对于海外仓而言&#xff0c;一套高效&#xff0c;易用的海外仓储系统&#xff0c;无疑将成为提升企业竞争力的重要工具&#xff0c;帮助海外仓实现从野蛮生长到标准化管理…

项目十二:简单的python基础爬虫训练

许久未见&#xff0c;甚是想念&#xff0c;今日好运&#xff0c;为你带好运。ok&#xff0c;废话不多说&#xff0c;希望这门案例能带你直接快速了解并运用。&#x1f381;&#x1f496; 基础流程 第一步&#xff1a;安装需要用到的requests库&#xff0c;命令如下 pip inst…

网络拓扑—DNS服务搭建

文章目录 DNS服务搭建网络拓扑配置网络DNSPC 安装DNS服务配置DNS服务创建正向查找区域创建反向查找区域创建子域名 PC机DNS域名解析 DNS服务搭建 网络拓扑 为了节省我的U盘空间&#xff0c;没有用路由器&#xff0c;所以搭建的环境只要在同网段即可。 //交换机不用考虑 DNS&a…

探数API统计分享-1949年-2021年中国历年夏粮产量统计报告

​​​​​​​​中国历年夏粮产量​&#xff0c;为1949年到2021年我国每年的夏粮产量数据。2021年&#xff0c;我国夏粮产量为14596万吨&#xff0c;比上年增长2.2%。 数据统计单位为&#xff1a;万吨 。 我国夏粮产量有多少&#xff1f; 2021年&#xff0c;我国夏粮产量为1…

计算机网络安全控制技术

1.防火墙技术 防火墙技术是近年来维护网络安全最重要的手段&#xff0c;但是防火墙不是万能的&#xff0c;需要配合其他安全措施来协同 2.加密技术 目前加密技术主要有两大类&#xff1a;对称加密和非对称加密 3.用户识别技术 核心是识别网络者是否是属于系统的合法用户 …

2024.5.26 机器学习周报

目录 引言 Abstract 文献阅读 1、题目 2、引言 3、创新点 4、Motivation 5、naive Lite-HRNet 6、Lite-HRNet 7、实验 深度学习 解读SAM(Segment Anything Model) 1、SAM Task 2、SAM Model 2.1、Patch Embedding 2.2、Positiona Embedding 2.3、Transformer …

VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION--论文笔记

论文笔记 论文来源 Very Deep Convolutional Networks for Large-Scale Image Recognition 代码来源 还没上传 数据集 这里采用的是猫狗数据集 还没上传 1论文摘要的翻译 在这项工作中&#xff0c;我们研究了卷积网络深度对其在大规模图像识别设置中的准确性的影响。我…

Offline RL : Beyond Reward: Offline Preference-guided Policy Optimization

ICML 2023 paper code preference based offline RL&#xff0c;基于HIM&#xff0c;不依靠额外学习奖励函数 Intro 本研究聚焦于离线偏好引导的强化学习&#xff08;Offline Preference-based Reinforcement Learning, PbRL&#xff09;&#xff0c;这是传统强化学习&#x…

QT编译安装mqtt连接Onenet云平台

目录 文章目录 目录前言一、编译mqtt**1.从官方源码下载对应自己qt版本的源文件&#xff0c;【此源文件不要有中文名称的路径】****2.打开qtmqtt.pro工程****3.选择qt的编译器&#xff0c;【我选择的是mingw 64】****4.将qtmqtt的源码头文件移植到QT的安装目录下面****5.编译**…

【译】MySQL复制入门: 探索不同类型的MySQL复制解决方案

原文地址&#xff1a;An Introduction to MySQL Replication: Exploring Different Types of MySQL Replication Solutions 在这篇博文中&#xff0c;我将深入介绍 MySQL 复制&#xff0c;回答它是什么、如何工作、它的优势和挑战&#xff0c;并回顾作为 MySQL 环境&#xff0…