从0开始学JAVA【3】


在这里插入图片描述

新建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

Thread

Runnable

Callable && Future

Callable产生结果,Future获取结果。


使用步骤如下:

创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值;

创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 
对象封装了该 Callable 对象的 call() 方法的返回值;

使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程;

调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
package com.company;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.*;

public class Task {
    public static void main(String[] args) throws Exception{
        Scanner input =new Scanner(System.in);
        int num=input.nextInt();
        Function f=new Function();
        f.runThread(num);
    }
}

 class Function {

    public void runThread(int num) {
// 在这里开启线程 获取线程执行的结果
        ThreadCallable tc=new ThreadCallable();
        tc.number=num;
        FutureTask<Integer> ft=new FutureTask<Integer>(tc);
        new Thread(ft).start();
        try{
            System.out.print("线程的返回值为:"+ft.get());
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

/* 在这里实现Callable接口及方法 */
class ThreadCallable implements Callable{
    public int number;

    public Integer call()throws Exception{
        int an;
        double a=(1+Math.sqrt(5))/2;
        double b=(1-Math.sqrt(5))/2;
        double c=1/(Math.sqrt(5));
        an=(int)(c*(Math.pow(a,number)-Math.pow(b,number)));
        return an;

    }

}


第2关:使用 Callable 和 Future 创建线程

package step2;
import java.util.concurrent.Callable;  
import java.util.concurrent.FutureTask;
public class Task {
    public void runThread(int num) {  
        // 在这里开启线程 获取线程执行的结果  
        //请在此添加实现代码  
/********** Begin **********/  
		Callable<Integer> callable = new ThreadCallable(num);  
        FutureTask<Integer> futureTask = new FutureTask<>(callable);  
        new Thread(futureTask).start();//开启线程  
        try {  
            Integer result = futureTask.get();  
            System.out.println("线程的返回值为:" + result);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }
/********** End **********/  
    }  
}
/********** Begin **********/  
/* 在这里实现Callable接口及方法 */  
class ThreadCallable implements Callable<Integer> {
    private int num;
    public ThreadCallable() {  
    }
    public ThreadCallable(int num) {  
        this.num = num;  
    }
    public Integer call() throws Exception {  
        int[] arr = new int[2];  
        arr[0] = 1;  
        arr[1] = 1;  
        for (int i = 2; i < num; i++) {  
            int tmp = arr[1];  
            arr[1] = arr[0] + arr[1];  
            arr[0] = tmp;  
        }  
        return arr[1];  
    }  
}
/********** End **********/

第1关:线程的状态与调度

在这里插入图片描述
在这里插入图片描述

第2关:常用函数(sleep/join)

package step2;
import java.util.*;
import java.util.Scanner;

public class Task {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		//请在此添加实现代码
     /********** Begin **********/
/**创建自定义线程,实现求第num项斐波那契数列的值num从0开始,
并且在main函数中获取子线程最终计算的结果。*/

    /********** End **********/
		Thread t = new MyThread(num);  
        t.start(); 
		try {  
            t.join();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
       // System.out.println("主线程结束");  
    }  			
}

		//请在此添加实现代码
   /********** Begin **********/
   /**创建自定义线程,实现求第num项斐波那契数列的值num从0开始*/
class MyThread extends Thread {  
    private int num;  
    public MyThread(int num) {  
        this.num = num;  
    }
    public void run() {  
       // System.out.println("子线程开始运行");  
        int a1=1;
		int a2=1;
		int a3=0;
		for (int i = 3; i <=num;i++) {
            a3=a2+a1;//2.根据前两个数算出第三个数
            a1=a2;//3.更新第一第二个数
            a2=a3;
		}
		System.out.println("子线程计算结果为:" + a3);  
            try {  
                Thread.sleep(30);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
  
        //System.out.println("子线程结束");  
		
    }  
}

   /********** End **********/


第3关:常用函数(wait/yield)

package step3;
//建立三个线程,A线程打印5次E,B线程打印5次D,C线程打印5次U,要求线程同时运行,交替打印5次EDU。
public class MyThread implements Runnable {   
	   //请在此添加实现代码
    private String name;     
    private Object prev;     
    private Object self; 

    private MyThread(String name, Object prev,Object self) {     
        this.name = name;     
        this.prev = prev;     
        this.self = self; 
        
    }     
    public void run() {     
        int count = 5;     
        while (count > 0) {     
            synchronized (prev) { 
                synchronized (self) {     
                    System.out.print(name);     
                        count--;    
                        self.notify();        
                    }     
                    try {     
                        prev.wait();    
                    } catch (InterruptedException e) {     
                        e.printStackTrace();     
                    }
                    
            }     
        }    
        System.exit(0);//退出jvm  
    }     
/********** Begin **********/
    public static void main(String[] args) throws Exception {   
        Object a = new Object();     
        Object b = new Object(); 
        Object c = new Object();

        MyThread ta = new MyThread("E", c,a);     
        MyThread tb = new MyThread("D", a,b); 
        MyThread tc = new MyThread("U", b,c); 
            
        new Thread(ta).start();  
        Thread.sleep(100);  //确保按顺序A、B执行  
        new Thread(tb).start();  
        Thread.sleep(100); 
        new Thread(tc).start();  
        Thread.sleep(100);    

    }   

/********** End **********/ 
   
}

在这里插入图片描述

3-6Java高级特性 - 多线程基础(3)线程同步

Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现大范围的原子性,可以通过synchronized和lock来实现,lock(锁)和synchronized(同步)在后面的关卡会介绍。
在这里插入图片描述

第2关:使用synchronized关键字同步线程

在Java中,每一个对象都有一个锁标记(monitor),也被称为监视器,当多个线程访问对象时,只有获取了对象的锁才能访问。
当某个线程访问这个对象synchronized方法或者代码块时,就获取到了这个对象的锁,
在这里插入图片描述

第3关:使用线程锁(Lock)实现线程同步

Lock不是Java语言内置的,而是一个类。
使用Lock必须在try{}catch{}块中进行,并且将释放锁的操作放在finally块中进行,以保证锁一定被被释放,防止死锁的发生。

Lock lock = ...;  
if(lock.tryLock()) {  
     try{  
         //处理任务  
     }catch(Exception ex){  
     }finally{  
         lock.unlock();   //释放锁  
     }   
}else {  
    //如果不能获取锁,则直接做其他事情  
} 

tryLock()顾名思义,是用来尝试获取锁的,并且该方法有返回值,表示获取成功与否,获取成功返回true,失败返回false,从方法可以发现,该方法如果没有获取到锁时不会继续等待的,而是会直接返回值。
lock()实现同步呢?相信你已经想到了,只要将Lock定义成全局变量

package step3;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Task {

	public static void main(String[] args) {
		final Insert insert = new Insert();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				insert.insert(Thread.currentThread());
			}
		});

		Thread t2 = new Thread(new Runnable() {
			public void run() {
				insert.insert(Thread.currentThread());
			}
		});

		Thread t3 = new Thread(new Runnable() {
			public void run() {
				insert.insert(Thread.currentThread());
			}
		});
		// 设置线程优先级
		t1.setPriority(Thread.MAX_PRIORITY);
		t2.setPriority(Thread.NORM_PRIORITY);
		t3.setPriority(Thread.MIN_PRIORITY);

		t1.start();
		t2.start();
		t3.start();

	}
}

class Insert {

	public static int num;

	// 在这里定义Lock
	private Lock lock = new ReentrantLock();
	public void insert(Thread thread) {
		/********* Begin *********/
		lock.lock();
		try{
			System.out.println(thread.getName()+"得到了锁"); 
			for (int i = 0; i < 5; i++) {
			num++;
			System.out.println(num);
			}
		}catch (Exception e){
		}finally{
			 System.out.println(thread.getName()+"释放了锁");  
            lock.unlock();
		}	
		/********* End *********/
	}

}

第4关:使用volatile实现变量的可见性

volatile是干啥用的,有什么含义和特点呢?

当一个共享变量被volatile修饰时,它就具备了“可见性”,即这个变量被一个线程修改时,
这个改变会立即被其他线程知道。

当一个共享变量被volatile修饰时,会禁止“指令重排序”。

中断线程一般都会采用下面代码

//线程1  
boolean stop = false;  
while(!stop){  
    doSomething();  
}  
//线程2  
stop = true;  

3-7Java高级特性 - 多线程练习题

顺序输出

package step1;
public class Task {
	public static void main(String[] args) throws Exception {
		/********* Begin *********/
		//在这里创建线程, 开启线程
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();
		MyThread ta = new MyThread("A",c,a);
		MyThread tb = new MyThread("B",a,b);
		MyThread tc = new MyThread("C",b,c);
		ta.start();
		ta.sleep(100);
		tb.start();
		tb.sleep(100);
		tc.start();
		tc.sleep(100);
		/********* End *********/
	}
}
class MyThread extends Thread {
	/********* Begin *********/
	private String threadName;
	private Object prev;
	private Object self;
	public MyThread(String name,Object prev,Object self){
		this.threadName = name;
		this.prev = prev;
		this.self = self;
	}
	public void run() {
		int count = 5;
		while(count>0){
			synchronized(prev){
				synchronized(self){
					System.out.println("Java Thread"+this.threadName+this.threadName);
					count--;
					self.notify();
				}
				try {
                    prev.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
				}
			}
		}
		System.exit(0);
	}
	/********* End *********/
}

售票问题

package step2;

/********* Begin *********/
import java.util.concurrent.locks.ReentrantLock;

//定义站台类,实现卖票的功能。
public class Station extends Thread {
	private static ReentrantLock lock = new ReentrantLock();
	private static int ticket = 20;

	@Override
	public void run() {

		while (true) {
			try {
				lock.lock();

				if (ticket > 0) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e1) {
						// TODO 自动生成的 catch 块
						e1.printStackTrace();
					}
					System.out.println("卖出了第" + ticket + "张票");
					ticket--;
				} else {
					System.out.println("票卖完了");
					System.exit(0);
				}

			} finally {

				lock.unlock();

			}

		}
	}

}
/********* End *********/


