在入库和查询中需要自动的让geometry的类型和实体类中的类型映射。

实体类中接收参数是String类型(geoJson)

PostGis中的geometry类型是十六进制的扩展WKB类型(EWKB),

虽然Postgis数据库中提供类类型转换函数,能转换各种类型postgis常用命令_yaoct的博客-CSDN博客

但是基于mybatis框架查询时,就需要用java代码来转换。初步方案时mybatis中的类型转换器。

先引入java处理GIS的库,这里用的是Geotools库。

1.java代码中数据类型的转换

geotools的maven引入:

<!-- geotools的远程库 --><repositories><repository><id>osgeo</id><name>OSGeo Release Repository</name><url>https://repo.osgeo.org/repository/release/</url><snapshots><enabled>false</enabled></snapshots><releases><enabled>true</enabled></releases></repository><repository><id>osgeo-snapshot</id><name>OSGeo Snapshot Repository</name><url>https://repo.osgeo.org/repository/snapshot/</url><snapshots><enabled>true</enabled></snapshots><releases><enabled>false</enabled></releases></repository></repositories><dependencies><!--geotool https://docs.geotools.org/latest/userguide/tutorial/quickstart/maven.html--><dependency><groupId>org.geotools</groupId><artifactId>gt-geojson</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-main</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-opengis</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-referencing</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-metadata</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-epsg-hsql</artifactId><version>${geotools.version}</version></dependency></dependencies>

Geotools工具类转换WKB和Geojson

WKBReader reader = new WKBReader( );Geometry geometry = reader.read(WKBReader.hexToBytes("0101000020E61000002C39382229FD5D4085716007088C3E40"));// 设置保留6位小数,否则GeometryJSON默认保留4位小数GeometryJSON geometryJson = new GeometryJSON(7);String s = geometryJson.toString(geometry);System.out.println(s);//{"type":"Point","coordinates":[119.9556356,30.5469975]}//EWKB->转geojson丢失信息Geometry read = geometryJson.read("{\"type\":\"Point\",\"coordinates\":[119.9556356,30.5469975]}");System.out.println(read.toString());WKBWriter wkbWriter = new WKBWriter();byte[] write = wkbWriter.write(geometry);String s1 = WKBWriter.toHex(write);System.out.println(s1);

2.mybatis-plus类型转换器

这里框架用的是mybatis-plus,所有使用转换时,mybatis-plus中的实体类也要配置一些转换注解,其他和mybaitis中的xml配置属性相同。参考

MyBatis Plus 自动类型转换之TypeHandler


@Data
@ToString
@TableName (value = "test_table",autoResultMap = true)
@ApiModel ("test")
public class TestTable  implements Serializable {private static final long serialVersionUID =  8881418345724766899L;@TableId(value = "id")private Integer id;@ApiModelProperty(value = "二进制WKB数据")@TableField(value = "position",typeHandler = WKB2GeoJsonTypeHandler.class)@JsonRawValueprivate String position;@TableField("name")private String name;}

mybatis-plus配置添加转换器包路径,类似mybatis,之后用于写xml中sql

mybatis-plus:type-handlers-package: com.zjzy.mapper.typehandlerconfiguration:map-underscore-to-camel-case: trueauto-mapping-behavior: fulllog-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath*:mapper/**/*Mapper.xml

3.mybatis类型转换器转换geometry格式

因为缺少JDBC映射,数据库开始报错:‘类型为 geometry, 但表达式的类型为 character varying’

参考:Mybatis-plus读取和保存Postgis geometry数据 - 简书

应该是缺少JDBC-type类型。引入响应的postGIS驱动

添加maven包:

        <!-- 这里会补充mybatis缺少的JDBC-Type如postGis中的geometry类型 --><dependency><groupId>net.postgis</groupId><artifactId>postgis-jdbc</artifactId><version>2.5.0</version></dependency>

类型转换器代码:

