【技术应用】java基于UNIX域套接字unix domain socket连接postgresql数据库
- 一、前言
- 二、postgresql套接字文件
- 三、PostgreSQL 配置文件pg_hba.conf
- 四、准备工作
- 五、jdbc基于UDS连接postgresql数据库
- 六、springboot+mybatis基于UDS使用示例
一、前言
之前分享了java
基于unix domain socket
实现mysql
的jdbc连接,由于平时使用postgresql数据库
比较多,今天总结一下java基于unix domain socket
实现postgresql数据库的jdbc连接
和mybatis
的使用;
二、postgresql套接字文件
postgresql数据库
的套接字文件是.s.PGSQL.nnnn
,其中nnnn
是服务器的端口号
,如下图:
通过unix套接字
实现连接服务端:
关于postgresql套接字文件连接介绍几个概念:
unix_socket_directories (string)
- 指定服务器用于监听来自客户端应用的连接的
Unix 域套接字
目录。通过列出用逗号分隔的多个目录可以建立多个套接字。项之间的空白被忽略,如果你需要在名字中包括空白或逗号,在目录名周围放上双引号。一个空值指定在任何
Unix 域套接字上都不监听,在这种情况中只能使用TCP/IP 套接字
来连接到服务器。默认值通常是/tmp
,但是在编译时可以被改变。这个参数只能在服务器启动时设置。
这个值通过修改postgresql.conf
文件修改失败,只有通过alter system setunix_socket_directories='/opt/pg12'
;命令修改才生效,不知道是我改的不对还是就应该这样设置。 - 除了套接字文件本身(名为
.s.PGSQL.nnnn
,其中nnnn
是服务器的端口号),一个名
为.s.PGSQL.nnnn.lock的普通文件会在每一个unix_socket_directories
目录中被创建。任何一个都不应该被手工移除。 -
Windows
下没有Unix 域套接字
,因此这个参数与 Windows 无关
unix_socket_group (string)
- 设置 Unix域套接字的所属组(套接字的所属用户总是启动服务器的用户)。可以与选项
unix_socket_permissions
一起用于对Unix域连接进行访问控制。默认是一个空字符串,表示服务器用户的默认组。这个参数只能在服务器启动时设置。
unix_socket_permissions (integer)
- 设置
Unix 域套接字
的访问权限。Unix 域套接字使用普通的 Unix
文件系统权限集。这个参数值应该是数字的形式,也就是系统调用chmod
和umask
接受的
形式(如果使用自定义的八进制格式,数字必须以一个0(零)开头)。 - 默认的权限是0777,意思是任何人都可以连接。合理的候选是0770(只有用户和同组的人可以访问,
又见unix_socket_group
)和0700(只有用户自己可以访问)(请注意,对于 Unix
域套接字,只有写权限有麻烦,因此没有对读取和执行权限的设置和收回)。 - 依然只能使用
alter system set unix_socket_permissions = '0700'
;修改才生效;
三、PostgreSQL 配置文件pg_hba.conf
文件路径:/usr/data/postgresql/pg_hba.conf
属性说明:
1、TYPE
定义了多种连接PostgreSQL的方式,一般分为:
-
local
使用本地unix套接字 -
host
使用TCP/IP连接(包括SSL和非SSL),host结合IPv4地址/结合IPv6地址 -
hostssl
只能使用SSL TCP/IP连接 -
hostnossl
不能使用SSL TCP/IP连接
2、METHOD
为身份验证模式一般分为:ident、trust、md5、password、peer、reject。其中ident和peer模式仅适用于Linux
、Unix
和Max
,不适用于Windows。
-
trust
:该模式可以不用密码直接连接数据库,不安全 -
md5
:该模式很常用,要求连接发起者携带用md5算法加密的密码 -
password
:该模式是使用明文密码进行身份验证,也不安全,不推荐 -
ident
:该模式下系统会将请求发起者的操作系统用户映射为PostgesSQL数据库内部用户,并以该内部用户的权限登录,且此时无需提供登录密码。操作系统用户与数据库内部用户之间的映射关系会记录在pg_ident.conf文件中。 -
peer
:该模式使用连接发起端的操作系统名进行身份验证。仅限于Linux、BSD、Mac OS
X和Solaris,并且仅可用于本地服务器发起的连接。 -
reject
:该模式表示拒绝所有请求。
四、准备工作
1、设置pom.xml文件
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<!--MyBatis整合SpringBoot框架的起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、创建数据库表
DROP TABLE IF EXISTS "public"."student";
CREATE TABLE "public"."student" (
"id" int4 NOT NULL,
"name" varchar(255) COLLATE "pg_catalog"."default",
"sex" varchar(255) COLLATE "pg_catalog"."default",
"pwd" varchar(255) COLLATE "pg_catalog"."default",
"email" varchar(255) COLLATE "pg_catalog"."default"
)
;
-- ----------------------------
-- Primary Key structure for table student
-- ----------------------------
ALTER TABLE "public"."student" ADD CONSTRAINT "student_pkey" PRIMARY KEY ("id");
五、jdbc基于UDS连接postgresql数据库
**1、jdbc操作类MysqlDemo **
package com.sk.jdbc;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class MysqlDemo {
public static Connection getConn02() throws Exception{
//加载驱动
Class.forName("org.postgresql.Driver");
String url="jdbc:postgresql://localhost/test";
String user="postgres";
String password="xxxxxx";//写自己之前设置的
//建立连接
Properties info = new Properties();
info.setProperty("socketFactory","org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg");
info.setProperty("user",user);
info.setProperty("password",password);
info.setProperty("socketFactoryArg","/run/postgresql/.s.PGSQL.5432");
info.setProperty("sslMode","prefer");
Connection conn= DriverManager.getConnection(url,info);
return conn;
}
public static List<String> run() throws Exception{
Connection conn = getConn02();
Statement stmt = conn.createStatement();
String sql = "select * from student";
ResultSet rs = stmt.executeQuery(sql);
//处理结果集
List<String> res = new ArrayList<>();
while(rs.next()) {
String str = rs.getString("name");
res.add(str);
}
rs.close();
System.out.println("结果集关闭成功!");
stmt.close();
System.out.println("语句通道关闭成功!");
conn.close();
System.out.println("关闭连接成功!");
//遍历输出
if(res!=null){
for(String out:res) {
System.out.println(out);
}
}
return res;
}
}
2、业务类
package com.controller;
import com.bean.Student;
import com.mapper.StudentMapper;
import com.sk.jdbc.MysqlDemo;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.List;
@Log4j2
@RestController
public class TestAction {
@Resource
private StudentMapper studentMapper;
/**
* 验证jdbc调用
* @return
*/
@GetMapping("/test/local")
private Object get(){
try {
return MysqlDemo.run();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
请求结果:
六、springboot+mybatis基于UDS使用示例
1、自定义MyDataSource类
package com.config;
import com.sk.jdbc.MysqlDemo;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
public class MyDataSource implements DataSource {
@Override
public Connection getConnection() {
try {
return MysqlDemo.getConn02();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Connection getConnection(String username, String password) {
try {
return MysqlDemo.getConn02();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
2、DruidConfig类
package com.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class DruidConfig {
@Bean
public DataSource druid(){
return new MyDataSource();
}
}
3、dao层StudentMapper
package com.mapper;
import com.bean.Student;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Mapper
@Repository
public interface StudentMapper {
@Select("select * from student")
List<Student> selectAll();
@Select("select * from student where id = #{id}")
Student selectById(@Param("id") int id);
@Select("select * from student where name = #{name}")
Map<String, Object> selectByName1(@Param("name") String name);
@Select("select * from student where name = #{name}")
Student selectByName2(@Param("name") String name);
@Select("select * from student where name = #{name} and pwd = #{pwd}")
Student selectByNameAndPwd(String name, String pwd);
@Delete("delete from student where id = #{id}")
boolean deleteById(int id);
@Insert("insert into student values (null,#{name},#{sex},#{pwd},#{email})")
boolean insertUser(String name, String sex, String pwd, String email);
@Update("update student set name = #{name} where id = #{id}")
boolean updateById(String name, int id);
}
4、业务类
package com.controller;
import com.bean.Student;
import com.mapper.StudentMapper;
import com.sk.jdbc.MysqlDemo;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.List;
@Log4j2
@RestController
public class TestAction {
@Resource
private StudentMapper studentMapper;
/**
* 验证
* @return
*/
@GetMapping("/test")
private Object get2(){
List<Student> studentList = studentMapper.selectAll();
log.info(studentList);
return studentList;
}
}
5、bean类Student
package com.bean;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Student {
private Integer id;
private String name;
private String sex;
private String pwd;
private String email;
public Student() { }
public Student(Integer id, String name, String sex, String pwd, String email) {
this.id = id;
this.name = name;
this.sex = sex;
this.pwd = pwd;
this.email = email;
}
}
请求结果: