Wednesday, May 30, 2012

Ubuntu 命令行模式和图形界面切换问题的解决

1、从桌面版怎么能进命令模式呢?

alt + ctrl + f1 ~ f6

或者

在终端中输入命令:sudo /etc/init.d/gdm stop 进入文本模式

alt + ctrl + f7 ~ f12

但是尝试后没有成功。不知道是不是我用虚拟机的缘故。

或者

startx 回到桌面


2、为什么用sudo /etc/init.d/gdm stop进入命令行界面后,再以startx进入图形界面的话这个命令sudo /etc/init.d/gdm stop就再也不行了呢?

需要搞清楚系统服务GDM(/etc/init.d/gdm)和X-Window的关系。

gdm服务是一个脚本,通过这个脚本可以启动X-Window并将gdm程序(/usr/bin/gdm) 作为窗口管理器 (Desktop Manager)。

系统服务的状态通常有两种:Running 或者 Stopped, 其状态转换可以通过下面的命令实现:

Stopped ==> Running: /etc/init.d/xxx start (开启服务)

Running ==> Stopped: /etc/init.d/xxx stop (停止服务)

还有另外一种: /etc/init.d/xxx restart (重启服务)
即:

sudo /etc/init.d/gdm stop #彻底停止x window

sudo /etc/init.d/gdm restart #启动x window

前面使用 /etc/init.d/gdm stop 来将服务关闭了(同时也关闭了已经打开的 X-window),然后用 startx 来启动了 X-window, 此时 gdm服务已经停止,你再次使用 /etc/init.d/gdm stop 的话,由于该服务已经停止,这个命令当然不会有什么作用。


记住: 系统服务只能在已经启动的前提下才能关闭或者重启,所以说“只能用一次这个命令”。

Ubuntu 10.04 命令行启动

还是搜国外的资料靠谱,英文关键字 ubuntu 10.04 text boot

在 /etc/init/rc-sysinit.conf:
env DEFAULT_RUNLEVEL=3 设置启动默认级别为3

in /etc/init/gdm.conf:
start on (filesystem
and started hal
and tty-device-added KERNEL=tty7
and (graphics-device-added or stopped udevtrigger)
and runlevel [!3]) 添加这一行
stop on runlevel [016]



然后就可以了。回去试试看


Tuesday, May 29, 2012

Java PreparedStatement 批处理执行