package com.zjzy.mapper.typehandler;import com.zjzy.mapper.CommonCodeMapper;
import com.zjzy.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.WKBReader;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.ParseException;
import org.postgis.PGgeometry;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Set;/*** @version 2.0* @description* @Author yaoct* @create 2021/12/22 16:19*/
@Slf4j
public class WKB2GeoJsonTypeHandler implements TypeHandler<String> {/*** 插入数据,转换,geoJson2EWKB* @param ps* @param i* @param parameter* @param jdbcType* @throws SQLException*/@Overridepublic void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
//EWKB是pg数据库自定义的类型,所以需要用数据库函数,插入数据库一般次数较少,这样并不会对数据库造成过大负担
//        CommonCodeMapper mapper = SpringContextUtil.getBean(CommonCodeMapper.class);
//        String EWKB = mapper.geo2EWKB(parameter);
//        PGgeometry ewkb = new PGgeometry(EWKB);
//        ps.setObject(i,ewkb);//通过geoTool转换WKBGeometryJSON geometryJson = new GeometryJSON(7);Geometry read = null;try {read = geometryJson.read(parameter);} catch (IOException e) {e.printStackTrace();}
//        System.out.println(read.toString());read.setSRID(4326);
//        GeometryJSON geometryJson = new GeometryJSON(7);WKBWriter wkbWriter = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN,true);byte[] write = wkbWriter.write(read);String s1 = WKBWriter.toHex(write);PGgeometry ewkb = new PGgeometry(s1);ps.setObject(i,ewkb);}/*** 取出数据转换,WKB->Geojson* @param rs* @param columnName* @return* @throws SQLException*/@Overridepublic String getResult(ResultSet rs, String columnName) throws SQLException {String WKB = rs.getString(columnName);if(WKB==null){return null;}WKBReader reader = new WKBReader( );Geometry geometry = null;try {geometry = reader.read(WKBReader.hexToBytes(WKB));} catch (ParseException e) {//转换失败return null;}//转换成4326try {int srid = geometry.getSRID();CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:"+srid,true);CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326",true);MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS,true);geometry = JTS.transform(geometry, transform);} catch (Exception e) {e.printStackTrace();}// 设置保留6位小数,否则GeometryJSON默认保留4位小数GeometryJSON geometryJson = new GeometryJSON(7);return geometryJson.toString(geometry);}@Overridepublic String getResult(ResultSet rs, int columnIndex) throws SQLException {return null;}@Overridepublic String getResult(CallableStatement cs, int columnIndex) throws SQLException {return null;}
}
@Component
public class SpringContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextUtil.applicationContext = applicationContext;}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通过name获取 Bean.public static Object getBean(String name) {return getApplicationContext().getBean(name);}//通过class获取Bean.public static <T> T getBean(Class<T> clazz) {return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublic static <T> T getBean(String name, Class<T> clazz) {return getApplicationContext().getBean(name, clazz);}//关闭springbootpublic static void close(){((ConfigurableApplicationContext)(getApplicationContext())).close();}//得到当前线程的HttpServletResponse,可在静态方法中得到public static HttpServletResponse getHttpServletResponse(){return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();}//得到当前线程的HttpServletRequest,可在静态方法中得到public static HttpServletRequest getHttpServletRequest(){return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();}}
@Repository
public interface CommonCodeMapper extends BaseMapper<CommonCode> {/*** EWKB是pg数据库自定义的类型,所以需要用数据库函数* @param geoJson* @return*/@Select("select ST_GeomFromGeoJSON(#{geoJson})")String geo2EWKB(String geoJson);}

=============================mybatis中使用================================

在mapper类中使用示例:https://www.jianshu.com/p/6465189984b0

