初次尝试使用Java来写Web API,选用了一些经典的Java框架。为满足定位服务相关功能,数据库上依然使用PostgreSQL+PostGIS这一经典组合。在配置PostGIS的JDBC驱动和ORM时遇到了一些坑,特此记录。
基础项目
首先搭建SpringBoot+Mybatis Plus+PostgreSQL项目,在服务器上建好相关数据库和Role,这一步教程充足,过程顺利,此处略过不提。
我使用application.properties文件配置参数,数据库配置大概如下:
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://域名:端口/数据库
spring.datasource.username=数据库Role
spring.datasource.password=密码
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:db/schema.sql
spring.sql.init.data-locations=classpath:db/data.sql
mybatis-plus.global-config.db-config.schema=public
注意,mybatis-plus.global-config.db-config.schema=public非常重要,某些特殊名称的表,如user,只有在加了这句话之后ORM才能正确运行。
schema.sql和data.sql与mybatis-plus官方示例类似,需要放在resources/db下面,内容如下所示:
DROP TABLE IF EXISTS "user";
CREATE TABLE "user"
(
id SERIAL4 PRIMARY KEY,
name VARCHAR NULL DEFAULT NULL,
age INT4 NULL DEFAULT NULL,
email VARCHAR NULL DEFAULT NULL
);
DELETE FROM "user";
INSERT INTO "user" (id, name, age, email)
VALUES (1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');
测试使用的User类如下:
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
}
UserMapper类如下:
import centerc.music.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface UserMapper extends BaseMapper<User> {
}
测试代码如下:
@Autowired
private UserMapper userMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userMapper.selectList(null);
Assert.isTrue(5 == userList.size(), "");
userList.forEach(System.out::println);
}
通过测试则说明已经成功连接到数据库,角色权限和ORM配置都正确,下面开始配置PostGIS扩展功能。
数据库配置
首先在服务器安装PostGIS。以Ubuntu 22.04为例,运行以下命令:
sudo apt install postgis
安装成功后,以具有superuser权限的Role登录PostgreSQL,使用\c database 命令使用数据库,并执行以下语句启用扩展:
CREATE EXTENSION postgis;
扩展会自动在数据库下建立spatial_ref_sys表。至此数据库端配置完成。
Java配置
Java端配置PostGIS的教程比较少,而且普遍过时。经过一下午的探索与尝试,发现postgis-java值得一试。
首先,需要下载该库最新的release代码并使用mvn package命令构建Jar包。构建过程中遇到git-commit-id-plugin插件报错。修改postgis-java/pom.xml,将
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>${git-commit-id-plugin.version}</version>
...
</plugin>
改为
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>${git-commit-id-plugin.version}</version>
<configuration>
<failOnNoGitDirectory>false</failOnNoGitDirectory>
</configuration>
...
</plugin>
即可。
点击此处下载构建好的Jar包(2024.1.0版本)和一会儿会用到的TypeHandler文件。
将构建好的四个Jar包放在resources/lib下,修改我们项目的pom.xml,添加如下本地依赖:
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2024.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/postgis-jdbc-2024.1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-geometry</artifactId>
<version>2024.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/postgis-geometry-2024.1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc-java2d</artifactId>
<version>2024.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/postgis-jdbc-java2d-2024.1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc-jts</artifactId>
<version>2024.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/postgis-jdbc-jts-2024.1.0.jar</systemPath>
</dependency>
将TypeHandler放在项目路径下,并记好该包的位置。
修改application.properties 中的spring.datasource.driver-class-name和spring.datasource.url,添加mybatis-plus.type-handlers-package,修改后如下所示:
spring.datasource.driver-class-name=net.postgis.jdbc.DriverWrapper
spring.datasource.url=jdbc:postgresql_postGIS://域名:端口/数据库
spring.datasource.username=数据库Role
spring.datasource.password=密码
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:db/schema.sql
# spring.sql.init.data-locations=classpath:db/data.sql 一会儿测试时使用Mybatis Plus填充数据
mybatis-plus.global-config.db-config.schema=public
mybatis-plus.type-handlers-package=xxx.typehandler
测试
接下来,我们删除在最开始建立的user表,修改User类和测试函数以验证配置是否正确。
schema.sql:
DROP TABLE IF EXISTS "user";
CREATE TABLE "user"
(
id SERIAL4 PRIMARY KEY,
name VARCHAR NULL DEFAULT NULL,
age INT4 NULL DEFAULT NULL,
email VARCHAR NULL DEFAULT NULL,
geom GEOMETRY(POINT, 4326) NULL DEFAULT NULL
);
User类:
import lombok.Data;
import net.postgis.jdbc.geometry.Point;
@Data
public class User {
private Integer id;
private String name;
private Integer age;
private String email;
private Point geom;
}
net.postgis.jdbc.geometry.Point会映射到PostGIS中的GEOMETRY(POINT)类型。
测试代码:
@Autowired
private UserMapper userMapper;
@Test
@Transactional
public void testPostGIS() {
System.out.println(("----- testPostgis method test ------"));
User user = new User();
user.setAge(18);
user.setEmail("lhabc@test");
user.setName("test");
user.setGeom(new Point(1, 1));
userMapper.insert(user);
user.setName("LHabc");
userMapper.updateById(user);
List<User> userList = userMapper.selectList(null);
Assert.isTrue(userList.size() == 1, "");
userList.forEach(System.out::println);
userMapper.deleteById(user.getId());
userList = userMapper.selectList(null);
Assert.isTrue(userList.isEmpty(), "");
}
无报错且输出User(id=1674174465, name=LHabc, age=18, [email protected], geom=SRID=4326;POINT(1 1)),说明一切顺利。

Comments NOTHING