Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 三级视频大全,久久爱老牛影视一区二区,九九精品视频在线观看

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          JavaWeb連接MySQL數(shù)據(jù)庫最細(xì)圖解

          JavaWeb連接MySQL數(shù)據(jù)庫最細(xì)圖解

          avaWeb連接MySQL數(shù)據(jù)庫的方式有很多,首先我們講解JDBC的配置方法

          一、JDBC的配置方法

          1、什么是JDBC

          什么是JDBC嘞?JDBC代表Java數(shù)據(jù)庫連接(Java Database Connectivity),它是用于Java編程語言和數(shù)據(jù)庫之間的數(shù)據(jù)庫無關(guān)連接的標(biāo)準(zhǔn)Java API,

          換句話說:JDBC是用于在Java語言編程中與數(shù)據(jù)庫連接的API。

          JDBC庫包括通常與數(shù)據(jù)庫使用相關(guān),如下面提到的每個任務(wù)的API -

          • 連接到數(shù)據(jù)庫
          • 創(chuàng)建SQL或MySQL語句
          • 在數(shù)據(jù)庫中執(zhí)行SQL或MySQL查詢
          • 查看和修改結(jié)果記錄

          從根本上說,JDBC是一個規(guī)范,它提供了一整套接口,允許以一種可移植的訪問底層數(shù)據(jù)庫API。 Java可以用它來編寫不同類型的可執(zhí)行文件,如 -

          • Java應(yīng)用程序
          • Java Applet
          • Java Servlets
          • Java ServerPages(JSP)
          • 企業(yè)級JavaBeans(EJB)

          所有這些不同的可執(zhí)行文件都能夠使用JDBC驅(qū)動程序來訪問數(shù)據(jù)庫,并用于存儲數(shù)據(jù)到數(shù)據(jù)庫中。

          JDBC提供與ODBC相同的功能,允許Java程序包含與數(shù)據(jù)庫無關(guān)的代碼(同樣的代碼,只需要指定使用的數(shù)據(jù)庫類型,不需要重修改數(shù)據(jù)庫查詢或操作代碼)。

          2、下載配置

          (1)首先我們到MySQL的官網(wǎng)去下載支持程序“MySQL Connector/J”(MySQL官方的JDBC驅(qū)動程序)

          這里附上一鍵直達(dá)的鏈接:MySQL :: Download MySQL Connector/J (Archived Versions)

          首先打開MySQL官網(wǎng),點擊DOWNLOADS

          之后我們點擊MySQL Community(GPL) Downloads

          點擊Connector/J

          點擊Archives

          按照圖片進(jìn)行選擇并下載(這里我們不可以選擇上方的那個文件,因為上面那個文件是Liunx、Dabian等系統(tǒng)的文件,下面的文件才是Windows版本的!!!

          至此,我們下載完成。

          (2)接下來我們進(jìn)行文件配置。

          我們將下載的壓縮包進(jìn)行解壓,在生成的文件中會有一個名為mysql-connector-java-8.0.28.jar的文件。

          我們要在需要與MySQL連接的項目中建立一個lib文件夾,并將.jar文件復(fù)制粘貼到此文件夾下(也可以直接進(jìn)行拖拽)

          之后我們用右鍵,按照圖片上的步驟操作,添加驅(qū)動程序路徑(成功后會多出一個

          文件)

          到這里不要著急,下面我們將.jar包導(dǎo)入到你電腦Tomcat文件根目錄下的lib文件夾內(nèi),這樣,你就完成了所有配置!

          (3)接下來我們注冊JDBC驅(qū)動程序

          連接數(shù)據(jù)庫時,需要將數(shù)據(jù)庫驅(qū)動程序注冊到j(luò)dbc的驅(qū)動管理器中。

          調(diào)用Class.forName()方法例如:Class.forName(“com.mysql.jdbc.Driver”);當(dāng)jdbc驅(qū)動程序mysql-connector-java-5.0.5-bin.jar為6.x版本以上時,調(diào)用為Class.forName(“com.mysql.cj.jdbc.Driver”);

          (4)基于數(shù)據(jù)庫連接的URL創(chuàng)建連接

          雖然不同數(shù)據(jù)庫廠商的URL不完全相同,但是都符合一個基本的格式,即“jdbc協(xié)議+IP地址或域名+端口號+數(shù)據(jù)庫名稱”。

          創(chuàng)建數(shù)據(jù)庫連接時,需要使用DriverManager類中g(shù)etConnection()的靜態(tài)方法,方法聲明如下:DriverManager.getConnection(String url,String username,password);

          二、使用JDBC的方法使JavaWeb連接MySQL數(shù)據(jù)庫

          下面我們寫一個JSP代碼,用來驗證是否可以連接MySQL數(shù)據(jù)庫。

          <%@page import="java.sql.DriverManager"%><%@page import="java.sql.DriverAction"%><%@page import="java.sql.Connection"%><%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta http-equiv="Content-Type" content:"text/html" charset="UTF-8"><title>MySQL</title></head><body>	<%	try {		Class.forName("com.mysql.cj.jdbc.Driver"); //顯示聲明將數(shù)據(jù)庫驅(qū)動程序注冊到j(luò)dbc的驅(qū)動管理器中		String url="jdbc:mysql://localhost:3306/text"; //數(shù)據(jù)庫名稱為text(需要提前在MySQL里面建立text數(shù)據(jù)庫)		String username="root"; //數(shù)據(jù)庫用戶名		String password="123456"; //數(shù)據(jù)庫密碼			Connection conn=DriverManager.getConnection(url, username, password); //連接數(shù)據(jù)庫		out.print("數(shù)據(jù)庫連接成功!");		conn.close();	} catch (Exception e) {		out.print("數(shù)據(jù)庫連接失敗!");		out.print("錯誤信息:" + e.toString());	}	%> </body></html>

          PS:這里需要注意的是我們自己使用時一定要修改成自己MySQL的用戶名和密碼,保證可以正常連接數(shù)據(jù)庫。并且我們連接的數(shù)據(jù)庫一定要存在!!!

          三、進(jìn)行實際操作

          1、創(chuàng)建首頁(login.jsp)

          首先需要創(chuàng)建一個新的首頁,首頁可以顯示用戶名,密碼,登錄按鈕等。代碼如下:

          <%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>歡迎登錄</title></head><body>	<div style="text-align: center; margin-top: 120px">		<form action="LoginServet" method="post">			<table style="margin-left: 40%">				<h1>登陸</h1>				<tr>					<td>登錄名:</td>					<td><input name="username" type="text" size="21"></td>				</tr>				<tr>					<td>密碼:</td>					<td><input name="password" type="password" size="21"></td>				</tr>			</table>			<input type="submit" value="登錄">			<input type="reset"value="重置">		</form>		<br>	</div></body></html>

          效果如下:

          2、創(chuàng)建LoginServlet.java文件

          接下來我們創(chuàng)建LoginServlet.java文件。代碼如下:

          package com.sdbi.servlet; import java.io.IOException;  import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;   import com.sdbi.dao.userDao;import com.sdbi.entity.User; @WebServlet("/LoginServet")public class LoginServet extends HttpServlet { 	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		String account=request.getParameter("username");		String passWord=request.getParameter("password");				HttpSession session=request.getSession();		String username=request.getParameter("username");		String password=request.getParameter("password");		userDao userDao=new userDao();					User user=(User)userDao.login(username, password);		if (user !=null) {			session.setAttribute(username, user);			request.getRequestDispatcher("check.jsp").forward(request, response);					}else {			request.getRequestDispatcher("failed.jsp").forward(request, response);		}	} 	protected void doPost(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException { 		doGet(request, response);	} }

          4、創(chuàng)建UserDao.java文件

          代碼如下:

          package com.sdbi.dao; import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;   import com.mysql.cj.protocol.Resultset.Concurrency;import com.sdbi.entity.User; import util.DButil; public class userDao { 	public User login(String username,String password) {		User u=null;		Connection connection=null;		PreparedStatement pstmt=null;		ResultSet resultSet=null;		try {			connection=DButil.getcon();			String sql="select * from user where username=? and password=?";			pstmt=(PreparedStatement) connection.prepareStatement(sql);			pstmt.setString(1, username);			pstmt.setString(2, password);			resultSet=pstmt.executeQuery();			if (resultSet.next()) {				u=new User();				u.setUsername(resultSet.getString("username"));				u.setPassword(resultSet.getString("password"));				System.out.println("登錄成功!");			} else {				System.out.println("用戶名或者密碼錯誤!");			} 		} catch (SQLException e) {			e.printStackTrace(); 		} finally {			//DBUtil.close(pstmt, connection); 		}		return u;	} 	public boolean addUser(User user) {		 Connection connection=null;		 PreparedStatement psmt=null;		 try {			connection=DButil.getcon();			String sql="insert into user(username,password);";			psmt=(PreparedStatement) connection.prepareStatement(sql);			 psmt.setString(1, user.getUsername());			psmt.setString(2,user.getPassword());			psmt.executeUpdate();																			} catch (SQLException e) {			e.printStackTrace();			return false;					}finally {			//DBUtil.close(psmt, connection);		}		 return true;	} }

          5、創(chuàng)建User.java文件

          package com.sdbi.entity; public class User {	private String username;	private String password;	public String getUsername() {		return username;	}	public void setUsername(String username) {		this.username=username;	}	public String getPassword() {		return password;	}	public void setPassword(String password) {		this.password=password;	}				 }

          6、創(chuàng)建check.jsp文件

          <%@page import="java.sql.ResultSet"%><%@page import="java.sql.PreparedStatement"%><%@page import="java.sql.DriverManager"%><%@page import="java.sql.Connection"%><%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>所有用戶信息</title></head><body>	<center>		<h3>所有用戶信息</h3>		<table border="1">			<tr>				<th>賬戶</th>				<th>密碼</th>			</tr>			<%			//加載、注冊數(shù)據(jù)庫驅(qū)動程序			Class.forName("com.mysql.cj.jdbc.Driver"); 			//數(shù)據(jù)庫連接字符串			String url="jdbc:mysql://localhost:3306/text";			//用戶名			String username="root";			//密碼			String password="123456";			//數(shù)據(jù)庫連接			Connection conn=DriverManager.getConnection(url, username, password);			//構(gòu)造sql語句			String sql="select * from user";			//獲取數(shù)據(jù)庫操作對象(PreparedStatement對象)			PreparedStatement pstmt=conn.prepareStatement(sql); 			ResultSet rs=pstmt.executeQuery(); 			//循環(huán)前準(zhǔn)備變量			String uname=null;			String upassword=null;			while (rs.next()) {				uname=rs.getString("username");				upassword=rs.getString("password");			%>			<tr>				<td><%=uname%></td>				<th><%=upassword%></th>			</tr> 			<%			}			//釋放對象			if (pstmt !=null) {			pstmt.close();			}			if (conn !=null) {			pstmt.close();			}			if (rs !=null) {			rs.close();			}			%>			</center>		</table></body></html>

          7、創(chuàng)建failed.jsp文件

          <%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>登陸失敗</title></head><body>	<h1>失敗</h1><br />	<a href="login.jsp">請重新登錄</a></body></html>

          8、創(chuàng)建所需要的數(shù)據(jù)庫連接

          9、登錄用戶


          如果本文對你有幫助,別忘記給我個3連 ,點贊,轉(zhuǎn)發(fā),評論,,咱們下期見。

          收藏 等于白嫖,點贊才是真情。



          原文 https://www.cnblogs.com/soosoo/p/16219491.html

          先說明,由于是8版本的數(shù)據(jù)庫,所以配置類的寫法上與5版本的有所區(qū)別,需要注意,同時用idea或eclipse時需要導(dǎo)入jar包,jar包的下載鏈接:

          https://dev.mysql.com/get/archives/mysql-connector-java-8.0/mysql-connector-java-8.0.28.zip

          如果想要下載8版本不同的jar包只需要修改8.0.28為指定版本即可。

          idea導(dǎo)入jar包的方法如下:

          然后是代碼部分,首先先建表:

          CREATE TABLE `train_message` (
                                           `id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
                                           `train_name` varchar(20) NOT NULL COMMENT '列車名',
                                           `origin` varchar(30) NOT NULL COMMENT '始發(fā)地',
                                           `terminal` varchar(30) NOT NULL COMMENT '終到地',
                                           `departure_time` timestamp NOT NULL COMMENT '出站時間',
                                           `state` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '正常' COMMENT '列車狀態(tài)',
                                           PRIMARY KEY (`id`)
          ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb3

          然后創(chuàng)建連接的配置類DbConfig.java,localhost是本機(jī)的ip地址,如果有服務(wù)器就填服務(wù)器的ip地址,message是數(shù)據(jù)庫的名字,這里一張圖說下有很多新手誤解的名字

          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.SQLException;
          
          /**
           *  數(shù)據(jù)庫配置類
           *  @author 景苒
           */
          public class DbConfig {
              public Connection dbConfig() throws SQLException {
                  try {
                      Class.forName("com.mysql.cj.jdbc.Driver");
                  }catch (Exception e) {
                      System.out.print("加載驅(qū)動失敗!");
                      e.printStackTrace();
                  }
                  String url="jdbc:mysql://localhost:3306/message?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true";
                  String user="root";
                  String password="123456";
                  return DriverManager.getConnection(url, user, password);
              }
          }

          然后寫下主函數(shù)Main.java,這里主函數(shù)的函數(shù)體可以在最后再寫,需要什么功能就把注釋打開就好,快捷注釋的方法,選中這句話,按ctrl加/,就能全注釋了。

          import java.sql.SQLException;
          
          /**
           * 主函數(shù),調(diào)用功能
           * @author 景苒
           */
          public class Main {
              public static void main(String[] args) throws SQLException {
          //        new GetMessage().getMessage();
          //        new UpdateTrainState().updateTrainState();
          //        new InsertTrain().insertTrain();
          //        new GetNumber().getNumber();
              }
          }

          然后是每個的功能:

          1.查詢沈陽到武漢的所有列車信息,按出發(fā)時間先后排序

          建GetMessage.java類

          import java.sql.Connection;
          import java.sql.PreparedStatement;
          import java.sql.ResultSet;
          import java.sql.SQLException;
          
          /**
           * 查詢沈陽到武漢的所有列車信息,按出發(fā)時間先后排序
           * @author 景苒
           */
          public class GetMessage {
              public void getMessage() throws SQLException {
                  Connection con=new DbConfig().dbConfig();
                  String sql="select * from `train_message` where origin=? and terminal=? ORDER BY departure_time ASC";
                  String origin="沈陽";
                  String terminal="武漢";
                  PreparedStatement ps=con.prepareStatement(sql);
                  ps.setString(1, origin);
                  ps.setString(2, terminal);
                  ResultSet rs=ps.executeQuery();
                  try {
                      while (rs.next()) {
                          System.out.println("列車名:" + rs.getString("train_name")
                                  + " 始發(fā)站:" + rs.getString("origin")
                                  + " 終到站:" + rs.getString("terminal")
                                  + " 出發(fā)時間:" + rs.getString("departure_time")
                                  + " 列車狀態(tài):" + rs.getString("state"));
                      }
                  }catch (SQLException e) {
                      e.printStackTrace();
                  }finally {
                      ps.close();
                      con.close();
                  }
              }
          }

          2.修改T2255列車的狀態(tài)為停運(yùn)

          建UpdateTrainState.java類

          import java.sql.Connection;
          import java.sql.SQLException;
          import java.sql.Statement;
          
          /**
           * 修改T2255列車的狀態(tài)為停運(yùn)
           * @author 景苒
           */
          public class UpdateTrainState {
              public void updateTrainState() throws SQLException {
                  Connection con=new DbConfig().dbConfig();
                  String sql="UPDATE `train_message` SET state='停運(yùn)' WHERE train_name='T2255'";
                  Statement statement=con.createStatement();
                  try {
                      int i=statement.executeUpdate(sql);
                      if (i > 0) {
                          System.out.println("更新成功");
                      }else {
                          System.out.println("更新失敗");
                      }
                  }catch (SQLException e) {
                      e.printStackTrace();
                  }finally {
                      statement.close();
                      con.close();
                  }
              }
          }

          3.新增一輛列車信息(自己輸入)

          建InsertTrain.java類

          import java.sql.Connection;
          import java.sql.PreparedStatement;
          import java.sql.SQLException;
          import java.util.Scanner;
          
          /**
           * 新增一輛列車信息(自己輸入)
           * 始發(fā)時間為timestamp類型,輸入時需要確保格式正確,如:2019-01-01 00:00:00
           * @author 景苒
           */
          public class InsertTrain {
              public void insertTrain() throws SQLException {
                  Connection con=new DbConfig().dbConfig();
                  Scanner scanner=new Scanner(System.in);
                  String sql="insert into `train_message` values(null, ?, ?, ?, ?, default)";
                  System.out.print("請輸入列車名:");
                  String trainName=scanner.nextLine();
                  System.out.print("請輸入始發(fā)站:");
                  String origin=scanner.nextLine();
                  System.out.print("請輸入終到站:");
                  String terminal=scanner.nextLine();
                  System.out.print("請輸入始發(fā)時間:");
                  String departureTime=scanner.nextLine();
                  PreparedStatement ps=con.prepareStatement(sql);
                  ps.setString(1, trainName);
                  ps.setString(2, origin);
                  ps.setString(3, terminal);
                  ps.setString(4, departureTime);
                  try {
                      int i=ps.executeUpdate();
                      if (i > 0) {
                          System.out.println("添加成功");
                      }else {
                          System.out.println("添加失敗");
                      }
                  }catch (SQLException e) {
                      e.printStackTrace();
                  }finally {
                      ps.close();
                      con.close();
                  }
              }
          }

          4.查詢狀態(tài)為正常的列車數(shù)量

          建GetNumber.java類

          import java.sql.Statement;
          
          /**
           * 查詢狀態(tài)為正常的列車數(shù)量
           * @author 景苒
           */
          public class GetNumber {
              public void getNumber() throws SQLException {
                  Connection con=new DbConfig().dbConfig();
                  String sql="select count(state) from `train_message` where state='正常'";
                  Statement statement=con.createStatement();
                  try {
                      ResultSet resultSet=statement.executeQuery(sql);
                      while (resultSet.next()) {
                          System.out.println("狀態(tài)為正常的列車數(shù)量為:" + resultSet.getInt(1));
                      }
                  }catch (SQLException e){
                      e.printStackTrace();
                  }finally {
                      statement.close();
                      con.close();
                  }
              }
          }

          最后附上navicat的屬性結(jié)構(gòu)圖和樣例插入的語句

          數(shù)據(jù)根據(jù)自己需求自行寫入幾個就行,以上就是java連接mysql數(shù)據(jù)庫的實例代碼,eclipse也大同小異,就導(dǎo)入jar包的方式不同。

          文章來自https://www.cnblogs.com/jingran/p/16120104.html

          數(shù)據(jù)庫已經(jīng)越來越被人們熟知,同時也在許多企業(yè)中得到了應(yīng)用,但是由于市面上沒有統(tǒng)一的圖查詢語言標(biāo)準(zhǔn),所以有部分開發(fā)者對于不同圖數(shù)據(jù)庫的用法存在著疑問。因此本文作者對市面上主流的幾款圖數(shù)據(jù)庫進(jìn)行了一番分析,并以查詢操作為例進(jìn)行深入介紹。

          文章的開頭我們先來看下什么是圖數(shù)據(jù)庫,根據(jù)維基百科的定義:圖數(shù)據(jù)庫是使用圖結(jié)構(gòu)進(jìn)行語義查詢的數(shù)據(jù)庫,它使用節(jié)點、邊和屬性來表示和存儲數(shù)據(jù)

          雖然和關(guān)系型數(shù)據(jù)庫存儲的結(jié)構(gòu)不同(關(guān)系型數(shù)據(jù)庫為表結(jié)構(gòu),圖數(shù)據(jù)庫為圖結(jié)構(gòu)),但不計各自的性能問題,關(guān)系型數(shù)據(jù)庫可以通過遞歸查詢或者組合其他 SQL 語句(Join)完成圖查詢語言查詢節(jié)點關(guān)系操作。得益于 1987 年 SQL 成為國際標(biāo)準(zhǔn)化組織(ISO)標(biāo)準(zhǔn),關(guān)系型數(shù)據(jù)庫行業(yè)得到了很好的發(fā)展。同 60、70 年代的關(guān)系型數(shù)據(jù)庫類似,圖數(shù)據(jù)庫這個領(lǐng)域的查詢語言目前也沒有統(tǒng)一標(biāo)準(zhǔn),雖然 19 年 9 月經(jīng)過國際 SQL 標(biāo)準(zhǔn)委員會投票表決,決定將圖查詢語言(Graph Query Language)納為一種新的數(shù)據(jù)庫查詢語言,但 GQL 的制定仍需要一段時間。

          鑒于市面上沒有統(tǒng)一的圖查詢語言標(biāo)準(zhǔn),在本文中我們選取市面上主流的幾款圖查詢語言來分析一波用法,由于篇幅原因本文旨在簡單介紹圖查詢語言和常規(guī)用法,更詳細(xì)的內(nèi)容將在進(jìn)階篇中講述。

          圖查詢語言·介紹

          圖查詢語言 Gremlin

          Gremlin 是 Apache ThinkerPop 框架下的圖遍歷語言。Gremlin 可以是的也可以是命令性的。雖然 Gremlin 是基于 Groovy 的,但具有許多語言變體,允許開發(fā)人員以 Java、JavaScript、Python、Scala、Clojure 和 Groovy 等許多現(xiàn)代編程語言原生編寫 Gremlin 查詢

          支持圖數(shù)據(jù)庫:Janus Graph、InfiniteGraph、Cosmos DB、DataStax Enterprise(5.0+) 、Amazon Neptune

          圖查詢語言 Cypher

          Cypher 是一個描述性的圖形查詢語言,允許不必編寫圖形結(jié)構(gòu)的遍歷代碼對圖形存儲有表現(xiàn)力和效率的查詢,和 SQL 很相似,Cypher 語言的關(guān)鍵字不區(qū)分大小寫,但是屬性值,標(biāo)簽,關(guān)系類型和變量是區(qū)分大小寫的。

          支持圖數(shù)據(jù)庫: Neo4j、RedisGraph、AgensGraph

          圖查詢語言 nGQL

          nGQL 是一種類 SQL 的聲明型的文本查詢語言,nGQL 同樣是關(guān)鍵詞大小寫不敏感的查詢語言,目前支持模式匹配、聚合運(yùn)算、圖計算,可無嵌入組合語句。

          支持圖數(shù)據(jù)庫:Nebula Graph

          圖查詢語言·術(shù)語篇

          在比較這 3 個圖查詢語言之前,我們先來看看他們各自的術(shù)語,如果你翻閱他們的文檔會經(jīng)常見到下面這些“關(guān)鍵字”,在這里我們不講用法,只看這些圖數(shù)據(jù)庫常用概念在這 3 個圖數(shù)據(jù)庫文檔中的叫法。

          術(shù)語GremlinCyphernGQL點VertexNodeVertex邊EdgeRelationshipEdge點類型LabelLabelTag邊類型labelRelationshipTypeedge type點 IDvidid(n)vid邊 IDeidid?無插入addcreateinsert刪除dropdeletedelete / drop更新屬性setPropertysetupdate

          我們可以看到大體上對點和邊的叫法類似,只不過 Cypher 中直接使用了 Relationship 關(guān)系一詞代表邊。其他的術(shù)語基本都非常直觀。

          圖查詢語言·實操篇

          上面說了一通術(shù)語之類的“干貨”之后,是時候展示真正的技術(shù)了——來個具體一點的例子,在具體的例子中我們將會分析 Gremlin、Cypher、nGQL 的用法不同。

          示例圖:The Graphs of Gods

          實操示例使用了 Janus Graph 的示例圖 The Graphs of Gods。該圖結(jié)構(gòu)如下圖所示,描述了羅馬萬神話中諸神關(guān)系。

          插入數(shù)據(jù)

          復(fù)制代碼

          # 插入點## nGQLnebula> INSERT VERTEX character(name, age, type) VALUES hash("saturn"):("saturn", 10000, "titan"), hash("jupiter"):("jupiter", 5000, "god");## Gremlingremlin> saturn=g.addV("character").property(T.id, 1).property('name', 'saturn').property('age', 10000).property('type', 'titan').next();==>v[1]gremlin> jupiter=g.addV("character").property(T.id, 2).property('name', 'jupiter').property('age', 5000).property('type', 'god').next();==>v[2]gremlin> prometheus=g.addV("character").property(T.id, 31).property('name',  'prometheus').property('age', 1000).property('type', 'god').next();==>v[31]gremlin> jesus=g.addV("character").property(T.id, 32).property('name',  'jesus').property('age', 5000).property('type', 'god').next();==>v[32]## Cyphercypher> CREATE (src:character {name:"saturn", age: 10000, type:"titan"})cypher> CREATE (dst:character {name:"jupiter", age: 5000, type:"god"})# 插入邊## nGQLnebula> INSERT EDGE father() VALUES hash("jupiter")->hash("saturn"):();## Gremlingremlin> g.addE("father").from(jupiter).to(saturn).property(T.id, 13);==>e[13][2-father->1]## Cyphercypher> CREATE (src)-[rel:father]->(dst)

          在數(shù)據(jù)插入這塊,我們可以看到 nGQL 使用 INSERT VERTEX 插入點,而 Gremlin 直接使用類函數(shù)的 g.addV() 來插入點,Cypher 使用 CREATE 這個 SQL 常見關(guān)鍵詞來創(chuàng)建插入的點。在點對應(yīng)的屬性值方面,nGQL 通過 VALUES 關(guān)鍵詞來賦值,Gremlin 則通過操作 .property() 進(jìn)行對應(yīng)屬性的賦值,Cypher 更直觀直接在對應(yīng)的屬性值后面跟上想對應(yīng)的值。

          在邊插入方面,可以看到和點的使用語法類似,只不過在 Cypher 和 nGQL 中分別使用 -[]-> 和 **-> 來表示關(guān)系,而 Gremlin 則用 to() ** 關(guān)鍵詞來標(biāo)識指向關(guān)系,在使用這 3 種圖查詢語言的圖數(shù)據(jù)庫中的邊均為有向邊,下圖左邊為有向邊,右邊為無向邊。

          刪除數(shù)據(jù)

          復(fù)制代碼

          # nGQLnebula> DELETE VERTEX hash("prometheus");# Gremlingremlin> g.V(prometheus).drop();# Cyphercypher> MATCH (n:character {name:"prometheus"}) DETACH DELETE n 

          這里,我們可以看到大家的刪除關(guān)鍵詞都是類似的:Delete 和 Drop,不過這里需要注意的是上面術(shù)語篇中提過 nGQL 中刪除操作對應(yīng)單詞有 Delete 和 Drop ,在 nGQL 中 Delete 一般用于點邊,Drop 用于 Schema 刪除,這點和 SQL 的設(shè)計思路是一樣的。

          更新數(shù)據(jù)

          復(fù)制代碼

          # nGQLnebula> UPDATE VERTEX hash("jesus") SET character.type='titan';# Gremlingremlin> g.V(jesus).property('age', 6000);==>v[32]# Cyphercypher> MATCH (n:character {name:"jesus"}) SET n.type='titan';

          可以看到 Cypher 和 nGQL 都使用 SET 關(guān)鍵詞來設(shè)置點對應(yīng)的類型值,只不過 nGQL 中多了 UPDATE 關(guān)鍵詞來標(biāo)識操作,Gremlin 的操作和查看點操作類似,只不過增加了變更 property 值操作,這里我們注意到的是,Cypher 中常見的一個關(guān)鍵詞便是 MATCH,顧名思義,它是一個查詢關(guān)鍵詞,它會去選擇匹配對應(yīng)條件下的點邊,再進(jìn)行下一步操作。

          查看數(shù)據(jù)

          復(fù)制代碼

          # nGQLnebula> FETCH PROP ON character hash("saturn");===================================================| character.name | character.age | character.type |===================================================| saturn         | 10000         | titan          |---------------------------------------------------# Gremlingremlin> g.V(saturn).valueMap();==>[name:[saturn],type:[titan],age:[10000]]# Cyphercypher> MATCH (n:character {name:"saturn"}) RETURN properties(n)  ╒════════════════════════════════════════════╕  │"properties(n)"                             │  ╞════════════════════════════════════════════╡  │{"name":"saturn","type":"titan","age":10000}│  └────────────────────────────────────────────┘

          在查看數(shù)據(jù)這塊,Gremlin 通過調(diào)取 valueMap() 獲得對應(yīng)的屬性值,而 Cypher 正如上面更新數(shù)據(jù)所說,依舊是 MATCH 關(guān)鍵詞來進(jìn)行對應(yīng)的匹配查詢再通過 RETURN 返回對應(yīng)的數(shù)值,而 nGQL 則對 saturn 進(jìn)行 hash 運(yùn)算得到對應(yīng) VID 之后去獲取對應(yīng) VID 的屬性值。

          查詢 hercules 的父親

          復(fù)制代碼

          # nGQLnebula>  LOOKUP ON character WHERE character.name=='hercules' | \      -> GO FROM $-.VertexID OVER father YIELD $$.character.name;=====================| $$.character.name |=====================| jupiter           |---------------------# Gremlingremlin> g.V().hasLabel('character').has('name','hercules').out('father').values('name');==>jupiter# Cyphercypher> MATCH (src:character{name:"hercules"})-[:father]->(dst:character) RETURN dst.name      ╒══════════╕      │"dst.name"│      ╞══════════╡      │"jupiter" │      └──────────┘

          查詢父親,其實是一個查詢關(guān)系 / 邊的操作,這里不做贅述,上面插入邊的時候簡單介紹了 Gremlin、Cypher、nGQL 這三種圖數(shù)據(jù)庫是各自用來標(biāo)識邊的關(guān)鍵詞和操作符是什么。

          查詢 hercules 的祖父

          復(fù)制代碼

          # nGQLnebula> LOOKUP ON character WHERE character.name=='hercules' | \     -> GO 2 STEPS FROM $-.VertexID OVER father YIELD $$.character.name;=====================| $$.character.name |=====================| saturn            |---------------------# Gremlingremlin> g.V().hasLabel('character').has('name','hercules').out('father').out('father').values('name');==>saturn# Cyphercypher> MATCH (src:character{name:"hercules"})-[:father*2]->(dst:character) RETURN dst.name      ╒══════════╕      │"dst.name"│      ╞══════════╡      │"saturn"  │      └──────────┘

          查詢祖父,其實是一個查詢對應(yīng)點的兩跳關(guān)系,即:父親的父親,我們可以看到 Gremlin 使用了兩次 out() 來表示為祖父,而 nGQL 這里使用了 (Pipe 管道) 的概念,用于子查詢。在兩跳關(guān)系處理上,上面說到 Gremlin 是用了 2 次 out(),而 Cypher、nGQL 則引入了 step 數(shù)的概念,分別對應(yīng)到查詢語句的 GO 2 STEP 和 [:father *2],相對來說 Cypher、nGQL 這樣書寫更優(yōu)雅。

          查詢年齡大于 100 的人物

          復(fù)制代碼

          # nGQLnebula> LOOKUP ON character WHERE character.age > 100 YIELD character.name, character.age;=========================================================| VertexID             | character.name | character.age |=========================================================| 6761447489613431910  | pluto          | 4000          |---------------------------------------------------------| -5860788569139907963 | neptune        | 4500          |---------------------------------------------------------| 4863977009196259577  | jupiter        | 5000          |---------------------------------------------------------| -4316810810681305233 | saturn         | 10000         |---------------------------------------------------------# Gremlingremlin> g.V().hasLabel('character').has('age',gt(100)).values('name');==>saturn==>jupiter==>neptune==>pluto# Cyphercypher> MATCH (src:character) WHERE src.age > 100 RETURN src.name      ╒═══════════╕      │"src.name" │      ╞═══════════╡      │  "saturn" │      ├───────────┤      │ "jupiter" │      ├───────────┤      │ "neptune" │      │───────────│      │  "pluto"  │      └───────────┘

          這個是一個典型的查詢語句,找尋符合特定條件的點并返回結(jié)果,在 Cypher 和 nGQL 中用 WHRER 進(jìn)行條件判斷,而 Gremlin 延續(xù)了它的“編程風(fēng)”用 gt(100) 表示年大于齡 100 的這個篩選條件,延伸下 Gremlin 中 eq() 則表示等于這個查詢條件。

          從一起居住的人物中排除 pluto 本人

          復(fù)制代碼

          # nGQLnebula>  GO FROM hash("pluto") OVER lives YIELD lives._dst AS place | GO FROM $-.place OVER lives REVERSELY WHERE $$.character.name !="pluto" YIELD $$.character.name AS cohabitants;===============| cohabitants |===============| cerberus    |---------------# Gremlingremlin> g.V(pluto).out('lives').in('lives').where(is(neq(pluto))).values('name');==>cerberus# Cyphercypher> MATCH (src:character{name:"pluto"})-[:lives]->()<-[:lives]-(dst:character) RETURN dst.name      ╒══════════╕      │"dst.name"│      ╞══════════╡      │"cerberus"│      └──────────┘

          這是一個沿指定點 Pluto 反向查詢指定邊(居住)的操作,在反向查詢中,Gremlin 使用了 in 來表示反向關(guān)系,而 Cypher 則更直觀的將指向箭頭反向變成 <- 來表示反向關(guān)系,nGQL 則用關(guān)鍵詞 REVERSELY 來標(biāo)識反向關(guān)系。

          Pluto 的兄弟們居住在哪

          復(fù)制代碼

          # which brother lives in which place?## nGQLnebula> GO FROM hash("pluto") OVER brother YIELD brother._dst AS god | \GO FROM $-.god OVER lives YIELD $^.character.name AS Brother, $$.location.name AS Habitations;=========================| Brother | Habitations |=========================| jupiter | sky         |-------------------------| neptune | sea         |-------------------------## Gremlingremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god','place').by('name');==>[god:jupiter, place:sky]==>[god:neptune, place:sea]## Cyphercypher> MATCH (src:Character{name:"pluto"})-[:brother]->(bro:Character)-[:lives]->(dst)RETURN bro.name, dst.name      ╒═════════════════════════╕      │"bro.name"    │"dst.name"│      ╞═════════════════════════╡      │ "jupiter"    │  "sky"   │      ├─────────────────────────┤      │ "neptune"    │ "sea"    │      └─────────────────────────┘

          這是一個通過查詢指定點 Pluto 查詢指定邊 brother 后再查詢指定邊 live 的查詢,相對來說不是很復(fù)雜,這里就不做解釋說明了。

          最后,本文只是對 Gremlin、Cypher、nGQL 等 3 個圖查詢語言進(jìn)行了簡單的介紹,更復(fù)雜的語法將在本系列的后續(xù)文章中繼續(xù),歡迎在論壇留言交流。


          主站蜘蛛池模板: 亚洲乱码一区av春药高潮| 国产精品主播一区二区| 精产国品一区二区三产区| 无码一区二区三区免费| 无码人妻久久一区二区三区蜜桃| 在线观看中文字幕一区| 国产一区二区不卡在线播放| 久久青草国产精品一区| 日韩免费一区二区三区在线 | 亚洲一区二区三区高清| 久久久久人妻精品一区二区三区 | 精品熟人妻一区二区三区四区不卡 | 日韩一区二区三区视频久久| 国产a∨精品一区二区三区不卡| 日韩美女视频一区| 波多野结衣一区二区| 精品亚洲一区二区| 国产福利电影一区二区三区久久久久成人精品综合 | 精品国产一区二区三区| 无码人妻精品一区二区三区东京热 | 一区二区三区免费在线视频| 人妻视频一区二区三区免费| 亚洲av午夜福利精品一区人妖| 国偷自产Av一区二区三区吞精| 老湿机一区午夜精品免费福利| 女人18毛片a级毛片一区二区| 亚洲视频一区网站| 亚洲午夜精品一区二区公牛电影院| 日韩制服国产精品一区| 国产在线一区二区在线视频| 国产a∨精品一区二区三区不卡| 国产成人精品无码一区二区老年人| 国产一区二区精品尤物| 亚洲熟妇av一区二区三区 | 美女视频一区三区网站在线观看| 亚洲综合av永久无码精品一区二区 | 中文字幕乱码一区久久麻豆樱花| 国产精品一区二区久久国产| 亚洲综合无码精品一区二区三区| 亚洲av综合av一区| 精品成人一区二区三区免费视频|