20155327《Java程序设计》第八周学习总结
教材学习内容总结
第12章

进程与线程
进程的完成过程:代码加载、执行至执行完毕
线程:一个进程由多个线程组成。
线程的完成过程:自身的产生、存在和消亡
关系:没有进程就不会有线程
线程是运行在进程中的小线程。
线程
多线程:几个执行体共同执行程序的过程。
注意:计算机在任何给定的时刻只能执行那些线程中的一个。
建立多线程机制:Java虚拟机快速地把控制从一个线程切换到另一个线程,这些线程被轮流执行,每个线程都有机会使用CPU资源。
主线程:JVM加载代码时,发现main方法之后启动的线程
线程的状态:
新建
运行:使用start()方法
中断
死亡
线程的创建
两种方式:
使用Thread类子类创建:需要重写run()方法。
使用Thread类
构造方法:Thread(Runable target)
需要创建一个Runnable接口类的事例,并在该接口中重写run方法。
目标对象与线程的关系:完全解耦和目标对象组合线程
线程中的常用方法:
start():注意使用start()方法后不必再让线程调用start()方法。
run():Thread子类中重写run()或在Runnable接口中编写run()
sleep(int millsecond):使进程休眠。
注意:参数millsecond是以毫秒为单位的休眠时间
必须在try-catch语句块中调用sleep方法
4.isAlive():线程没有进入死亡状态,调用isAlive()方法返回true
线程进入死亡状态后,调用isAlive()方法返回false
5.currentThread():返回正在使用CPU线程的线程。
6.interrupt():解除线程的休眠状态。
线程同步: 程序中的若干个线程都需要使用一个方法,而这个方法用synchronized给予了修饰。
线程同步机制:线程A使用synchronized方法时,其他线程想使用这个synchronized方法必须等待,直到线程A使用完该synchronized方法。
协调同步的线程:
1.wait():在同步方法中使用,使本线程等待,暂时让出CPU的使用权。
2.notifyAll():通知所有由于使用这个同步方法而处于等待的线程结束等待,曾中断的线程就会从刚才的中断处继续执行这个同步方法。
3.notify():通知处于等待中的线程的某一个结束等待。
++必须在同步方法中使用这三种方法++

线程联合
join():其他线程调用该方法,可以和正在使用CPU资源的线程联合。
问题解决:
报错如下:
Port 443 in use by “C:\Linux\vm\vmware-hostd.exe -u “C:\ProgramData\VMware\hostd\config.xml”” with PID 3696!
.将 vmware-hostd.exe 的自动启动改为手动启动并将其停止。在桌面的计算机图标点击鼠标右键,选择 “管理→服务和应用程序→服务”,将显示名称为“VMware Workstation Server”的服务的启动类型改为手动,并停止该服务即可。

GUI线程
计时器线程:使用Time类
守护线程:使用void setDaemon(boolean on)方法

代码托管

上周考试错题总结
Q1:接口RowSet继承了接口__,可以调用RowSet中的方法__来填充其数据区。
①Statement ②ResultSet ③update ④populate
A . ①③
B . ①④
C . ②③
D . ②④

A1:正解:C
解析:与ResultSet相比较,
(1)RowSet扩展了ResultSet接口,因此可以像使用ResultSet一样使用RowSet。

  (2)RowSet扩展了ResultSet接口,因此功能比ResultSet更多、更丰富。

  (3)默认情况下,所有 RowSet 对象都是可滚动的和可更新的。而ResultSet是只能向前滚动和只读的。

  (4)RowSet可以是非链接的,而ResultSet是连接的。因此利用CacheRowSet接口可以离线操作数据。

  (5)RowSet接口添加了对 JavaBeans 组件模型的 JDBC API 支持。rowset 可用作可视化Bean开发环境中的 JavaBeans 组件。

  (6)RowSet采用了新的连接数据库的方法。
  update常用于更新数据。

实践测试:

实践一

教材p332 Example11_1

  1. 修改数据库的表R1001改为R+自己学号后四位,张三改为自己姓名
  2. 提交运行结果截图

实践步骤:

