JDBC连接数据库概述

一、JDBC基础知识

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC为数据库开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯 Java API 编写数据库应用程序,并且可跨平台运行,并且不受数据库供应商的限制。

1、跨平台运行:这是继承了Java语言的“一次编译,到处运行”的特点;

2、不受数据库供应商的限制:巧妙在于JDBC设有两种接口,一个是面向应用程序层,其作用是使得开发人员通过SQL调用数据库和处理结果,而不需要考虑数据库的提供商;另一个是驱动程序层,处理与具体驱动程序的交互,JDBC驱动程序可以利用JDBC API创建Java程序和数据源之间的桥梁。应用程序只需要编写一次,便可以移到各种驱动程序上运行。Sun提供了一个驱动管理器,数据库供应商——如MySQL、Oracle,提供的驱动程序满足驱动管理器的要求就可以被识别,就可以正常工作。所以JDBC不受数据库供应商的限制。

JDBC API可以作为连接Java应用程序与各种关系数据库的纽带,在带来方便的同时也有负面影响,以下是JDBC的优、缺点。优点如下:

操作便捷:JDBC使得开发人员不需要再使用复杂的驱动器调用命令和函数;

可移植性强:JDBC支持不同的关系数据库,所以可以使同一个应用程序支持多个数据库的访问,只要加载相应的驱动程序即可;

通用性好:JDBC-ODBC桥接驱动器将JDBC函数换成ODBC;

面向对象:可以将常用的JDBC数据库连接封装成一个类,在使用的时候直接调用即可。

缺点如下:

访问数据记录的速度受到一定程度的影响;

更改数据源困难:JDBC可支持多种数据库,各种数据库之间的操作必有不同,这就给更改数据源带来了很大的麻烦

二、JDBC连接数据库的流程及其原理

创建一个以JDBC连接数据库的程序,包含7个步骤:

1、加载JDBC驱动程序:

在连接数据库之前,首先要加载想要连接的数据库的驱动,就是数据库厂商提供的jar包,将它加载到JVM(Java虚拟机)中,这通过java.lang.Class类的静态方法forName(String className)实现。

例如:

  1. 01
  2. try{
  3. 02
  4.  
  5. 03
  6. //加载MySql的驱动类 
  7. 04
  8. //不同的数据库提供的驱动包是不一样的,在下面大家将会看到常用的驱动类。
  9. 05
  10. Class.forName("com.mysql.jdbc.Driver") ; 
  11. 06
  12. System.out.println("成功加载驱动");
  13. 07
  14.  
  15. 08
  16. }catch(ClassNotFoundException e){
  17. 09
  18.  
  19. 10
  20. System.out.println("找不到驱动程序类 ,加载驱动失败!");
  21. 11
  22.  
  23. 12
  24. e.printStackTrace() ;
  25. 13
  26.  
  27. 14
  28. }
  29.  

成功加载后,会将Driver类的实例注册到DriverManager类中,我们在下一步中,就可以直接调用类中的方法。

2、提供JDBC连接的URL

•连接URL定义了连接数据库时的协议、子协议、数据源标识。

•书写形式:协议:子协议:数据源标识

协议:在JDBC中总是以jdbc开始

子协议:是桥连接的驱动程序或是数据库管理系统名称。

数据源标识:标记找到数据库来源的地址与连接端口。

下面列出常用的数据库连接URL:

Oracle8/8i/9i数据库(thin模式)

  1. 1
  2. Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
  3. 2
  4. String url="jdbc:oracle:thin:@localhost:1521:orcl";
  5. 3
  6. //orcl为数据库的SID
  7.  

DB2数据库

  1. 1
  2. Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
  3. 2
  4. String url="jdbc:db2://localhost:5000/sample";
  5. 3
  6. //sample为你的数据库名
  7.  

Sql Server7.0/2000数据库

  1. 1
  2. Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
  3. 2
  4. String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";
  5. 3
  6. //mydb为数据库
  7.  

Sybase数据库

  1. 1
  2. Class.forName("com.sybase.jdbc.SybDriver").newInstance();
  3. 2
  4. String url =" jdbc:sybase:Tds:localhost:5007/myDB";
  5. 3
  6. //myDB为你的数据库名
  7.  

Informix数据库

  1. 1
  2. Class.forName("com.informix.jdbc.IfxDriver").newInstance();
  3. 2
  4. String url ="jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
  5.  

MySQL数据库

  1. 1
  2. Class.forName("com.mysql.jdbc.Driver").newInstance();
  3. 2
  4. String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1"
  5. 3
  6. //myDB为数据库名
  7.  