3-8Java高级特性 - Java反射’

三种获取Class类型的实例的方法;

通过Object类中的getClass()方法;

通过静态方法Class.forName(“全类名”);

通过类字面常量Class.class。

第1关:了解 Class 对象

package step1;

/**
 * 学员任务文件
 */
public class Reflect_stu {

    public static void main(String[] args) {
        System.out.println("通过Object 类中的 getClass() 获取的 Class 对象为:" + getPersonClass1());
        System.out.println("通过静态方法 Class.forName() 获取的 Class 对象为:" + getPersonClass2());
        System.out.println("通过类字面常量获取 Class 的对象为:" + getPersonClass3());
    }

    /**
     * 通过 Object 类中的 getClass() 获取的 Class 对象
     *
     * @return
     */
    public static Class getPersonClass1() {
        /********** Begin *********/
    

        return new Person().getClass();
        /********** End *********/
    }

    /**
     * 通过静态方法 Class.forName() 获取的 Class 对象
     * <p>
     * 注意:Person 类的全路径为: step1.Person
     *
     * @return
     */
    public static Class getPersonClass2() {
        /********** Begin *********/

        Class clazz = null;  
        String className = "step1.Person";  
        try {  
            clazz = Class.forName(className);  
            } catch(ClassNotFoundException e) {
        } 

        return clazz;
        /********** End *********/
    }

