201711671109《Java程序设计》第十一周总结(第11、12章)

本文详细介绍如何使用Java的JDBC API与MySQL数据库进行高效交互,包括连接数据库、执行查询、更新操作及预处理语句的使用。同时,探讨了Java多线程机制,包括线程的创建、状态管理、同步与协调等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

教材内容学习

 

11.1MySQL数据库管理系统

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS(Relational Database Management System,关系数据库管理系统) 应用软件。

MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

 

11.4JDBC

JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。

常用操作:1.与一个数据库建立连接 2.向已连接的数据库发送SQL语句 3.处理SQL语句返回的结果

 

11.5连接数据库

使用JDBC-数据库驱动方式和数据库建立连接需要建立两个步骤:

(1)加载JDBC-数据库驱动

(2)和指定的数据库建立连接

 

11.6查询操作

(1)向数据库发送SQL查询语句:

首先使用Statement声明一个SQL语句对象,然后让已创建的连接对象con调用方法createment()创建SQL语句对象

try{(Statement sql=con.createStatement();

}  catch (SQLException e) {}

(2)处理查询结果

在创建了查询对象后,就可以调用对应方法实现查询修改,并将结果存放在ResultSet类声明的对象中,按列组织的数据行,如:

ResultSet rs=sql.executeQuery(“Select *From student”); 结果rs列数4列,分别是number,name,birthday,height

(3)关闭连接

若连接对象被关系,则对象中的数据会马上消失。

1、顺序查询  

使用next()方法移到下一个数据行,移动成功返回true,否则false。

 

2、控制游标

游标的初始位置在结果集第一行的前面,调用next()方法移动游标。

若需要在结果集上下移动、显示结果集中的若条记录或随机显示若干条记录,则必须返回一个可滚动的结果集。例如:

获取一个对象:Statement stmt=con.createStatement(int type,int concurrency);

然后根据参数的取值情况返回相应的结果集:ResultSet re=rtmt.executeQuery(SQl语句)  type的取值决定滚动方式,见P333

 

3、条件与排序查询:

(1)where语句 :

select 字段  from 表明 where 条件

(2)排序

用order by子句对记录进行排序

 

11.7更新、添加、删除

(1)更新 update 表  set 字段 =新值  where<条件>

(2)添加 insert into 表(字段列表) values(记录)

(3)删除 delete from 表 where

 

11.8使用预处理语句

1、预处理语句的优点

可以事先将SQL语句解释为数据库底层执行命令,提高数据库访问速度

prepareStatement(String sql)进行预编译处理 ,生成底层命令

调用下列方法都可以使得该底层内部命令被数据库执行:

①ResultSet executeQuery()

②boolean execute()

③int executeUpdate()

 

2、使用通配符

通配符:可以代替字段的值,只需在预处理语句执行前设置具体值即可。

 

11.9通用查询

通用查询:一个可以用二维数组返回查询记录的类,需要知道数据库表的列名及列数。

 

代码编写:
Example11_6.java

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);
   }
}
 

Query.java

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);
      }
   }    
}

 

 

12.1进程与线程

1、进程:程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。

 

2、线程:比进程更小的执行单位,一个进程在其执行过程中,可以产生多个线程,形成多条执行线索。没有进程就没有线程。

 

12.2Java中的线程

1、主线程(main线程)

每个java程序都有一个缺省的主线程main;在执行java程序时候,多个线程轮流执行。

 

2、线程的状态

(1)新建

当一个thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。

在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口

(2)运行

用start()方法通知JVM加入新线程,并且重新线程中的run()方法,若线程是thread子类创建,则立即执行run()。

(3)中断

通常有4个原因:

①JVM将CPU资源从当前线程切换给其他线程,使本线程让出CPU的使用权处于中断状态。
②线程使用CPU资源期间执行了sleep方法,使当前线程进入休眠状态。
③线程使用CPU资源期间执行了wait( )方法,使得当前线程进入等待状态。
④线程使用CPU资源期间执行某个操作进入阻塞状态,比如执行读/写操作引起阻塞。

(4)死亡:死亡后就不具有继续运行的能力,通常有两个原因:

①正常运行的线程完成了他的全部工作

②被强制性终止,run方法被强制结束

 

4、线程调度与优先级:

java虚拟机中的线程调度器负责管理线程,调度器把线程的优先级分成10个级别,分别用thread类中的类变量表示。每个Java的线程的优先级通常在1(Thread.MIN_PRORITY)-10(Thread.MAX_PRORITY)之间,若没有明确设置线程的优先级别,则优先级为5,即(Thread.NORM_PRORITY).优先级可通过setPrority()调整。

 

12.3Thread类与线程的创建

1、创建线程对象有两种方法:

(1)使用Thread子类方法创建线程对象,需要重写父类中的Run()方法.。优点:可以在子类中增加新的成员变量,使线程具有某种属性,也可以新增方法,具有某种功能。

(2)直接用Thread方法创建。——Thread(Runnable target)参数是一个Runnable类型的参数。

 

2、目标线程与线程的关系:

①目标对象和线程完全解耦

②目标对象组合线程(弱耦合):可以将线程作为自己的成员

 

12.4线程常用的方法

(1)Start():线程调用该方法启动线程。注:调用后不能再调用。

(2)run():定义线程对象被调度之后执行的操作。

(3)Sleep(int millsecond):使线程休眠,休眠时间用参数决定。

(4)isAlive():在线程新建状态的时候,调用这个方法返回false;死亡后也是返回false;没死前调用返回true。

(5)currenThread():返回当前正在使用的线程