PostgreSQL数据库

  1. 1
  2. Class.forName("org.postgresql.Driver").newInstance();
  3. 2
  4. String url ="jdbc:postgresql://localhost/myDB"
  5. 3
  6. //myDB为数据库名
  7.  

说明:useUnicode=true:表示使用Unicode字符集。如果characterEncoding设置为gb2312或GBK,本参数必须设置为true 。aracterEncoding=gbk:字符编码方式。

3、创建数据库的连接

•要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。

•使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。

例如:

  1. 01
  2. String url = "jdbc:mysql://localhost:3306/test" ;
  3. 02
  4.  
  5. 03
  6. String username = "root" ;
  7. 04
  8.  
  9. 05
  10. String password = "root" ;
  11. 06
  12.  
  13. 07
  14. try{
  15. 08
  16.  
  17. 09
  18. Connection con =
  19. 10
  20.  
  21. 11
  22. DriverManager.getConnection(url , username , password ) ;
  23. 12
  24.  
  25. 13
  26. }catch(SQLException se){
  27. 14
  28.  
  29. 15
  30. System.out.println("数据库连接失败!");
  31. 16
  32.  
  33. 17
  34. se.printStackTrace() ;
  35. 18
  36.  
  37. 19
  38. }
  39.  

也可以不单独定义上面username和password,直接将用户名、密码附加在url上,作为参数发送给数据库服务器,例如

  1. 1
  2. jdbc:mysql://localhost:3306/test?user=root&password=root
  3.  

4、创建一个Statement

•要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3

种类型:

1、执行静态SQL语句。通常通过Statement实例实现。

2、执行动态SQL语句。通常通过PreparedStatement实例实现。

3、执行数据库存储过程。通常通过CallableStatement实例实现。

具体的实现方式:

  1. 1
  2. Statement stmt = con.createStatement() ; 
  3. 2
  4. PreparedStatement pstmt = con.prepareStatement(sql) ; 
  5. 3
  6. CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ; 
  7.  

5、执行SQL语句

Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate

和execute

1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句

,返回一个结果集(ResultSet)对象。

2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或

DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等

3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的

语句。

具体实现的代码:

  1. 1
  2. ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ; 
  3. 2
  4. int rows = stmt.executeUpdate("INSERT INTO ...") ; 
  5. 3
  6. boolean flag = stmt.execute(String sql) ; 
  7.  

6、处理结果

两种情况:

1、执行更新返回的是本次操作影响到的记录数。

2、执行查询返回的结果是一个ResultSet对象。

• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些

行中数据的访问。

• 使用结果集(ResultSet)对象的访问方法获取数据:

  1. 1
  2. while(rs.next()){
  3. 2
  4.  
  5. 3
  6. String name = rs.getString("name") ;
  7. 4
  8.  
  9. 5
  10. String pass = rs.getString(1) ; // 此方法比较高效
  11. 6
  12.  
  13. 7
  14. }
  15.  

(列是从左到右编号的,并且从列1开始)

7、关闭JDBC对象

操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声

明顺序相反:

1、关闭记录集

2、关闭声明

3、关闭连接对象

  1. 01
  2. if(rs != null){ // 关闭记录集
  3. 02
  4.  
  5. 03
  6. try{
  7. 04
  8.      rs.close() ;
  9. 05
  10.  
  11. 06
  12. }catch(SQLException e){
  13. 07
  14.  
  15. 08
  16.      e.printStackTrace() ;
  17. 09
  18.  
  19. 10
  20. }   }
  21. 11
  22.  
  23. 12
  24. if(stmt != null){ // 关闭声明
  25. 13
  26.  
  27. 14
  28. try{
  29. 15
  30.  
  31. 16
  32. stmt.close() ;
  33. 17
  34.  
  35. 18
  36. }catch(SQLException e){
  37. 19
  38.  
  39. 20
  40. e.printStackTrace() ;
  41. 21
  42. }     }
  43. 22
  44.  
  45. 23
  46. if(conn != null){ // 关闭连接对象
  47. 24
  48.  
  49. 25
  50. try{
  51. 26
  52.  
  53. 27
  54. conn.close() ;
  55. 28
  56.  
  57. 29
  58. }catch(SQLException e){
  59. 30
  60.  
  61. 31
  62. e.printStackTrace() ;
  63. 32
  64.  
  65. 33
  66. }    }
  67. 34
  68.  

三、JDBC应用示例实验