    /**
     * 通过类字面常量获取 Class 的对象
     *
     * @return
     */
    public static Class getPersonClass3() {
        /********** Begin *********/


        return Person.class;
        /********** End *********/
    }
}

第2关:利用反射分析类的能力

反射的基本概念

反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

提示:

Method.getReturnType()可以获得方法的返回类型。

打印方法或域的修饰符可以调用提供的printModifiers()方法

打印方法的参数可以调用提供的printParamTypes()方法

Field的getType方法可以获得域类型、getName方法可以获得域的名称

java.lang.reflect包中有三个类Field、Method和Constructor分别用于描述类的域、方法和构造器。
Class类中的getFields()、getMethods()和getConstructors()方法将分别返回类提供的 public 域、方法和构造器,其中包括超类的共有成员。
Class类中的getDeclareFields()、getDeclareMethods()和getDeclareConstructors()方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护的成员,但不包括超类的成员。

package step2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

class Apple {
    private String name;
    public Apple(){}
    public Apple(String name){}
    public void setName(String name) {
        this.name = name;
    }
}

public class Reflect_stu {

    public static void main(String[] args) {
        // 请根据提供的 classPath 获取 step2.Apple 的 Class 对象, 请使用 Class.forName() 方法, 注意捕获异常
        // 通关之后,你也可以修改 clasapath 为其他类路径,分析某个类的能力, 例如: java.util.Date
        String classPath = "step2.Apple";
        Class clazz = null;
        /********** Begin *********/

        try {
            clazz = Class.forName(classPath);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        
        /********** End *********/
        printFields(clazz);
        printConstructors(clazz);
        printMethods(clazz);
    }
    
  	/**
     * 请打印类的每个域,输出格式为:修饰符 类型 变量名;
     * @param clazz
     */
    public static void printFields(Class clazz) {
        /********** Begin *********/
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            // 获得描述域所属类型的Class对象
            Class type = field.getType();
            //获得域的名字
            String name = field.getName();
            // 获得域的描述符
            String modifiers = Modifier.toString(field.getModifiers());  
            if (modifiers.length() > 0) {  
                System.out.print(modifiers + " ");  
            }  
            System.out.println(type.getName() + " " + name + ";");
        }



        /********** End *********/
    }