1.修改数据库表

2.运行代码:

遇见问题

运行xampp时报错如下:
Port 443 in use by “C:\Linux\vm\vmware-hostd.exe -u “C:\ProgramData\VMware\hostd\config.xml”” with PID 3696!

解决方法:
.将 vmware-hostd.exe 的自动启动改为手动启动并将其停止。在桌面的计算机图标点击鼠标右键,选择 “管理→服务和应用程序→服务”,将显示名称为“VMware Workstation Server”的服务的启动类型改为手动,并停止该服务即可

开启成功:

实践二:

. 下载附件中的world.sql.zip, 参考http://www.cnblogs.com/rocedu/p/6371315.html#SECDB,导入world.sql,提交导入成功截图
2. 编写程序,查询世界上超过“你学号前边七位并把最后一位家到最高位,最高位为0时置1”(比如学号20165201,超过3016520;学号20165208,超过1016520)的所有城市列表,提交运行结果截图
3. 编写程序,查询世界上的所有中东国家的总人口
4. 编写程序,查询世界上的平均寿命最长和最短的国家

实践过程:

1.导入world.sql

2.编写代码:
查询世界上超过“你学号前边七位并把最后一位家到最高位,最高位为0时置1”(比如学号20165201,超过3016520;学号20165208,超过1016520)的所有城市列表

/**
 * Created by lz50 on 2018/6/14.
 */
import java.sql.*;
public class test2_1 {
    public static void main(String args[]) {
        Connection con=null;
        Statement sql;
        ResultSet rs;
        try{  Class.forName("com.mysql.jdbc.Driver"); //加载JDBC_MySQL驱动
        }
        catch(Exception e){}
        String uri = "jdbc:mysql://localhost:3306/world?useSSL=true";
        String user ="root";
        String password ="";
        try{
            con = DriverManager.getConnection(uri,user,password); //连接代码
        }
        catch(SQLException e){ }
        try {
            sql=con.createStatement();
            rs=sql.executeQuery("SELECT * FROM city"); //查询mess表
            while(rs.next()) {
                int id=rs.getInt(1);
                String name=rs.getString(2);
                String countrycode=rs.getString(3);
                String district=rs.getString(4);
                int population=rs.getInt(5);
                if(population>9015532){    //20155327
                    System.out.printf("%d\t",id);
                    System.out.printf("%s\t",name);
                    System.out.printf("%s\t",countrycode);
                    System.out.printf("%s\t",district);
                    System.out.printf("%d\n",population);
                }
            }
            con.close();
        }
        catch(SQLException e) {
            System.out.println(e);
        }
    }
}

查询人口:

import java.sql.*;
public class test2_2 {
    public static void main(String [] args) {
        Connection con=null;
        Statement sql;
        ResultSet rs;
        String sqlStr = "select * from country where Region = 'Middle East'";
        try{  Class.forName("com.mysql.jdbc.Driver"); //加载JDBC_MySQL驱动
        }
        catch(Exception e){}
        String uri = "jdbc:mysql://localhost:3306/world?useSSL=true";
        String user ="root";
        String password ="";
        try{
            con = DriverManager.getConnection(uri,user,password); //连接代码
        }
        catch(SQLException e){ }
        try {
            sql=con.createStatement();
            rs = sql.executeQuery(sqlStr);
            int sum=0;
            while(rs.next()) {
                int population=rs.getInt(7);
                sum =sum+population;
            }
            System.out.printf("中东国家的总人口为:"+sum);
            con.close();
        }
        catch(SQLException e) {
            System.out.println(e);
        }
    }
}

查询世界上的平均寿命最长和最短的国家