实验使用mysql数据库,使用myeclipse工具新建一个类,命名为 JDBCTest,可以使用Navicat for MySQL可视化数据库操作,新建数据库users,在数据库users里添加 表user_table( UserId,UserName,PassWord)),有三个字段,本示例主要用于演示数据库连接,连接成功后,插入一条数据。具体内容如下

  1. 01
  2. import java.sql.*;
  3. 02
  4. public class JDBCTest {
  5. 03
  6.  
  7. 04
  8. /**
  9. 05
  10. * @param args
  11. 06
  12. * @throws ClassNotFoundException 
  13. 07
  14. * @throws SQLException 
  15. 08
  16. */
  17. 09
  18. public static void main(String[] args) throws ClassNotFoundException, SQLException {
  19. 10
  20. //第一步:打开数据库 需要用户名,密码,数据库地址,数据库名称;
  21. 11
  22. String username = "root";
  23. 12
  24. String password = "123456";
  25. 13
  26.  
  27. 14
  28. String url = "jdbc:mysql://localhost:3306/users";
  29. 15
  30. //1.加载数据库驱动
  31. 16
  32. Class.forName("com.mysql.jdbc.Driver");
  33. 17
  34. //2.创建是数据库连接
  35. 18
  36. Connection conn = DriverManager.getConnection(url, username, password);
  37. 19
  38.  
  39. 20
  40. System.out.println("数据库连接成功!");
  41. 21
  42. //第二步:操作数据库;
  43. 22
  44. String sql=" insert into user_table ( UserId,UserName,PassWord) values (5,'song','ss') ";
  45. 23
  46. PreparedStatement pt=conn.prepareStatement( sql );
  47. 24
  48. pt.executeUpdate( );
  49. 25
  50. //第三步:关闭数据库;
  51. 26
  52. conn.close();
  53. 27
  54. System.out.println("数据库操作成功!");
  55. 28
  56.  
  57. 29
  58. }
  59. 30
  60.  
  61. 31
  62. }
  63.  