更新一个数据表字段,数据量较大的情况下,不能每次执行一条sql语句,这样数据库负担太大,而且速度相当慢。所以要采用批处理的方法执行。




  1. Statement批量处理和事务代码如下:  
  2. package com.ambow.day20.jdbc.JDBCTestCommitAndRollback;  
  3. import java.sql.Connection;  
  4. import java.sql.SQLException;  
  5. import java.sql.Statement;  
  6. import com.ambow.day19.jdbc.util.JDBCConAndClo;  
  7. /* 
  8.  *1,首先把Auto commit设置为false,不让它自动提交 
  9.  *2,进行手动提交(commit) 
  10.  *3,提交完成后回复现场将Auto commit,还原为true, 
  11.  *4,当异常发生执行catch中SQLException时,记得要rollback(回滚); 
  12.  * */  
  13. public class StatementCommitAndRollbackTest {  
  14.     public static void main(String args[]) {  
  15.         Connection con = null;  
  16.         Statement stm = null;  
  17.         try {  
  18.             con = JDBCConAndClo.getConnectionBao();  
  19.             stm = con.createStatement();  
  20.             con.setAutoCommit(false);  
  21.             // 若不出现异常,则继续执行到try语句完,否则跳转到catch语句中  
  22.             stm.addBatch("insert into student values(23,'tangbao','高数',100)");  
  23.             stm.addBatch("insert into student values(24,'王定','c#',98)");  
  24.             stm.addBatch("insert into student values(25,'王国云','java',90)");  
  25.             stm.addBatch("insert into student values(26,'溜出','英语',89)");  
  26.             stm.addBatch("insert into student values(27,'wqde','java',63)");  
  27.             /* 
  28.              * int[] executeBatch() throws 
  29.              * SQLException将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。 
  30.              */  
  31.             stm.executeBatch();  
  32.             System.out.println("插入成功!");  
  33.             // commit:若成功执行完所有的插入操作,则正常结束  
  34.             con.commit();  
  35.             System.out.println("提交成功!");  
  36.             con.setAutoCommit(true);  
  37.   
  38.         } catch (SQLException e) {  
  39.             e.printStackTrace();  
  40.             try {  
  41.     //rollback: 若出现异常,对数据库中所有已完成的操作全部撤销,则回滚到事务开始状态  
  42.                 if (!con.isClosed()) {  
  43.                     con.rollback();  
  44.                     System.out.println("提交失败,回滚!");  
  45.                     con.setAutoCommit(true);  
  46.                 }  
  47.             } catch (SQLException e1) {  
  48.                 e1.printStackTrace();  
  49.             } finally {  
  50.                 JDBCConAndClo.closeStatement(stm);  
  51.                 JDBCConAndClo.closeConnection(con);  
  52.             }  
  53.         }  
  54.     }  
  55. }  
  56. PreparedStatement批量处理和事务代码如下:  
  57. package com.ambow.day20.jdbc.JDBCTestCommitAndRollback;  
  58. import java.sql.Connection;  
  59. import java.sql.PreparedStatement;  
  60. import java.sql.SQLException;  
  61. import com.ambow.day19.jdbc.util.JDBCConAndClo;  
  62.   
  63. /* 
  64.  * PreparedStatement: 
  65.  1.addBatch() 将一组参数添加到 PreparedStatement对象内部 
  66.  2.executeBatch() 将一批参数提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。 
  67.  *  
  68.  */  
  69. public class PreparedStatementCommitAndRollbackTest {  
  70.     public static void main(String args[]) {  
  71.         Connection con = null;  
  72.         PreparedStatement pstm = null;  
  73.   
  74.         try {  
  75.             // 1. 建立与数据库的连接  
  76.             con = JDBCConAndClo.getConnectionBao();  
  77.             // 2. 执行sql语句  
  78.             // 1).先创建PreparedStatement语句(发送slq请求):  
  79.             pstm = con.prepareStatement("insert into student values(?,?,?,?)");  
  80.             con.setAutoCommit(false);//1,首先把Auto commit设置为false,不让它自动提交  
  81.             // 2) 设置sql语句1  
  82.             pstm.setInt(133);  
  83.             pstm.setString(2,"wangqin");  
  84.             pstm.setString(3"c++");  
  85.             pstm.setDouble(478.5);  
  86.             // 3) 将一组参数添加到此 PreparedStatement 对象的批处理命令中。  
  87.             pstm.addBatch();  
  88.             // 2) 设置sql语句2  
  89.             pstm.setInt(134);  
  90.             pstm.setString(2,"wuytun");  
  91.             pstm.setString(3"c");  
  92.             pstm.setDouble(477);  
  93.             // 3) 将一组参数添加到此 PreparedStatement 对象的批处理命令中。  
  94.             pstm.addBatch();  
  95.             // 2) 设置sql语句3  
  96.             pstm.setInt(131);  
  97.             pstm.setString(2,"tetet");  
  98.             pstm.setString(3"c++");  
  99.             pstm.setDouble(490);  
  100.             // 3) 将一组参数添加到此 PreparedStatement 对象的批处理命令中。  
  101.             pstm.addBatch();  
  102.             // 2) 设置sql语句4  
  103.             pstm.setInt(132);  
  104.             pstm.setString(2,"liug");  
  105.             pstm.setString(3"c");  
  106.             pstm.setDouble(450);  
  107.             // 3) 将一组参数添加到此 PreparedStatement 对象的批处理命令中。  
  108.             pstm.addBatch();  
  109.             // 4) 将一批参数提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。  
  110.             pstm.executeBatch();  
  111.             System.out.println("插入成功!");  
  112.             // 若成功执行完所有的插入操作,则正常结束  
  113.             con.commit();//2,进行手动提交(commit)  
  114.             System.out.println("提交成功!");  
  115.             con.setAutoCommit(true);//3,提交完成后回复现场将Auto commit,还原为true,  
  116.   
  117.         } catch (SQLException e) {  
  118.             e.printStackTrace();  
  119.             try {  
  120.                 // 若出现异常,对数据库中所有已完成的操作全部撤销,则回滚到事务开始状态  
  121.                 if(!con.isClosed()){  
  122.                     con.rollback();//4,当异常发生执行catch中SQLException时,记得要rollback(回滚);  
  123.                     System.out.println("插入失败,回滚!");  
  124.                     con.setAutoCommit(true);  
  125.                 }  
  126.             } catch (SQLException e1) {  
  127.                 e1.printStackTrace();  
  128.             }  
  129.         }finally{  
  130.             JDBCConAndClo.closePreparedStatement(pstm);  
  131.             JDBCConAndClo.closeConnection(con);  
  132.         }  
  133.     }  
  134. }  


以下是我当时写的程序。


// 以下是MySQL的驱动连接
public static Connection MySQL_conn = null;
static PreparedStatement MySQL_statement = null;