import java.sql.*;
public class test2_3 {
    public static void main(String [] args) {
        Connection con=null;
        Statement sql;
        ResultSet rs;
        float smzd=1000.0f,smzc=0.0f;
        String c=new String("");
        String d=new String("");
        String sqlStr =
                "select * from country order by LifeExpectancy";
        try{  Class.forName("com.mysql.jdbc.Driver"); //加载JDBC_MySQL驱动
        }
        catch(Exception e){}
        String uri = "jdbc:mysql://localhost:3306/world?useSSL=true";
        String user ="root";
        String password ="";
        try{
            con = DriverManager.getConnection(uri,user,password); //连接代码
        }
        catch(SQLException e){ }
        try {
            sql=con.createStatement();
            rs = sql.executeQuery(sqlStr);
            while(rs.next()) {
                String Name=rs.getString(2);
                Float LifeExpectancy=rs.getFloat(8);
                if(LifeExpectancy>smzc) {
                    smzc =LifeExpectancy;
                    c =Name;
                }
                else if(LifeExpectancy<smzd){
                    {
                        smzd = LifeExpectancy;
                        d = Name;
                    }
                }

            }
            con.close();
            System.out.printf("世界上平均寿命最长的国家为:"+c+",平均寿命为:"+smzc+"\n");
            System.out.printf("世界上平均寿命最短的国家为:"+d+",平均寿命为:"+smzd+"\n");
        }
        catch(SQLException e) {
            System.out.println(e);
        }
    }
}

代码分析

Example11_1

import java.sql.*; 
public class Example11_1 {
   public static void main(String args[]) {
      Connection con=null;
      Statement sql; 
      ResultSet rs;
      try{  Class.forName("com.mysql.jdbc.Driver"); //加载JDBC_MySQL驱动
      }
      catch(Exception e){}
      String uri = "jdbc:mysql://localhost:3306/students?useSSL=true";
      String user ="root";
      String password ="";
      try{  
         con = DriverManager.getConnection(uri,user,password); //连接代码
      }
      catch(SQLException e){ }
      try { 
          sql=con.createStatement();
          rs=sql.executeQuery("SELECT * FROM mess"); //查询mess表
          while(rs.next()) {//当存在下一个数据是返回true
             String number=rs.getString(1);//将表第一列的数据传给number
             String name=rs.getString(2);
             Date date=rs.getDate(3);
             float height=rs.getFloat(4);
             System.out.printf("%s\t",number);
             System.out.printf("%s\t",name);
             System.out.printf("%s\t",date); 
             System.out.printf("%.2f\n",height);
          }
          con.close();//关闭连接
      }
      catch(SQLException e) { 
         System.out.println(e);
      }
  }
}

这个代码是用来查询student数据库中的mess表的全部记录。
Example11_2

import java.sql.*; 
public class Example11_2 {
   public static void main(String args[]) {
      Connection con;
      Statement sql; 
      ResultSet rs;
      con = GetDBConnection.connectDB("students","root","");
      if(con == null ) return;
      try { 
          sql=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                                    ResultSet.CONCUR_READ_ONLY);
          rs = sql.executeQuery("SELECT * FROM mess ");
          rs.last();
          int max = rs.getRow();
          System.out.println("表共有"+max+"条记录,随机抽取2条记录:");
          int [] a =GetRandomNumber.getRandomNumber(max,2);//得到1-max之间2个不同随机数
          for(int i:a){
             rs.absolute(i);//油标移动到第i行
             String number = rs.getString(1);
             String name = rs.getString(2);
             Date date = rs.getDate(3);
             float h = rs.getFloat(4);
             System.out.printf("%s\t",number);
             System.out.printf("%s\t",name);
             System.out.printf("%s\t",date); 
             System.out.printf("%.2f\n",h);
          }
          con.close();
      }
      catch(SQLException e) { 
         System.out.println(e);
      }
  }
}
import java.sql.*; 
public class GetDBConnection {
   public static Connection connectDB(String DBName,String id,String p) {
      Connection con = null;
      String 
      uri = "jdbc:mysql://localhost:3306/"+DBName+"?useSSL=true&characterEncoding=utf-8";
      try{  Class.forName("com.mysql.jdbc.Driver");//加载JDBC-MySQL驱动
      }
      catch(Exception e){}
      try{  
         con = DriverManager.getConnection(uri,id,p); //连接代码
      }
      catch(SQLException e){}
      return con;
   }
}
import java.util.*;
public class GetRandomNumber {
   public static int [] getRandomNumber(int max,int amount) {
      //1-max之间的amount个不同随机整数
     int [] randomNumber = new int[amount];
     int index =0;
     randomNumber[0]= -1;
     Random random = new Random();
     while(index<amount){
       int number = random.nextInt(max)+1;
       boolean isInArrays=false;
       for(int m:randomNumber){//m依次取数组randomNumber元素的值(见3.7)
          if(m == number)
            isInArrays=true;  //number在数组里了
       }
       if(isInArrays==false){
           //如果number不在数组randomNumber中:
           randomNumber[index] = number;
           index++;   
       }
     }
     return  randomNumber;
   }
}