    /**
     * 打印构造函数,输出格式为:修饰符 方法名称(参数)
     * @param clazz
     */
    public static void printConstructors(Class clazz) {
 		Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            Class[] paramTypes = null;
            /********** Begin *********/
            String name = constructor.getName();
            String modifiers = Modifier.toString(constructor.getModifiers());  
            if (modifiers.length() > 0) {  
                System.out.print(modifiers + " ");  
            }  
            System.out.print(name + "(");

            paramTypes = constructor.getParameterTypes();
            /********** End *********/
            printParamTypes(paramTypes);
        }
    }

    /**
     * 请针对每个方法打印其签名,格式为:修饰符 返回值类型 方法名称(参数);
     * @param clazz
     */
    public static void printMethods(Class clazz) {
        Method[] methos = clazz.getDeclaredMethods();
        for (Method method : methos) {
            Class[] paramTypes = null;
            /********** Begin *********/
            Class returnType = method.getReturnType();
            String name = method.getName();
            String modifiers = Modifier.toString(method.getModifiers());  
            if (modifiers.length() > 0) {  
                System.out.print(modifiers + " ");  
            }  
            System.out.print(returnType.getName() + " " + name + "(");
            //Class[] paramTypes = method.getParameterTypes();


            paramTypes = method.getParameterTypes();
            /********** End *********/
            printParamTypes(paramTypes);
        }
    }


    /**
     * 打印方法参数
     * @param paramTypes
     */
    private static void printParamTypes(Class[] paramTypes) {
        for (int j = 0; j < paramTypes.length; ++j) {
            if (j > 0) {
                System.out.print(",");
            }
            System.out.print(paramTypes[j].getName());
        }
        System.out.println(");");
    }
    
}

第3关:在运行时使用反射分析对象

如何通过 Field 类的 get 方法获取对象域

在这里插入图片描述