更多关于数据库的操作,如增删改查,参考网友sererin写的如下代码,很详细:

  1. 001
  2. 002
  3. <PRE class=java name="code">package chp07;
  4. 003
  5.  
  6. 004
  7. import java.sql.Connection;
  8. 005
  9. import java.sql.DriverManager;
  10. 006
  11. import java.sql.ResultSet;
  12. 007
  13. import java.sql.SQLException;
  14. 008
  15. import java.sql.Statement;
  16. 009
  17.  
  18. 010
  19. public class JDBC_Test {
  20. 011
  21.  // 创建静态全局变量
  22. 012
  23.  static Connection conn;
  24. 013
  25.  
  26. 014
  27.  static Statement st;
  28. 015
  29.  
  30. 016
  31.  public static void main(String[] args) {
  32. 017
  33.  insert(); //插入添加记录
  34. 018
  35.  update(); //更新记录数据
  36. 019
  37.  delete(); //删除记录
  38. 020
  39.  query(); //查询记录并显示
  40. 021
  41.  }
  42. 022
  43.  
  44. 023
  45.  /* 插入数据记录,并输出插入的数据记录数*/
  46. 024
  47.  public static void insert() {
  48. 025
  49.  
  50. 026
  51.  conn = getConnection(); // 首先要获取连接,即连接到数据库
  52. 027
  53.  
  54. 028
  55.  try {
  56. 029
  57.  String sql = "INSERT INTO staff(name, age, sex,address, depart, worklen,wage)"
  58. 030
  59.  + " VALUES ('Tom1', 32, 'M', 'china','Personnel','3','3000')"; // 插入数据的sql语句
  60. 031
  61.  
  62. 032
  63.  st = (Statement) conn.createStatement(); // 创建用于执行静态sql语句的Statement对象
  64. 033
  65.  
  66. 034
  67.  int count = st.executeUpdate(sql); // 执行插入操作的sql语句,并返回插入数据的个数
  68. 035
  69.  
  70. 036
  71.  System.out.println("向staff表中插入 " + count + " 条数据"); //输出插入操作的处理结果
  72. 037
  73.  
  74. 038
  75.  conn.close(); //关闭数据库连接
  76. 039
  77.  
  78. 040
  79.  } catch (SQLException e) {
  80. 041
  81.  System.out.println("插入数据失败" + e.getMessage());
  82. 042
  83.  }
  84. 043
  85.  }
  86. 044
  87.  
  88. 045
  89.  /* 更新符合要求的记录,并返回更新的记录数目*/
  90. 046
  91.  public static void update() {
  92. 047
  93.  conn = getConnection(); //同样先要获取连接,即连接到数据库
  94. 048
  95.  try {
  96. 049
  97.  String sql = "update staff set wage='2200' where name = 'lucy'";// 更新数据的sql语句
  98. 050
  99.  
  100. 051
  101.  st = (Statement) conn.createStatement(); //创建用于执行静态sql语句的Statement对象,st属局部变量
  102. 052
  103.  
  104. 053
  105.  int count = st.executeUpdate(sql);// 执行更新操作的sql语句,返回更新数据的个数
  106. 054
  107.  
  108. 055
  109.  System.out.println("staff表中更新 " + count + " 条数据"); //输出更新操作的处理结果
  110. 056
  111.  
  112. 057
  113.  conn.close(); //关闭数据库连接
  114. 058
  115.  
  116. 059
  117.  } catch (SQLException e) {
  118. 060
  119.  System.out.println("更新数据失败");
  120. 061
  121.  }
  122. 062
  123.  }
  124. 063
  125.  
  126. 064
  127.  /* 查询数据库,输出符合要求的记录的情况*/
  128. 065
  129.  public static void query() {
  130. 066
  131.  
  132. 067
  133.  conn = getConnection(); //同样先要获取连接,即连接到数据库
  134. 068
  135.  try {
  136. 069
  137.  String sql = "select * from staff"; // 查询数据的sql语句
  138. 070
  139.  st = (Statement) conn.createStatement(); //创建用于执行静态sql语句的Statement对象,st属局部变量
  140. 071
  141.  
  142. 072
  143.  ResultSet rs = st.executeQuery(sql); //执行sql查询语句,返回查询数据的结果集
  144. 073
  145.  System.out.println("最后的查询结果为:");
  146. 074
  147.  while (rs.next()) { // 判断是否还有下一个数据
  148. 075
  149.  
  150. 076
  151.  // 根据字段名获取相应的值
  152. 077
  153.  String name = rs.getString("name");
  154. 078
  155.  int age = rs.getInt("age");
  156. 079
  157.  String sex = rs.getString("sex");
  158. 080
  159.  String address = rs.getString("address");
  160. 081
  161.  String depart = rs.getString("depart");
  162. 082
  163.  String worklen = rs.getString("worklen");
  164. 083
  165.  String wage = rs.getString("wage");
  166. 084
  167.  
  168. 085
  169.  //输出查到的记录的各个字段的值
  170. 086
  171.  System.out.println(name + " " + age + " " + sex + " " + address
  172. 087
  173.  + " " + depart + " " + worklen + " " + wage);
  174. 088
  175.  
  176. 089
  177.  }
  178. 090
  179.  conn.close(); //关闭数据库连接
  180. 091
  181.  
  182. 092
  183.  } catch (SQLException e) {
  184. 093
  185.  System.out.println("查询数据失败");
  186. 094
  187.  }
  188. 095
  189.  }
  190. 096
  191.  
  192. 097
  193.  /* 删除符合要求的记录,输出情况*/
  194. 098
  195.  public static void delete() {
  196. 099
  197.  
  198. 100
  199.  conn = getConnection(); //同样先要获取连接,即连接到数据库
  200. 101
  201.  try {
  202. 102
  203.  String sql = "delete from staff  where name = 'lili'";// 删除数据的sql语句
  204. 103
  205.  st = (Statement) conn.createStatement(); //创建用于执行静态sql语句的Statement对象,st属局部变量
  206. 104
  207.  
  208. 105
  209.  int count = st.executeUpdate(sql);// 执行sql删除语句,返回删除数据的数量
  210. 106
  211.  
  212. 107
  213.  System.out.println("staff表中删除 " + count + " 条数据\n"); //输出删除操作的处理结果
  214. 108
  215.  
  216. 109
  217.  conn.close(); //关闭数据库连接
  218. 110
  219.  
  220. 111
  221.  } catch (SQLException e) {
  222. 112
  223.  System.out.println("删除数据失败");
  224. 113
  225.  }
  226. 114
  227.  
  228. 115
  229.  }
  230. 116
  231.  
  232. 117
  233.  /* 获取数据库连接的函数*/
  234. 118
  235.  public static Connection getConnection() {
  236. 119
  237.  Connection con = null; //创建用于连接数据库的Connection对象
  238. 120
  239.  try {
  240. 121
  241.  Class.forName("com.mysql.jdbc.Driver");// 加载Mysql数据驱动
  242. 122
  243.  
  244. 123
  245.  con = DriverManager.getConnection(
  246. 124
  247.  "jdbc:mysql://localhost:3306/myuser", "root", "root");// 创建数据连接
  248. 125
  249.  
  250. 126
  251.  } catch (Exception e) {
  252. 127
  253.  System.out.println("数据库连接失败" + e.getMessage());
  254. 128
  255.  }
  256. 129
  257.  return con; //返回所建立的数据库连接
  258. 130
  259.  }
  260. 131
  261. }
  262. 132
  263. </PRE><BR>
  264. 133
  265. <PRE></PRE>
  266. 134
  267. <P></P>
  268. 135
  269. <P><STRONG>项目部署到服务器,然后运行结果:</STRONG></P>
  270. 136
  271. <P></P>
  272. 137
  273. <PRE></PRE>
  274. 138
  275. <PRE></PRE>
  276. 139
  277. <PRE></PRE>
  278. 140
  279.  