将数据库单独分装在一个GetDatabaseConnection类中。随机查询student数据库中的mess表的两条记录。
Example11_3

import java.sql.*; 
public class Example11_3 {
   public static void main(String args[]) {
      Connection con;
      Statement sql; 
      ResultSet rs;
      con = GetDBConnection.connectDB("students","root","");
      if(con == null ) return;
      String c1=" year(birthday)<=2000 and month(birthday)>7";//条件1
      String c2=" name Like '张_%'";
      String c3=" height >1.65";
      String sqlStr =
      "select * from mess where "+c1+" and "+c2+" and "+c3+"order by birthday";
      try { 
          sql=con.createStatement();
          rs = sql.executeQuery(sqlStr);
          while(rs.next()) { 
             String number=rs.getString(1);
             String name=rs.getString(2);
             Date date=rs.getDate(3);
             float height=rs.getFloat(4);
             System.out.printf("%s\t",number);
             System.out.printf("%s\t",name);
             System.out.printf("%s\t",date); 
             System.out.printf("%.2f\n",height);
          }
          con.close();
      }
      catch(SQLException e) { 
         System.out.println(e);
      }
  }
}
import java.sql.*; 
public class GetDBConnection {
   public static Connection connectDB(String DBName,String id,String p) {
      Connection con = null;
      String uri = 
     "jdbc:mysql://localhost:3306/"+DBName+"?useSSL=true&characterEncoding=utf-8";
      try{  Class.forName("com.mysql.jdbc.Driver");//加载JDBC-MySQL驱动
      }
      catch(Exception e){}
      try{  
         con = DriverManager.getConnection(uri,id,p); //连接代码
      }
      catch(SQLException e){}
      return con;
   }
}

这个代码是查询mess表中姓张,身高大于16.5,出生年份为2000或2000年之前,月份在七月份之后的学生,并按出生日期排序。
Example11_4

import java.sql.*; 
public class Example11_4 {
   public static void main(String args[]) {
      Connection con;
      Statement sql; 
      ResultSet rs;
      con = GetDBConnection.connectDB("students","root","");
      if(con == null ) return;
      String jiLu="('R11q','王三','2000-10-23',1.66),"+
                  "('R10q','李武','1989-10-23',1.76)";    //2条记录
      String sqlStr ="insert into mess values"+jiLu;
      try { 
          sql=con.createStatement(); 
          int ok = sql.executeUpdate(sqlStr);
          rs = sql.executeQuery("select * from mess");
          while(rs.next()) { 
             String number=rs.getString(1);
             String name=rs.getString(2);
             Date date=rs.getDate(3);
             float height=rs.getFloat(4);
             System.out.printf("%s\t",number);
             System.out.printf("%s\t",name);
             System.out.printf("%s\t",date); 
             System.out.printf("%.2f\n",height);
          }
          con.close();
      }
      catch(SQLException e) { 
         System.out.println("记录中number值不能重复"+e);
      }
  }
}

这个代码是在mess表中插入两条记录。
Example11_5