package step3;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Reflect_stu {

    public static String toString(Object obj) {
        Class cl = obj.getClass();
        String r = "";
        r += "[";

        // 请获取所有 Field 并设置访问权限为 true
        /********** Begin *********/
        Field[] fields = null;
        fields=cl.getDeclaredFields();
        AccessibleObject.setAccessible(fields, true);

        
        /********** End *********/
        for (Field f : fields) {
            // 此处 if,逻辑为判断 Field 域是否为非静态域
            if (!Modifier.isStatic(f.getModifiers())) {
                if (!r.endsWith("[")) r += ",";
                r += f.getName() + "=";
                try {
                    // 请获取域的类型及值
                    /********** Begin *********/     
                    Class t = null;
                    Object val = null;
                    t =f.getType();
                    val = f.get(obj);
                    /********** End *********/
                    // isPrimitive() 用于判断是否为基本数据类型,若为基础数据类型直接拼接,否则递归调用 toString 方法
                    if (t.isPrimitive()) r += val;
                    else r += toString(val);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        r += "]";
        return r;
    }


    public static void main(String[] args) {
        Person person = new Person(88, 19, 175);
        System.out.println(toString(person));
    }
}

class Person {
    public Integer weight;
    private Integer age;
    private Double height;


    public Person(Integer weight, Integer age, double height) {
        this.weight = weight;
        this.age = age;
        this.height = height;
    }
}

第4关:利用反射进行方法调用

通过反射创建对象

通过Class对象的newInstance()方法
第一种:通过Class对象的newInstance()方法。  

Class clazz = Apple.class;  
Apple apple = (Apple)clazz.newInstance();  
通过Constructor对象的 newInstance()方法
第二种:通过Constructor对象的newInstance()方法  

Class clazz = Apple.class;  
Constructor constructor = clazz.getConstructor();  
Apple apple = (Apple)constructor.newInstance();  

如何通过反射调用对象方法

// 获取类的 Class 对象实例  
Class clz = Class.forName("Apple");  
// 根据 Class 对象实例获取 Constructor 对象  
Constructor appleConstructor = clz.getConstructor();  
// 使用 Constructor 对象的 newInstance 方法获取反射类对象  
Object appleObj = appleConstructor.newInstance();
// 而如果要调用某一个方法,则需要经过下面的步骤:  
// 1、获取方法的 Method 对象  
Method setPriceMethod = clz.getMethod("setPrice", int.class);  
// 2、用 invoke 方法调用方法  
setPriceMethod.invoke(appleObj, 14);
class Apple {  
    public void setPrice(int price) {  
        //省略  
    }  
    // 省略  
}  
package step4;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**使用反射调用 Apple 类的 setPrice()方法,设置苹果价格为 14,并打印价格。接着还要用反射去调用getTotal方法获取单价为 20,数量 24 的总金额并打印。*/
public class Reflect_stu {
    public static void main(String[] args) throws InvocationTargetException {
        //使用反射调用
        Class clazz = null;
        try {
            // 获取类的 Class 对象实例 
            clazz = Class.forName("step4.Apple");
            /********** Begin *********/
            // 获取方法的 Method 对象
            Method setPriceMethod = clazz.getMethod("setPrice", double.class);
            // 根据 Class 对象实例获取 Constructor 对象  
            Constructor appleConstructor = clazz.getConstructor();
            // 使用 Constructor 对象的 newInstance 方法获取反射类对象
            Object apple = appleConstructor.newInstance();
            //用 invoke 方法调用方法
            setPriceMethod.invoke(apple, 14);
       

            Method getPriceMethod = clazz.getMethod("getPrice");
            System.out.println(getPriceMethod.invoke(apple));

            Method getTotal = clazz.getMethod("getTotal", double.class, int.class);
            System.out.println(getTotal.invoke(apple, 20, 24));
            /********** End *********/
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


class Apple {
    private double price;
    private int count;

    public Apple() {
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public double getTotal(double price, int count) {
        return price * count;
    }
}

3-9Java高级特性 - JDBC(上)

JDBC(Java DataBase Connectivity)是一种用于执行SQL语句的Java API,它由一组用Java语言编写的类和接口组成。换句话说:就是可以直接通过java语言,去操作数据库。

JDBC库包括常与数据库使用相关的API:
连接数据库;
创建SQL或MySQL语句;
在数据库中执行SQL或MySQL查询;
查看和修改结果记录。

第1关JDBC连接数据库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package jdbc;

import java.sql.*;

public class jdbcConn {
    public static void getConn() {
        /**********    Begin   **********/
        try {
			//1.注册驱动
            Class.forName("com.mysql.jdbc.Driver" );

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        /**********    End   **********/


        /**********    Begin   **********/
        Connection conn = null;
        Statement statement = null;
        //2.建立连接并创建数据库和表

        //建立数据库连接(Connection)一定要抛出异常
        try{
            String url = "jdbc:mysql://localhost:3306";
            conn = DriverManager.getConnection(url,"root","123123");  
        }catch(SQLException e){
             e.printStackTrace();  
        }
        
        // 创建执行SQL语句的Statement对象 
        try {  
            statement = conn.createStatement();  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        //创建数据库
        try {  
            String sql1="drop database if exists mysql_db";  
            String sql2="create database mysql_db";  
            statement.executeUpdate(sql1);//执行sql语句  
            statement.executeUpdate(sql2);  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        //创建表
        try {  
            statement.executeUpdate("use mysql_db");//选择在哪个数据库中操作  
            String sql = "create table student(" +  
                            "id int not null, " +  
                            "name varchar(20)," +
                            "sex varchar(4),"+
                            "age int "+
                            ")";  
            statement.executeUpdate(sql);  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }
        

        /**********    End   **********/
        //为确保资源释放代码能运行,资源释放代码一定要放在finally语句中。
        finally {
            try {
                if(statement!=null)
                    statement.close();
                if(conn!=null)
                    conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

第2关JDBC对表中数据的操作

package jdbc;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class jdbcInsert {
    public static void insert(){
		/**********   Begin  **********/
        try {
            //加载驱动
            Class.forName("com.mysql.jdbc.Driver" );

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
		/**********   End   **********/
		Connection conn = null;
		PreparedStatement statement = null;
		/**********   Begin  **********/
        //连接并插入数据
		try{
            String url = "jdbc:mysql://localhost:3306/mysql_db";  
            conn = DriverManager.getConnection (url,"root","123123");   
              
            statement = conn.prepareStatement("insert into student(id,name,sex,age) values(?,?,?,?)");//使用占位符来先占个位置 
           
            statement.setInt(1,1);
            statement.setString(2, "张三");
            statement.setString(3,"男");
            statement.setInt(4, 19);
            statement.executeUpdate();//每执行一个sql语句就需要执行该方法

            statement.setInt(1,2);
            statement.setString(2, "李四");
            statement.setString(3,"女");
            statement.setInt(4, 18);
            statement.executeUpdate();

            statement.setInt(1,3);
            statement.setString(2, "王五");
            statement.setString(3,"男");
            statement.setInt(4, 20);
            statement.executeUpdate();

            PreparedStatement statement1 = conn.prepareStatement("select * from      student");  
            ResultSet r = statement1.executeQuery();//将执行结果给ResultSet  
            while (r.next()) {//循环判断表中是否还有数据  
                System.out.println(r.getString(1)+" "+r.getString(2)+" "+
                r.getString(3)+" "+r.getString(4));//通过列的索引查询 
                //一行数据 
            }  

            	
		} catch (SQLException e) {
            e.printStackTrace();
        }
		/**********   End   **********/
		finally {
            try {
                if (statement != null)
                    statement.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

第3关JDBC事务

package jdbc;

import java.sql.*;

public class jdbcTransaction {

    public static void transaction(){
        try {
            Class.forName("com.mysql.jdbc.Driver" );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        Connection conn = null;
        PreparedStatement ps = null;
        /**********  Begin   **********/
        //连接数据库并开启事务
        try {
            String url = "jdbc:mysql://localhost:3306/mysql_db";  
            conn = DriverManager.getConnection (url,"root","123123" );  
            conn.setAutoCommit(false);//关闭自动提交开启事务 
           
            ps = conn.prepareStatement("insert into student(id,name,sex,age) values(?,?,?,?)");
            ps.setInt(1,4);
            ps.setString(2, "赵六");
            ps.setString(3,"女");
            ps.setInt(4, 21);
            ps.executeUpdate();
           
            conn.commit();//提交事务 

        } catch (SQLException e) {
            try {
                //事务回滚      
                conn.rollback();//回滚事务  回滚到你开始事务之前  

            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }
        /**********  End   **********/
        finally {
            try {
                if(ps!=null)
                    ps.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }
    }
}

3-10Java高级特性 - JDBC(下)

第1关指定类型JDBC封装

package step1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import test.News;

public class JDBCUtils {
	/**
	 * 连接数据库
	 */
	private static Connection getConnection() {
		Connection conn=null;
		/**********  Begin  **********/
		String url="jdbc:mysql://localhost:3306/mysql_db";
		try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection (url,"root","123123");
            
		}catch (ClassNotFoundException e) {
			e.printStackTrace();
		}catch (SQLException e) {
			e.printStackTrace();
		}
		/**********   End   **********/
		return conn;
	}
	
	/**
     * 更新数据方法
     * @param news
     * @throws SQLException
     */
    public void update(News news) throws SQLException {
        Connection conn = getConnection();
        PreparedStatement ps = null;
        /**********  Begin  **********/
        String sql = "update news set title = ? ,author_name = ? where id = ?";
        try{
            ps = conn.prepareStatement(sql);

			ps.setObject(1, news.getTitle());
			ps.setObject(2, news.getAuthor_name());
			ps.setObject(3, news.getId());

			ps.execute();
       
        }catch(SQLException e){
            e.printStackTrace();
            throw new SQLException("更新数据失败");
        }finally{
            close(null, ps, conn);
        }    
        /**********  End  **********/
    }
    
    /**
     * 查询所有数据
     * @return
     * @throws SQLException
     */
    public List<News> findAll() throws SQLException {
        Connection conn =  getConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;
        News news = null;
        List<News> newsList = new ArrayList<News>();
        /**********  Begin  **********/
        String sql = "select * from news";
		try {

			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();//将执行结果给ResultSet  

			while (rs.next()) {
				news = new News(rs.getInt(1), rs.getString(2), rs.getString(3));
				newsList.add(news);
			}
        
        }catch(SQLException e){
            e.printStackTrace();
            throw new SQLException("查询所有数据失败");
        }finally{
            close(rs, ps, conn);
        }
        /**********  End  **********/
        return newsList;
    }
	
	/**
	 * 删除方法
	 * @param id
	 * @throws SQLException
	 */
    public void delete(int id) throws SQLException{
        Connection conn = getConnection();
        PreparedStatement ps = null;
        /**********  Begin  **********/
        String sql = "delete from news where id=?";
		try {

			ps = conn.prepareStatement(sql);
			ps.setObject(1, id);
			ps.execute();
        
        }catch(SQLException e){
        	e.printStackTrace();
            throw new SQLException(" 删除数据失败");
        }
        finally{
            close(null, ps, conn);
        }        
        /**********  End  **********/
    }
    
    /**
     * 增加对象
     * @param news
     * @throws SQLException
     */
    public void insert(News news) throws SQLException {
        Connection conn = getConnection();
        PreparedStatement ps = null;
        String sql = "insert into news(id,title,author_name)values(?,?,?)";
        try{
            ps = conn.prepareStatement(sql);
            ps.setInt(1, news.getId());
            ps.setString(2, news.getTitle());
            ps.setString(3, news.getAuthor_name());
            ps.executeUpdate();
        }catch(SQLException e){
            e.printStackTrace();
            throw new SQLException("添加数据失败");
        }finally{
           close(null, ps, conn);
        }
    }
    
    /**
     * 根据id查询对象
     * @param id
     * @return
     * @throws SQLException
     */
    public News findById(int id) throws SQLException {
        Connection conn = getConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;
        News news = null;
        String sql = "select * from news where id=?";
        try{
            ps = conn.prepareStatement(sql);
            ps.setInt(1, id);
            rs = ps.executeQuery();
            if(rs.next()){
            	news = new News();
            	news.setId(id);
            	news.setTitle(rs.getString(2));
            	news.setAuthor_name(rs.getString(3));
            }
        }catch(SQLException e){
            e.printStackTrace();
            throw new SQLException("根据ID查询数据失败");
        }
        finally{
            close(rs, ps, conn);
        }
        return news;
    }
    
    /**
     * 关闭数据库连接
     * @param rs
     * @param ps
     * @param conn
     */
    public static void close(ResultSet rs,PreparedStatement ps,Connection conn){
    	try {
    		if(rs!=null)rs.close();
    		if(ps!=null)ps.close();
    		if(conn!=null)conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
    }
}	

第2关泛型JDBC封装

在这里插入图片描述
在这里插入图片描述

3-11JDBC基础编程练习

第1关JDBC更新员工密码

package step1;

import java.sql.*;

public class UpdatePass {
	// 修改数据
	public static void updateDB() {

		/********* Begin *********/

		// 第一步:加载驱动
		try {
			//1.注册驱动
            Class.forName("com.mysql.jdbc.Driver" );

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


		// 第二步:建立连接, "root"和"123123"是针对MySQL设置了用户名(root)和密码(123123)的情况
        Connection conn = null;
        Statement statement = null;
		// 127.0.0.1:3306是mysql服务器地址及端口   数据库编码格式设置为utf-8
        try{
            String url="jdbc:mysql://127.0.0.1:3306";
            conn = DriverManager.getConnection(url,"root","123123");
        }catch(SQLException e){
            e.printStackTrace();  
        }    

		// 第三步:建立statement对象
        try{
		    statement = conn.createStatement();  
		}catch(SQLException e){
             e.printStackTrace();  
        }

		// 第四步:修改数据
        try{
            statement.executeUpdate("use tsgc");
            String sql1="update employee set password='hello' where sex='女'"; 
            statement.executeUpdate(sql1);
        }catch(SQLException e){
             e.printStackTrace();  
        }
		// 第五步:关闭statement对象和连接对象
		finally {
            try {
                if(statement!=null)
                    statement.close();
                if(conn!=null)
                    conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }


		/********* End *********/
	}

}

第2关JDBC查询员工信息

package step1;

import java.sql.*;

public class QueryPass {
	
	// 查询数据代码不用上实验报告
	public static void queryDB() {
		
		/********* Begin *********/

		// 第一步:加载驱动
		try {
			//1.注册驱动
            Class.forName("com.mysql.jdbc.Driver" );

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
		

		// 第二步:建立连接, "root"和"123123"是针对MySQL设置了用户名(root)和密码(123123)的情况
		// 127.0.0.1:3306是mysql服务器地址及端口   数据库编码格式设置为utf-8
			
		Connection conn=null;
        Statement statement=null;

        try{
            String url="jdbc:mysql://127.0.0.1:3306";
            conn = DriverManager.getConnection(url,"root","123123");
        }catch(SQLException e){
            e.printStackTrace(); 
        }

		// 第三步:建立statement对象
		
		try{
		    statement = conn.createStatement();  
		}catch(SQLException e){
             e.printStackTrace();  
        }

		// 第四步:查询数据
		try{
            statement.executeUpdate("use tsgc");
            PreparedStatement statement1 = conn.prepareStatement("select * from      employee");  
            ResultSet r = statement1.executeQuery();//将执行结果给ResultSet  
            while (r.next()) {//循环判断表中是否还有数据  
                System.out.println("no:"+r.getString(1)+"	"
                                  +"name:"+r.getString(2)+"	"
                                  +"password:"+r.getString(3)+"	"
                                  +"sex:"+r.getString(4)+"	"
                                  +"salary:"+r.getFloat(5));//通过列的索引查询 
                //一行数据 
            }  
        }catch(SQLException e){
             e.printStackTrace();  
        }
		

		// 第五步:关闭statement对象和连接对象
		finally {
            try {
                if (statement != null)
                    statement.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    
		

		/********* End *********/
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值