四种后端语言的数据库操作的代码风格横向比对与建议

导览

      • 前言
      • JAVA
      • PHP
      • node.js
          • mysql
          • mongoDB
      • Swift
      • 总结

前言

数据库的增删该查在后端开发中几乎是肯定碰到的,对于后端来说很大一部分数据处理消息交互都会用到数据库的连接与消息交换,不同语言框架也提供了不同的代码风格和设计模式,下面通过对swift、java、nodejs、PHP四种语言连接mysql的方式来对代码风格进行横向对比,为广大开发者选择后端项目提供一个参考。

JAVA

首先下载JDBC的最新jar包:JDBC,下载对应的版本(注意区分5版本和8版本)
下载完成后导入到你的库中,Java中加载的方式如下

Class.forName("com.mysql.cj.jdbc.Driver"); // 5版本需要去掉.cj
conn = DriverManager
	.getConnection("jdbc:mysql://localhost:3306/test_demo?
	useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC","root","password");

插入数据

INSERT INTO `websites` VALUES 
	('1', 'AAA', 'https://www.AAA.cm/', '1', 'USA'), 
	('2', 'BBB', 'https://www.BBB.com/', '13', 'CN'), 
	('3', 'CCC', 'http://www.CCC.com', '5892', ''), 
	('4', 'DDD', 'http://DDD.com/', '20', 'CN'), 
	('5', 'EEE', 'https://www.EEE.com/', '3', 'USA');

增删改(传入SQL方式)

public int executeUpdate(String sql ,Object []ob){
	conn=getconn();
	PreparedStatement ps=null;
	try {
		ps=prepareStatement(conn,sql,ob);
		int i=ps.executeUpdate();
		return i;	
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		//	e.printStackTrace();
		return 0;
	}finally{			
		closeAll(conn, ps, null);
	}
}

查询(传入SQL方式)

protected PreparedStatement prepareStatement(Connection conn,String sql,Object []ob){		
	PreparedStatement ps=null;
	try {
		int index=1;
		ps = conn.prepareStatement(sql);
		if(ps!=null&&ob!=null){
			for (int i = 0; i < ob.length; i++) {			
				ps.setObject(index, ob[i]);	
				index++; 
			}
		}
	} catch (SQLException e1) {
		e1.printStackTrace();
	}
	return ps;
}

我们可以看到JDBC对于数据库操作进行了很好的封装,我们只需要做好对应的异常捕获与SQL语句,我们可以用不多的代码来完成从Java底层进行的数据库访问,如果配合GSON或fastjson或其他可解析字符串元组数据结构,配合servlet的方式对于做数据处理要求不大的、Ajax的轻量数据交互的业务场景。相对大一点的业务场景JDBC也是能屈能伸,动态调整。

对于相对大型项目在SSM中mybatis也有着不错的表现,通过配置核心文件SqlMapConfig.xml,可以完成高度的解耦能力,通过工厂模式完成对数据库的操控,可以有效提高内存与交互安全性,线程池也让高并发的业务场景得到了实现的可能,相对需要一些学习成本,但对于熟悉spring生态的同学来说,是一个很好很顺手的选择。

对于代码风格来说,Java开发本身具有很好的封装性,对于各种类通信之间可以让逻辑非常清晰,每一个类、每一个方法,都可以很规范的处在相应的层级,对于排查文件系统树和细节是,可以很方便的定位,加上成熟的框架也帮助了程序员可以对于类之间实现更好的低耦合,但是Java严格的封装特性会显得在开发DAO时,代码量巨大的情况,可能会给人带来压力感,喜欢规整清晰、享受代码舒适感的同学可以使用Java作为选择。

PHP

PHP作为一个很成熟的语言,可以直接使用mysqli包,建议使用xampp等虚拟集成软件来跑PHP。

下面开始连接mysqli


$servername = "localhost";
$username = "username";
$password = "password";
 
// 创建连接
$conn = new mysqli($servername, $username, $password);
 
// 检测连接
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
} 
echo "连接成功";
?>

关闭连接

$conn->close();

插入数据


$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
 
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检测连接
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
} 
 
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', '[email protected]')";
 
if ($conn->query($sql) === TRUE) {
    echo "新记录插入成功";
} else {
    echo "Error: " . $sql . "
"
. $conn->error; } $conn->close(); ?>