JAVA采用JDBC连接操作数据库详解的更多相关文章

  1. JAVA通过JDBC连接Oracle数据库详解【转载】

    JAVA通过JDBC连接Oracle数据库详解 (2011-03-15 00:10:03) 转载▼http://blog.sina.com.cn/s/blog_61da86dd0100q27w.htm ...

  2. ava基础MySQL存储过程 Java基础 JDBC连接MySQL数据库

    1.MySQL存储过程   1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if  while)等等 的sql语句   1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...

  3. java用JDBC连接MySQL数据库的详细知识点

    想实现java用JDBC连接MySQL数据库.需要有几个准备工作: 1.下载Connector/J的库文件,下载Connector/J的官网地址:http://www.mysql.com/downlo ...

  4. JAVA连接各种数据库详解

    Java数据库连接(JDBC)由一组用 Java 编程语言编写的类和接口组成.JDBC 为工具/数据库开发人员提供了一个标准的 API,使他们能够用纯Java API 来编写数据库应用程序.然而各个开 ...

  5. Java使用JDBC连接MySQL数据库

    1.引用 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写 ...

  6. 使用JDBC连接操作数据库

    JDBC简介 Java数据库连接(Java Database Connectivity,JDBC),是一种用于执行SQL语句的Java API,它由一组用Java编程语言编写的类和接口组成. JDBC ...

  7. 【转】Java 通过JDBC连接Mysql数据库的方法和实例【图文说明】

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...

  8. Java 通过JDBC连接Mysql数据库的方法和实例

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...

  9. Java 通过JDBC连接Mysql数据库的方法和实例【图文说明】

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...

随机推荐

  1. 关于vis标记

    原来写题目的时候对vis标记都是先memset在标记,今天看见一个只要每次对T值修改,然后看看等不等于T就可以了,真好!

  2. Python同时向控制台和文件输出日志logging的方法 Python logging模块详解

    Python同时向控制台和文件输出日志logging的方法http://www.jb51.net/article/66756.htm 1 #-*- coding:utf-8 -*- 2 import ...

  3. jquery实现复选框全选反选

    实现原理: 给所有的复选框取相同的名字,当点击全选的时候把chenked属性全部设置为true;当点击全不选的时候把checked属性设置为false; 源代码如下: html代码: <form ...

  4. div弹出登录窗口

    <meta charset="utf-8"/> <script type="text/javascript"> //弹出式登录 func ...

  5. flask开发restful api系列(5)-短信验证码

    我们现在开发app,注册用户的时候,不再像web一样,发送到个人邮箱了,毕竟个人邮箱在移动端填写验证都很麻烦,一般都采用短信验证码的方式.今天我们就讲讲这方面的内容. 首先,先找一个平台吧.我们公司找 ...

  6. Leakcanary

    一.什么是内存泄漏 垃圾回收器无法回收应被回收的对象比如:在Activity生命周期过程中,旋转屏幕时应新建activity,原activity应被销毁.但如果线程一直在引用此activity,则会出 ...

  7. IOS多线程 总结 -------------核心代码(GCD)

    //NSObject //在子线程中执行代码 // 参数1: 执行的方法 (最多有一个参数,没有返回值) //参数2: 传递给方法的参数 [self performSelectorInBackgrou ...

  8. BZOJ1628: [Usaco2007 Demo]City skyline

    1628: [Usaco2007 Demo]City skyline Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 256  Solved: 210[Su ...

  9. Linux企业级项目实践之网络爬虫(4)——主程序流程

    当我们设计好程序框架之后就要开始实现它了.第一步当然是要实现主程序的流程框架.之后我们逐渐填充每个流程的细节和其需要调用的模块. 主程序的流程如下: 1.  解析命令行参数,并根据参数跳转到相应的处理 ...

  10. Centos 6.5中安装后不能打开emacs的问题

    问题的发现过程: 安装了最新的centos版本后发现居然打不开emacs,然后在终端中输入emacs后还是不能打开,出现了下面的提示: emacs: error while loading share ...