import java.sql.*; 
public class Example11_5 {
   public static void main(String args[]) {
      Connection con;
      PreparedStatement preSql;  //预处理语句对象preSql
      ResultSet rs;
      con = GetDBConnection.connectDB("students","root","");
      if(con == null ) return;
      String sqlStr ="insert into mess values(?,?,?,?)";
      try { 
          preSql = con.prepareStatement(sqlStr);//得到预处理语句对象preSql
          preSql.setString(1,"A001");       //设置第1个?代表的值
          preSql.setString(2,"刘伟");       //设置第2个?代表的值
          preSql.setString(3,"1999-9-10"); //设置第3个?代表的值
          preSql.setFloat(4,1.77f);        //设置第4个?代表的值   
          int ok = preSql.executeUpdate();
          sqlStr="select * from mess where name like ? ";
          preSql = con.prepareStatement(sqlStr);//得到预处理语句对象preSql
          preSql.setString(1,"张%");       //设置第1个?代表的值
          rs = preSql.executeQuery();
          while(rs.next()) { 
             String number=rs.getString(1);
             String name=rs.getString(2);
             Date date=rs.getDate(3);
             float height=rs.getFloat(4);
             System.out.printf("%s\t",number);
             System.out.printf("%s\t",name);
             System.out.printf("%s\t",date); 
             System.out.printf("%.2f\n",height);
          }
          con.close();
      }
      catch(SQLException e) { 
         System.out.println("记录中number值不能重复"+e);
      }
  }
}
import java.sql.*; 
public class GetDBConnection {
   public static Connection connectDB(String DBName,String id,String p) {
      Connection con = null;
      String uri = 
     "jdbc:mysql://localhost:3306/"+DBName+"?useSSL=true&characterEncoding=utf-8";
      try{  Class.forName("com.mysql.jdbc.Driver");//加载JDBC-MySQL驱动
      }
      catch(Exception e){}
      try{  
         con = DriverManager.getConnection(uri,id,p); //连接代码
      }
      catch(SQLException e){}
      return con;
   }
}

此代码是使用预处理语句向mess表添加并查询了姓张的记录
Example11_6

import javax.swing.*;
public class Example11_6 {
   public static void main(String args[]) {
  String [] tableHead;
  String [][] content; 
  JTable table ;
  JFrame win= new JFrame();
  Query findRecord = new  Query();
  findRecord.setDatabaseName("students");
  findRecord.setSQL("select * from mess");
  content = findRecord.getRecord();
  tableHead=findRecord.getColumnName();
  table = new JTable(content,tableHead); 
  win.add(new JScrollPane(table));
  win.setBounds(12,100,400,200);
  win.setVisible(true); 
  win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
}
import java.sql.*;
public class Query {
   String databaseName="";      //数据库名
   String SQL;              //SQL语句
   String [] columnName;        //全部字段(列)名
   String [][] record;          //查询到的记录
   public Query() {
  try{  Class.forName("com.mysql.jdbc.Driver");//加载JDBC-MySQL驱动
  }
  catch(Exception e){}
   }
   public void setDatabaseName(String s) {
  databaseName=s.trim();
   }
   public void setSQL(String SQL) {
  this.SQL=SQL.trim();
   }
   public String[] getColumnName() {
   if(columnName ==null ){
       System.out.println("先查询记录");
       return null;
   }
   return columnName;
   }
   public String[][] getRecord() {
   startQuery();
   return record;
   }
   private void startQuery() { 
  Connection con;
  Statement sql;  
  ResultSet rs;
  String uri = 
 "jdbc:mysql://localhost:3306/"+
  databaseName+"?useSSL=true&characterEncoding=utf-8";
  try { 
    con=DriverManager.getConnection(uri,"root","");
    sql=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                            ResultSet.CONCUR_READ_ONLY);
    rs=sql.executeQuery(SQL);
    ResultSetMetaData metaData = rs.getMetaData();
    int columnCount = metaData.getColumnCount();//字段数目 
    columnName=new String[columnCount]; 
    for(int i=1;i<=columnCount;i++){
        columnName[i-1]=metaData.getColumnName(i);
    } 
    rs.last(); 
    int recordAmount =rs.getRow();  //结果集中的记录数目
    record = new String[recordAmount][columnCount];
    int i=0;
    rs.beforeFirst();
    while(rs.next()) { 
      for(int j=1;j<=columnCount;j++){
         record[i][j-1]=rs.getString(j); //第i条记录,放入二维数组的第i行
      }
      i++;
    }
    con.close();
  }
  catch(SQLException e) {
    System.out.println("请输入正确的表名"+e);
  }
   }    
}