读取数据


$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
 
// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("连接失败: " . $conn->connect_error);
} 
 
$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $conn->query($sql);
 
if ($result->num_rows > 0) {
    // 输出数据
    while($row = $result->fetch_assoc()) {
        echo "id: " . $row["id"]. " - Name: " . $row["firstname"]. " " . $row["lastname"]. "
"
; } } else { echo "0 结果"; } $conn->close(); ?>

修改数据


$con=mysqli_connect("localhost","username","password","database");
// 检测连接
if (mysqli_connect_errno())
{
    echo "连接失败: " . mysqli_connect_error();
}

mysqli_query($con,"UPDATE Persons SET Age=36
WHERE FirstName='Peter' AND LastName='Griffin'");

mysqli_close($con);
?>

从示例代码中看起来好像代码量比Java的要多得多,这也是PHP文件的很大的碎片化问题之一,不过仔细观察就可以发现增删改查中有大量的重复代码段,可以说是几乎一样的,这就可以使用require函数把一样的重复的代码封装在一个php文件或一个函数里,用的时候调用即可。实际上,在开发中可以很直接的体验到PHP代码的轻便性,对于小型的应用场景可以非常灵活,几乎无耦合的特点也让PHP可以面向碎片业务开发-有什么需求写什么交互,配上Ajax所小消息交互非常的方便。缺点也是显而易见的,就是每个PHP文件各管各,每个PHP包各管各,导致了及其严重的碎片化。与Java的jar包war包不同,PHP的碎片化还容易导致一不小心的注入漏洞,引发很大的安全性问题,依赖包的碎片化还导致了开发的项目不容易迁移问题、包加载失败问题。因此PHP非常适合跑在xampp、docker等容器中并且应付非常小的或简单消息广播的小型业务场景。

node.js

mysql

连接数据库

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'root',
  password : '123456',
  database : 'test'
});
 
connection.connect();
 
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

查询数据

var mysql  = require('mysql');  
 
var connection = mysql.createConnection({     
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
 
connection.connect();
 
var  sql = 'SELECT * FROM websites';
//查
connection.query(sql,function (err, result) {
        if(err){
          console.log('[SELECT ERROR] - ',err.message);
          return;
        }
 
       console.log('--------------------------SELECT----------------------------');
       console.log(result);
       console.log('------------------------------------------------------------\n\n');  
});
 
connection.end();

插入数据

var mysql  = require('mysql');  
 
var connection = mysql.createConnection({     
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
 
connection.connect();
 
var  addSql = 'INSERT INTO websites(Id,name,url,alexa,country) VALUES(0,?,?,?,?)';
var  addSqlParams = ['AAA', 'https://c.AAA.com','23453', 'CN'];
//增
connection.query(addSql,addSqlParams,function (err, result) {
        if(err){
         console.log('[INSERT ERROR] - ',err.message);
         return;
        }        
 
       console.log('--------------------------INSERT----------------------------');
       //console.log('INSERT ID:',result.insertId);        
       console.log('INSERT ID:',result);        
       console.log('-----------------------------------------------------------------\n\n');  
});
 
connection.end();

修改数据

var mysql  = require('mysql');  
 
var connection = mysql.createConnection({     
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
 
connection.connect();
 
var modSql = 'UPDATE websites SET name = ?,url = ? WHERE Id = ?';
var modSqlParams = ['BBB', 'https://m.BBB.com',6];
//改
connection.query(modSql,modSqlParams,function (err, result) {
   if(err){
         console.log('[UPDATE ERROR] - ',err.message);
         return;
   }        
  console.log('--------------------------UPDATE----------------------------');
  console.log('UPDATE affectedRows',result.affectedRows);
  console.log('-----------------------------------------------------------------\n\n');
});
 
connection.end();

删除数据

var mysql  = require('mysql');  
 
var connection = mysql.createConnection({     
  host     : 'localhost',       
  user     : 'root',              
  password : '123456',       
  port: '3306',                   
  database: 'test' 
}); 
 
connection.connect();
 
var delSql = 'DELETE FROM websites where id=6';
//删
connection.query(delSql,function (err, result) {
        if(err){
          console.log('[DELETE ERROR] - ',err.message);
          return;
        }        
 
       console.log('--------------------------DELETE----------------------------');
       console.log('DELETE affectedRows',result.affectedRows);
       console.log('-----------------------------------------------------------------\n\n');  
});
 
connection.end();
mongoDB

连接数据库

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/AAA";
 
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
  if (err) throw err;
  console.log("数据库已创建!");
  db.close();
});

插入数据

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
 
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
    if (err) throw err;
    var dbo = db.db("AAA");
    var myobj = { name: "AAA", url: "www.AAA" };
    dbo.collection("site").insertOne(myobj, function(err, res) {
        if (err) throw err;
        console.log("文档插入成功");
        db.close();
    });
});

读取数据

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
 
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
    if (err) throw err;
    var dbo = db.db("AAA");
    dbo.collection("site"). find({}).toArray(function(err, result) { // 返回集合中所有数据
        if (err) throw err;
        console.log(result);
        db.close();
    });
});