(6)interrupt():吵醒休眠的线程。

 

12.5线程同步

若干个线程都需要使用一个synchronized(同步)修饰的方法,及程序中的若干个线程都需要使用一个方法,而这个方法用synchronized给与了修饰。多个线程都必须遵守机制。

线程同步机制:当一个线程A使用synchronized方法时,其他方法想使用这个方法必须等待,直到A用完。

 

12.6协调同步的线程

当一个线程使用的同步方法中用到某个变量,而此变量又需要其他线程修改后才能符合本线程的需要,那么可以在同步方法中使用wait()方法。wait方法可以中断线程的执行使本线程等待,暂时让出CPU的使用权,并允许其他线程使用这个同步方法。在其他线程使用完这份方法后,用notifyAll()方法通知由于使用本方法而等待的线程结束等待。

注:wait()、nitify()和notifyAll()都是final方法,不允许继承,切不可以在非同步方法中使用这三方法。

 

12.7线程联合

在线程A占有资源期间,可以让其他线程调用join()和本线程联合,如:B.join();称A在运行期间联合了B。这样A的线程马上中断,直至B完成。

 

12.8GUI线程

在Java程序包括图形用户界面时候,虚拟机会启动更多线程如 AWT-EventQuecue和AWT-WIndows。

AWT-EventQuecue:处理GUI事件

AWT-WIndows:负责将窗体或组件绘制到桌面。

 

 

12.9计时器线程

计时器线程Timer:

构造方法:Timer(int a,Object b) 参数a是毫秒,b是计时器的监视器。

计时器次数设置:setRepeats(boolean b) b取false则只运行一次。

 

12.10守护线程

线程默认为非守护线程,称作user用户线程。调用void setDaemon(boolean on)方法将自己设置成一个守护线程。


代码编写

Example12_14.java

public class Example12_14 {
   public static void main(String args[]) {
      StandardExamInTime win=new StandardExamInTime();
      win.setTitle("限时回答问题");
      win.setTestFile(new java.io.File("test.txt"));
      win.setMAX(8); 
   }
}

 

StandardExamInTime.java

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class StandardExamInTime extends JFrame implements ActionListener,ItemListener{
   File testFile;
   int MAX = 8; 
   int maxTime = MAX,score=0;
   javax.swing.Timer time;  //计时器
   JTextArea  showQuesion; //显示试题
   JCheckBox choiceA,choiceB,choiceC,choiceD;
   JLabel showScore,showTime;
   String correctAnswer;   //正确答案
   JButton reStart;
   FileReader inOne;
   BufferedReader inTwo;
   StandardExamInTime(){
      time = new javax.swing.Timer(1000,this);
      showQuesion = new JTextArea(2,16);
      setLayout(new FlowLayout());
      showScore=new JLabel("分数"+score);
      showTime=new JLabel(" ");
      add(showTime);
      add(new JLabel("问题:")) ;
      add(showQuesion);
      choiceA =new JCheckBox("A");
      choiceB =new JCheckBox("B");
      choiceC =new JCheckBox("C"); 
      choiceD =new JCheckBox("D");
      choiceA.addItemListener(this);
      choiceB.addItemListener(this);
      choiceC.addItemListener(this);
      choiceD.addItemListener(this); 
      add(choiceA);
      add(choiceB);
      add(choiceC);
      add(choiceD);
      add(showScore); 
      reStart=new JButton("再做一遍");
      reStart.setEnabled(false);
      add(reStart);
      reStart.addActionListener(this);
      setBounds(100,100,200,200);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setVisible(true);
   } 
   public void setMAX(int n){
      MAX = n;
   }
   public void setTestFile(File f) {
      testFile = f;
      score=0;
      try{
         inOne = new FileReader(testFile);
         inTwo = new BufferedReader(inOne);
         readOneQuesion();
         reStart.setEnabled(false); 
      }
      catch(IOException exp){
         showQuesion.setText("没有选题");
      }
   }
   public void readOneQuesion() {
      showQuesion.setText(null);
      try {
           String s = null;
           while((s = inTwo.readLine())!=null) {
              if(!s.startsWith("-"))
                  showQuesion.append("\n"+s);
              else {
                  s = s.replaceAll("-",""); 
                  correctAnswer = s;
                  break;
              }
           }
           time.start();   //启动计时
           if(s==null) {
              inTwo.close();
              reStart.setEnabled(true);
              showQuesion.setText("题目完毕");
              time.stop();
           }
      } 
      catch(IOException exp){}
   }
   public void itemStateChanged(ItemEvent e) {
      JCheckBox box=(JCheckBox)e.getSource();
      String str=box.getText();
      boolean booOne=box.isSelected(); 
      boolean booTwo=str.compareToIgnoreCase(correctAnswer)==0;
      if(booOne&&booTwo){
           score++;
           showScore.setText("分数:"+score);
           time.stop();       //停止计时
           maxTime = MAX;
           readOneQuesion(); //读入下一道题目  
      }
      box.setSelected(false);
   }
   public void actionPerformed(ActionEvent e) {
      if(e.getSource()==time){
            showTime.setText("剩:"+maxTime+"秒");
            maxTime--;
            if(maxTime <= 0){
                maxTime = MAX;
                readOneQuesion(); //读入下一道题目
            }
      }
      else if(e.getSource()==reStart) {
         setTestFile(testFile);
      }
   }
}
 

教材学习中遇到的问题

 

学习进度条

 代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
目标5000行30篇400小时 
第二周180/9801/1115/101

JDBC与MySQL

Java多线程机制

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值