这段代码的功能是将数据库名以及SQL语句传递给Query类的对象。
Example11_7

import java.sql.*; 
public class Example11_7{
    public static void main(String args[]){
       Connection con = null;
       Statement sql;
       ResultSet rs; 
       String sqlStr;
       con = GetDBConnection.connectDB("students","root","");
       if(con == null ) return;
       try{ float n = 0.02f;
            con.setAutoCommit(false);       //关闭自动提交模式
            sql = con.createStatement();
            sqlStr = "select name,height from mess where number='R1001'";
            rs = sql.executeQuery(sqlStr);
            rs.next();
            float h1 = rs.getFloat(2);
            System.out.println("事务之前"+rs.getString(1)+"身高:"+h1);
            sqlStr = "select name,height from mess where number='R1002'"; 
            rs = sql.executeQuery(sqlStr);
            rs.next();
            float h2 = rs.getFloat(2);
            System.out.println("事务之前"+rs.getString(1)+"身高:"+h2);  
            h1 = h1-n;
            h2 = h2+n;
            sqlStr = "update mess set height ="+h1+" where number='R1001'";
            sql.executeUpdate(sqlStr);
            sqlStr = "update mess set height ="+h2+" where number='R1002'";
            sql.executeUpdate(sqlStr);
            con.commit(); //开始事务处理,如果发生异常直接执行catch块
            con.setAutoCommit(true); //恢复自动提交模式
            String s = "select name,height from mess"+
                      " where number='R1001'or number='R1002'";
            rs = 
            sql.executeQuery(s);
            while(rs.next()){
               System.out.println("事务后"+rs.getString(1)+
                                  "身高:"+rs.getFloat(2));  
            }
            con.close();
         }
         catch(SQLException e){
            try{ con.rollback();          //撤销事务所做的操作
            }
            catch(SQLException exp){}
         }
    }
}
import java.sql.*; 
public class GetDBConnection {
   public static Connection connectDB(String DBName,String id,String p) {
      Connection con = null;
      String uri = 
     "jdbc:mysql://localhost:3306/"+DBName+"?useSSL=true&characterEncoding=utf-8";
      try{  Class.forName("com.mysql.jdbc.Driver");//加载JDBC-MySQL驱动
      }
      catch(Exception e){}
      try{  
         con = DriverManager.getConnection(uri,id,p); //连接代码
      }
      catch(SQLException e){}
      return con;
   }
}

这段代码的功能是将mess表中的number字段R1001的height值减少n,并将减少的n增加到字段是R1002的height上。
Example11_8

import java.sql.*;
public class Example11_8 {
   public static void main(String[] args) {
      Connection con =null;
      Statement sta = null;
      ResultSet rs;
      String SQL;
      try { 
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");//加载驱动
      }
      catch(Exception e) {
        System.out.println(e);  
        return;
      }
      try { 
         String uri ="jdbc:derby:students;create=true";
         con=DriverManager.getConnection(uri);  //连接数据库
         sta = con.createStatement();
      }
      catch(Exception e) {
        System.out.println(e);  
        return;
      }
      try { SQL = "create table chengji(name varchar(40),score float)";
            sta.execute(SQL);//创建表
      }
      catch(SQLException e) { 
         //System.out.println("该表已经存在"); 
      }
      SQL ="insert into chengji values"+
            "('张三', 90),('李斯', 88),('刘二', 67)";
      try {
         sta.execute(SQL);
         rs = sta.executeQuery("select * from chengji "); // 查询表中的记录
         while(rs.next()) {
            String name=rs.getString(1);
            System.out.print(name+"\t");
            float score=rs.getFloat(2);
            System.out.println(score);
         }
         con.close();
      } 
      catch(SQLException e) {
          System.out.println(e);  
      }
  }
}

这段代码的功能是使用了Derby数据库系统创建了名字是student的数据库,并在数据库中建立了chengji表

 posted on 2018-04-22 22:47  20155327李百乾-  阅读(258)  评论(0编辑  收藏  举报