修改数据

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
 
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
    if (err) throw err;
    var dbo = db.db("AAA");
    var whereStr = {"name":'AAA'};  // 查询条件
    var updateStr = {$set: { "url" : "https://www.AAA.com" }};
    dbo.collection("site").updateOne(whereStr, updateStr, function(err, res) {
        if (err) throw err;
        console.log("文档更新成功");
        db.close();
    });
});

删除数据

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
 
MongoClient.connect(url, { useNewUrlParser: true }, function(err, db) {
    if (err) throw err;
    var dbo = db.db("AAA");
    var whereStr = {"name":'BBB'};  // 查询条件
    dbo.collection("site").deleteOne(whereStr, function(err, obj) {
        if (err) throw err;
        console.log("文档删除成功");
        db.close();
    });
});

看起来好像代码量更加的多,同样的nodejs的文件和php很相似,碎片化但已于调整,它使用了近几年优化的很成熟的V8引擎、对前端开发者非常友好的语言-JavaScript,让前端全栈成为可能,借助于V8引擎,js可以非常方便的跑在服务端上,用统一的语言、原生的json支持、ES6+先进的代码思想,完美支持后端的应用逻辑,对于js编写的MongoDB来说更是做到了原生集成,在新时代的nosql逐渐成为主流情况下,node.js是一个非常值得应用于新项目的后端语言平台,当然新事物也会有一些风险,不建议应用在稳定性、数据严格性较高的应用场景。

Swift

安装swift包

# mkdir swift_mysql
# swift package init --type executable

Package.swift

import PackageDescription

let package = Package(
    name: "swift_mysql",
    dependencies:[
      .Package(url:"https://github.com/vapor/mysql", majorVersion:1)
    ]
)

连接数据库

import Glibc
import MySQL

var mysql:Database
do {
  mysql = try Database(host:"localhost",
                       user:"swift",
                       password:"swiftpass",
                       database:"swift_test")
  try mysql.execute("SELECT @@version")
} catch {
  print("Unable to connect to MySQL:  \(error)")
  exit(-1)
}

插入数据

let stmt = "INSERT INTO samples (created_at, location, sample) VALUES ('\(created_at)', POINT\(point), '\(sampleJSON)')"
try mysql.execute(stmt)

查询数据

// ... 查询
  let results = try mysql.execute("SELECT created_at,sample FROM samples where JSON_EXTRACT(sample, '$.speed') > 80") 
  for result in results {
    if let sample      = result["sample"]?.object,
       let speed       = sample["speed"]?.int,
       let temperature = sample["temperature"]?.int,
       let created_at  = result["created_at"]?.string {
      print("Time:\(created_at)\tSpeed:\(speed)\tTemperature:\(temperature)")
    }
  }

不难发现,swift的代码非常的精简方便,语言风格又是集各种现代语言的大成,经过5个版本的迭代已经发布了稳定版本,安全性也是有目共睹的,现在swift还支持了Linux,性能方面底层又是与C语言一致甚至更强的效能,swift直接代表着未来,国外的讨论也非常的活跃,我希望国内站在时代浪尖的同学们可以一起,让这种现代化的语言能够在国内更加活跃和流行。

总结

代码结构上:Java > Swift > node.js > PHP
性能上:Swift > Java > node.js > PHP
简洁方便程度:PHP > Swift > node.js > Java
上手难度:node.js > PHP > Swift > Java

面向过去:PHP
面向现在:Java
面向未来:Swift、node.js

END

你可能感兴趣的:(学习与发文测试)