public static String MySQL_URL = "jdbc:mysql://localhost:3306/test";
public static String MySQL_DRIVER = "com.mysql.jdbc.Driver";
public static String username = "root";
public static String password = "chaick1989";
//public Hashtable<String,String> province_code_name = new Hashtable<String, String>();   放到外面不可以使用!!!!!!!!!!?????
public static int sum = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {

Connect();// 打开mysql的数据库连接
ResultSet rs = selectSQL("select * from tb_data_2_copy");
String tmp_name = null;
String tmp_name_middle = null;
String tmp_name_rep = null;
int tmp_eid = 0;
String sql = null;
int i =0 ;
int i_tmp = 0 ; 
sql = "update tb_data_2_copy set name = ? where name = ? and eid = ? ";

MySQL_statement =  (PreparedStatement) MySQL_conn.prepareStatement(sql);
MySQL_conn.setAutoCommit(false);//把事物的自动提交设置为false,不自动提交
while (rs.next()){
tmp_name = rs.getString("name");
tmp_eid = rs.getInt("eid");
i++;
tmp_name_middle = tmp_name.replaceAll("\\([^)]*\\)", "");
tmp_name_rep = tmp_name_middle.replaceAll("\\([^)]*\\)", "");
if (!tmp_name.equals(tmp_name_rep)){
tmp_name_rep = Convert_Dan(tmp_name_rep);
tmp_name = Convert_Dan(tmp_name);
MySQL_statement.setString(1, tmp_name_rep);
MySQL_statement.setString(2, tmp_name);
MySQL_statement.setInt(3, tmp_eid);
MySQL_statement.addBatch();
i_tmp++;
if (i_tmp % 200 ==0){        //每预编译200个sql语句,提交一次。
MySQL_statement.executeBatch();//执行批处理
MySQL_conn.commit();//提交执行的事物
if (null==MySQL_conn) { //如果连接关闭了 就在创建一个 为什么要这样 原因是 conn.commit()后可能conn被关闭   
Connect();
MySQL_conn.setAutoCommit(false);   
}  
  MySQL_statement.clearBatch();把批处理队列清空
         
}
}
if (i % 2000 ==0){
System.out.println("执行了条数"+i );
}
}

if (MySQL_statement!=null){

    MySQL_statement.executeBatch();//执行

     MySQL_conn.commit();//提交

}


MySQL_conn.setAutoCommit(true); //重新还原自动提交事务


MySQL_statement.close(); //关闭statement

 Disconnect();



PreparedStatement接口继承Statement,并与之在两方面有所不同:

  PreparedStatement 实例包含已编译的 SQL 语句。这就是使语句“准备好”。包含于 PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。IN参数的值在 SQL 语句创建时未被指定。相反的,该语句为每个 IN 参数保留一个问号(“?”)作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX 方法来提供。

  由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象。因此,多次执行的 SQL 语句经常创建为 PreparedStatement 对象,以提高效率。


作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。另外它还添加了一整套方法,用于设置发送给数据库以取代 IN 参数占位符的值。同时,三种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数。这些方法的 Statement 形式(接受 SQL 语句参数的形式)不应该用于 PreparedStatement 对象。
1、创建 PreparedStatement 对象

以下的代码段(其中 con 是 Connection 对象)创建包含带两个 IN 参数占位符的 SQL 语句的 PreparedStatement 对象:

PreparedStatement pstmt = con.prepareStatement("UPDATE table4 SET m = ? WHERE x = ?");

pstmt 对象包含语句 "UPDATE table4 SET m = ? WHERE x = ?",它已发送给DBMS,并为执行作好了准备。

2、传递 IN 参数

在执行 PreparedStatement 对象之前,必须设置每个 ? 参数的值。这可通过调用 setXXX 方法来完成,其中 XXX 是与该参数相应的类型。例如,如果参数具有Java 类型 long,则使用的方法就是 setLong。setXXX 方法的第一个参数是要设置的参数的序数位置,第二个参数是设置给该参数的值。例如,以下代码将第一个参数设为 123456789,第二个参数设为 100000000:

pstmt.setLong(1, 123456789);
pstmt.setLong(2, 100000000);

一旦设置了给定语句的参数值,就可用它多次执行该语句,直到调用clearParameters 方法清除它为止。在连接的缺省模式下(启用自动提交),当语句完成时将自动提交或还原该语句。

如果基本数据库和驱动程序在语句提交之后仍保持这些语句的打开状态,则同一个 PreparedStatement 可执行多次。如果这一点不成立,那么试图通过使用PreparedStatement 对象代替 Statement 对象来提高性能是没有意义的。

利用 pstmt(前面创建的 PreparedStatement 对象),以下代码例示了如何设置两个参数占位符的值并执行 pstmt 10 次。如上所述,为做到这一点,数据库不能关闭 pstmt。在该示例中,第一个参数被设置为 "Hi"并保持为常数。在 for 循环中,每次都将第二个参数设置为不同的值:从 0 开始,到 9 结束。


pstmt.setString(1, "Hi");

for (int i = 0; i < 10; i++) {

pstmt.setInt(2, i);

int rowCount = pstmt.executeUpdate();

}


3、IN 参数中数据类型的一致性

setXXX 方法中的 XXX 是 Java 类型。它是一种隐含的 JDBC 类型(一般 SQL 类型),因为驱动程序将把 Java 类型映射为相应的 JDBC 类型(遵循该 JDBCGuide中§8.6.2 “映射 Java 和 JDBC 类型”表中所指定的映射),并将该 JDBC 类型发送给数据库。例如,以下代码段将 PreparedStatement 对象 pstmt 的第二个参数设置为 44,Java 类型为 short:

pstmt.setShort(2, 44);