/*** 使用ResultMap */
@Results(id = "userMap", value = {//可以使用这种方式来处理字段名和数据库表字段名不一致的情况@Result(column = "username", property = "username", jdbcType=JdbcType.VARCHAR,typeHandler = WKB2GeoJsonTypeHandler.class),@Result(column = "passwd", property = "passwd", jdbcType=JdbcType.VARCHAR),@Result(column = "birth_day", property = "birthDay", jdbcType=JdbcType.VARCHAR)})
@Select("SELECT * FROM t_user WHERE id=#{id}")
User loadByIdResultMap(Long id);/*** 引用其他的Result */
@ResultMap("userMap")
@Select("SELECT * FROM t_user WHERE id=#{id}")
User loadByIdResultMapReference(Long id);

在xml中使用示例示例:

    <resultMap id="locationResultMap" type="com.zjzy.model.po.ExaminationApplication"><result typeHandler="com.zjzy.mapper.typehandler.WKB2GeoJsonTypeHandler" column="dig_position" javaType="String"property="digPosition"/></resultMap><select id="selectExaminationApplicationByPage" resultMap="locationResultMap"></select>

注意:

1.postgresql的JDBC实现中(驱动),数据自定义的类型对应java类型一般都通过实现

org.postgresql.util.PGobject。

2.对应数据库geometry类型的java类不在PG的JDBC驱动的实现类中,因为geometry类型在PG的扩展postgis中,所以响应的要引入postGIS这部分的驱动,

3. PG的JDBC驱动底层也是通过SOCKET连接org.postgresql.core.PGStream#createSocket

4.原生jdbc接口在java.sql包中。

5.一定要实现org.postgresql.util.PGobject#getValue方法因为,org.postgresql.jdbc.PgPreparedStatement#setPGobject底层调用org.postgresql.jdbc.PgPreparedStatement#setString(int, java.lang.String, int)时

要用到org.postgresql.util.PGobject#getValue方法

==============================2022.12.12============================

以下方式不用导入 net.postgis包

package com.zjzy.mapper.typehandler;import com.alibaba.fastjson.JSONObject;
import com.zjzy.util.GisUtil;
import com.zjzy.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.WKBReader;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.ByteOrderValues;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKBWriter;
import org.locationtech.jts.io.WKTWriter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.postgis.PGbox2d;
import org.postgis.PGgeometry;
import org.postgresql.util.PGobject;
import org.springframework.core.env.Environment;import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @version 1.0* @description* @Author yaoct* @create 2021/12/22 16:19*/
@Slf4j
public class WKB2GeoJsonTypeHandler implements TypeHandler<String> {/*** 插入数据,转换,geoJson2EWKB* @param ps* @param i* @param parameter* @param jdbcType* @throws SQLException*/@Overridepublic void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {//EWKB是pg数据库自定义的类型,所以需要用数据库函数,插入数据库一般次数较少,这样并不会对数据库造成过大负担
//        CommonCodeMapper mapper = SpringContextUtil.getBean(CommonCodeMapper.class);
//        String EWKB = mapper.geo2EWKB(parameter);
//        PGgeometry ewkb = new PGgeometry(EWKB);
//        ps.setObject(i,ewkb);//通过geoTool转换WKBGeometryJSON geometryJson = new GeometryJSON(7);Geometry geometry = null;try {geometry = geometryJson.read(parameter);} catch (IOException e) {e.printStackTrace();}
//        System.out.println(read.toString());geometry.setSRID(4326);
//        GeometryJSON geometryJson = new GeometryJSON(7);//方式1.基于net.postgis
//        WKBWriter wkbWriter = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN,true);
//        byte[] write = wkbWriter.write(geometry);
//        String s1 = WKBWriter.toHex(write);
//        PGgeometry ewkb = new PGgeometry(s1);//EWKB比WKB多了SRID头字符串,PGgeometry.toString()会自动添加SRID
//        ps.setObject(i,ewkb);//方式2.设置ewkb,Postgresql驱动会先去数据库 pg_catalog.pg_type 查出geometry的类型id,这里的geometry字符串对应数据库pg_catalog.pg_type表中的geometry//以下方式不用导入net.postgis包
//        PGobject pGobject = new PGobject();
//        pGobject.setType("geometry");
//        pGobject.setValue(s1);
//        ps.setObject(i,pGobject);//方式3.设置拼接ewkt//以下方式不用导入net.postgis包,ewkb太长会超出sql限制,以下转换为ewktPGobject pGobject = new PGobject();pGobject.setType("geometry");String pre="SRID="+4326+";";pGobject.setValue(pre+GisUtil.Geometry2WKT(geometry));ps.setObject(i,pGobject);}/*** 取出数据转换,WKB->Geojson* @param rs* @param columnName* @return* @throws SQLException*/@Overridepublic String getResult(ResultSet rs, String columnName) throws SQLException {String WKB = rs.getString(columnName);if(WKB==null){return null;}WKBReader reader = new WKBReader( );Geometry geometry = null;try {geometry = reader.read(WKBReader.hexToBytes(WKB));} catch (ParseException e) {//转换失败return null;}//转换成4326try {int srid = geometry.getSRID();if(srid==0)srid=4549;//默认4549int targetSrid=4326;//默认4326Environment environment = SpringContextUtil.getBean(Environment.class);if(environment!=null){String sridTarget = environment.getProperty("sridTarget");if(sridTarget!=null){try {targetSrid=Integer.valueOf(sridTarget);} catch (Exception e){//转换失败}}}CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:"+srid,true);CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:"+targetSrid,true);MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS,true);geometry = JTS.transform(geometry, transform);} catch (Exception e) {e.printStackTrace();}// 设置保留6位小数,否则GeometryJSON默认保留4位小数GeometryJSON geometryJson = new GeometryJSON(7);String json = geometryJson.toString(geometry);JSONObject jsonObject = JSONObject.parseObject(json);jsonObject.put("srid",geometry.getSRID());return jsonObject.toJSONString();}@Overridepublic String getResult(ResultSet rs, int columnIndex) throws SQLException {return null;}@Overridepublic String getResult(CallableStatement cs, int columnIndex) throws SQLException {return null;}}
package com.zjzy.util;import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.WKBReader;
import org.geotools.referencing.CRS;
import org.geotools.referencing.GeodeticCalculator;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.*;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;import java.io.IOException;/*** @Author yaoct* @Date 2022/9/16 10:55* @Version 1.0* @description*/
public class GisUtil {/*** WKB字符串转Geometry格式* @param WKB* @return*/public static Geometry WKB2Geometry(String WKB){WKBReader reader = new WKBReader();Geometry geometry = null;try {geometry = reader.read(WKBReader.hexToBytes(WKB));} catch (ParseException e) {//转换失败throw new RuntimeException("转换失败",e);}return geometry;}/*** Geometry格式转WKB字符串* @param geometry* @return*/public static String Geometry2WKB(Geometry geometry){WKBWriter wkbWriter = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN,true);byte[] write = wkbWriter.write(geometry);String ret = WKBWriter.toHex(write);return ret;}/*** WKT字符串转Geometry格式* @param WKT* @return*/public static Geometry WKT2Geometry(String WKT){WKTReader reader = new WKTReader();Geometry geometry = null;try {geometry = reader.read(WKT);} catch (ParseException e) {//转换失败throw new RuntimeException("转换失败",e);}return geometry;}/*** Geometry格式转WKT字符串* @param geometry* @return*/public static String Geometry2WKT(Geometry geometry){WKTWriter wktWriter = new WKTWriter();String wkt= wktWriter.write(geometry);return wkt;}/*** 转换Geometry坐标* @param geometry* @param targetSrid 新坐标* @return*/public static Geometry coordinateTransfer(Geometry geometry, int targetSrid){int originSrid = geometry.getSRID();CoordinateReferenceSystem sourceCRS = null;CoordinateReferenceSystem targetCRS = null;MathTransform transform=null;try {sourceCRS = CRS.decode("EPSG:"+originSrid,true);targetCRS = CRS.decode("EPSG:"+targetSrid,true);transform = CRS.findMathTransform(sourceCRS, targetCRS,true);} catch (FactoryException e) {throw new RuntimeException("坐标错误",e);}Geometry ret = null;try {ret = JTS.transform(geometry, transform);} catch (TransformException e) {throw new RuntimeException("坐标转换错误",e);}return ret;}/*** Geometry->geoJson* @param geometry* @return*/public static String geometry2GeoJson(Geometry geometry){// 设置保留6位小数,否则GeometryJSON默认保留4位小数GeometryJSON geometryJson = new GeometryJSON(7);String json = geometryJson.toString(geometry);
//        JSONObject jsonObject = JSONObject.parseObject(json);
//        jsonObject.put("srid",geometry.getSRID());
//        return jsonObject.toJSONString();return json;}/*** geoJson->Geometry* @param geoJson* @return*/public static Geometry geoJson2Geometry(String geoJson){GeometryJSON geometryJson = new GeometryJSON(7);Geometry ret=null;try {Geometry read = geometryJson.read(geoJson);} catch (IOException e) {throw new RuntimeException("转换失败",e);}return ret;}/*** 计算两点间的距离* @param lon1* @param lat1* @param lon2* @param lat2* @return*/public static double calculateDistance(double lon1,double lat1,double lon2,double lat2){//CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:"+srid,true);GeodeticCalculator geodeticCalculator = new GeodeticCalculator(DefaultGeographicCRS.WGS84);// 起点经纬度geodeticCalculator.setStartingGeographicPoint(lon1,lat1);// 末点经纬度geodeticCalculator.setDestinationGeographicPoint(lon2,lat2);// 计算距离,单位:米double distance = geodeticCalculator.getOrthodromicDistance();return distance;}
}

===================================================================

参考:

Mybatis-plus读取和保存Postgis geometry数据 - 简书

MyBatis Plus 自动类型转换之TypeHandler - 周世元ISO8859-1 - 博客园

GeoTools The Open Source Java GIS Toolkit — GeoTools

Geotools中Geometry对象与GeoJson的相互转换_mathyrs的博客-CSDN博客_geojson转geometry

mybatis 自定义TypeHandler映射Geometry空间几何数据 PGPoint (java +mybatis+ pgsql) - 灰信网(软件开发博客聚合)

Mybatis常用注解

mybatis类型转换器处理PostGis数据库geometry类型转换相关推荐

  1. Mybatis类型转换器使用

    1.mybatis类型转换器,就是Java类型与数据库的类型之间转换的一个中介,由这个转换器可以对类型进行映射,mybatis对于基础类型都有默认类型转换器,你可以自定义类型转换器替代默认的转换器,大 ...

  2. 通过mybatis自定义参数类型转换器,进行数据库字段加密脱敏

    1 问题背景 在数据库存储人员的信息时,有一些信息是敏感数据,如身份证号.出生地等.为了防止信息泄漏,这些信息不允许直接在数据库中查看,此时就需要对这些字段进行加密存储,但在页面查看的仍旧是解密后的数 ...

  3. mysql mybatis类型对应_Mybatis与数据库的类型对应

    Mybatis与数据库的类型对应 由于业务的改变,在首次存入数据库时某些int属性并没有赋值,于是默认值就开始污染数据库了. java实体属性对应mysql和SQL Server 和Oracle 数据 ...

  4. spring 类型转换器_Spring中的类型转换

    spring 类型转换器 以下是一些需要类型转换的简单情况: 情况1. 为了帮助简化bean配置,Spring支持属性值与文本值之间的转换. 每个属性编辑器仅设计用于某些类型的属性. 为了使用它们,我 ...

  5. Spring MVC Converter(类型转换器)详解

    Spring MVC 框架的 Converter<S,T> 是一个可以将一种数据类型转换成另一种数据类型的接口,这里 S 表示源类型,T 表示目标类型.开发者在实际应用中使用框架内置的类型 ...

  6. SpringMVC-应用(数据绑定-自定义类型转换器,数据的格式化,数据校验)

    一.提出问题 SpringMVC封装自定义类型对象的时候,JavaBean要和页面提交的数据一一绑定.下面要知道: 1)页面提交的数据都是字符串 2)JavaBean中的属性如:Integer age ...

  7. mybatis 自定义转换规则_Mybatis使用小技巧-自定义类型转换器

    一般情况下,mybatis自带的类型转换器已经足够用了,但是需求永无止境,自定义类型转换器还是学一下吧,指不定哪天会用上. 举个没啥用的示例 javabean如下: public class User ...

  8. Mybatis中的类型转换器

    无论是mybati是向数据库中存储数据还是将数据读取出来都需要涉及类型转换器. Mybatis再带的类型转换器:[部分] 自定义类型处理器 自定义类型转换器的解决方案: 重写已经有的类型转换器. 新建 ...

  9. 玩转Mybatis中的类型转换器TypeHandler

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 抛开使用场景谈技术都是耍流氓 1. 场景 日常java开发中经常有这种需求,用0或者1这些代 ...

最新文章

  1. Jvm面试题及答案 100道(持续更新)
  2. cac会议投稿难度大吗_注册化工师考试难度大吗?
  3. UVA 1151 Buy or Build MST(最小生成树)
  4. 深度学习总结:GAN,原理,算法描述,pytoch实现
  5. vue 创建项目的命令
  6. 实例15:python
  7. package.json和bower的参数解释
  8. 【数据结构与算法基础】队列、栈、递归
  9. transact-sql_如何使用Transact-SQL创建,配置和删除SQL Server链接服务器
  10. 搞不明白为什么大家都在学习 k8s
  11. java相关的国际化步骤_Java语言资源国际化步骤
  12. 文件浏览器及数码相框 -2.3.2-freetype_arm-1
  13. java mavenpom_java-使用pom-packaging Maven项目作为依赖项
  14. ThinkSNS电商系统,带你玩转社群经济
  15. BZOJ 1208 HNOI 2004 宠物收养所 splay
  16. 【FPGA】DS18B20温度显示
  17. 2022阿里巴巴全球数学竞赛 第4题 虎虎生威(盲盒问题、集卡问题)解决思路
  18. 华为官方模拟器eNSP_B500高速网盘下载——带CE系统
  19. Python语言程序设计基础 第二版(嵩天著)课后答案第四章
  20. BNUZ程协技术部2020寒假任务简单版(后端)

热门文章

  1. ubuntu安装过程中提示: the path is not vaild path to the gcc binary等gcc路径不对和kernel不存在?
  2. Learning to Track at 100 FPS with Deep Regression Networks全文翻译
  3. 键盘按键名称及HID扫描码及VK虚拟键码对照表
  4. 计算机组装与系统安装实验目的,计算机原理与系统组装实验
  5. oracle数据删了怎么恢复吗,oracle误删数据恢复方法总结
  6. 4G LTE浪潮何时席卷全球?
  7. 阿里云推高校YY计划助推大学生创业潮
  8. 3年开发了5个私人项目:自动化办公、网站、机器人、小程序...免费开源,拿走不谢~
  9. 20170105资金净流入排行榜
  10. Mac下浏览器超实用快捷键