JavaWeb之JDBC(1.2):MySQL数据库的连接、PrepareStatement等代码演示

本文详细介绍了使用Java JDBC进行数据库通用增删改查(CRUD)操作的代码实现,包括从控制台输入数据到数据库表的插入,以及针对不同表的通用查询操作。此外,还探讨了PreparedStatement如何解决Statement的弊端,防止SQL注入,并演示了如何使用PreparedStatement进行高效的批量数据插入。

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

从控制台向数据库的表customers中插入一条数据及通用的增删改操作代码

package JavaWeb.JDBC.day2.exer;

import JavaWeb.JDBC.day2.util.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Scanner;

/**
 * @author 黄佳豪
 * @create 2019-08-03-19:19
 */
public class InsertDemo {
//练习1:从控制台向数据库的表customers中插入一条数据
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.println("id:");
        int id = s.nextInt();

        System.out.println("name:");
        String name = s.next();

        System.out.println("email:");
        String email = s.next();

        System.out.println("birth:");
        String birth = s.next();

        // 如果从控制台输入,编写一个sql语句
        String sql = "insert into customers(id,name,email,birth) values(?,?,?,?)";
        update(sql,id,name,email,birth);
        System.out.println("插入成功!");

    }

    // 通用的增删改操作
    public static void update(String sql, Object... args) {
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeResource(conn, ps, null);
        }

    }
}

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

MySQL对JDBC通用的增删改操作

package JavaWeb.JDBC.day2.exer;

import JavaWeb.JDBC.day2.bean.Student;
import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Scanner;

/**
 * @author 黄佳豪
 * @create 2019-08-03-19:21
 */
public class UniversalDemo {
    public static void main(String[] args) {
        UniversalDemo u = new UniversalDemo();
        u.testInsert();
    }
    // 3.删除(法二):较好!
    @Test
    public void testDelete1() {
        Scanner s = new Scanner(System.in);
        System.out.println("请输入学生的考号:");
        String examCard = s.next();
        String sql = "delete from examstudent where examcard = ?";

        boolean b = delete(sql,examCard);
        if (b) {
            System.out.println("删除成功!");
        } else {
            System.out.println("查无此人");
        }
    }

在这里插入图片描述
单元测试结果
在这里插入图片描述

    // 3.删除(法一)
    @Test
    public void testDelete() throws Exception {
        Scanner s = new Scanner(System.in);
        System.out.println("请输入学生的考号:");
        String examCard = s.next();
        String sql = "delete from examstudent where examcard = ?";

        String sql1 = "select Type type,IDCard IDCard,ExamCard examCard,Location location,StudentName studentName,Grade grade from examstudent"
                + " where examCard = ?";
        Student student = getInstance(Student.class,sql1,examCard);
        if (student != null) {
            update(sql,examCard);
            System.out.println("删除成功");
        } else {
            System.out.println("查无此人");
        }

    }

    // 2.查询(身份证号、准考证号)
    @Test
    public void testQuery() throws Exception {
        System.out.println("请选择您要输入的类型:\na:准考证号\nb:身份证号:");
        Scanner s = new Scanner(System.in);
        String type = s.next();

        if (type.equalsIgnoreCase("a")) {
            System.out.println("请输入准考证号:");
            String examCard = s.next();
            String sql = "select Type type,IDCard IDCard,ExamCard examCard,Location location,StudentName studentName,Grade grade from examstudent"
                    + " where examCard = ?";

            Student s1 = getInstance(Student.class,sql,examCard);

            if (s1 != null) {
                System.out.println(s1);
            } else {
                System.out.println("查无此人");
            }

        } else if (type.equalsIgnoreCase("b")) {
            System.out.println("请输入身份证号:");
            String IDCard = s.next();
            String sql = "select Type type,IDCard IDCard,ExamCard examCard,Location location,StudentName studentName,Grade grade from examstudent where IDCard = ?";

            Student s1 = getInstance(Student.class,sql,IDCard);

            if (s1 != null) {
                System.out.println(s1);
            } else {
                System.out.println("查无此人");
            }
        } else {
            System.out.println("您输入的信息有误!请重新进入");
        }
    }

在这里插入图片描述
单元测试结果
在这里插入图片描述

    // 1.向表中插入数据
    @Test
    public void testInsert() {
        Scanner s = new Scanner(System.in);
        System.out.println("type:");
        int type = s.nextInt();
        System.out.println("IDCard:");
        String idCard = s.next();
        System.out.println("examCard:");
        String examCard = s.next();
        System.out.println("StudentName:");
        String studentName = s.next();
        System.out.println("Location:");
        String location = s.next();
        System.out.println("Grade:");
        int grade = s.nextInt();

        String sql = "insert into examstudent(type,idcard,examcard,studentname,location,grade)"
                + "values(?,?,?,?,?,?)";

        update(sql,type,idCard,examCard,studentName,location,grade);
        System.out.println("录入成功!");
    }

在这里插入图片描述
单元测试结果
在这里插入图片描述

    //通用的查询
    public <T> T getInstance(Class<T> clazz,String sql,Object ... args) throws Exception{
        Connection conn = JDBCUtils.getConnection();
        PreparedStatement ps = conn.prepareStatement(sql);
        for(int i = 0;i < args.length;i++){
            ps.setObject(i + 1, args[i]);
        }

        ResultSet rs = ps.executeQuery();
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        if(rs.next()){
            T t = clazz.newInstance();
            for(int i = 0;i < columnCount;i++){
                Object columnVal = rs.getObject(i + 1);
                String columnLabel = rsmd.getColumnLabel(i + 1);

                Field field = clazz.getDeclaredField(columnLabel);
                field.setAccessible(true);
                field.set(t, columnVal);

            }
            return t;
        }

        JDBCUtils.closeResource(conn, ps, rs);

        return null;
    }

    // 通用的增删改操作
    public static void update(String sql, Object... args) {
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.closeResource(conn, ps, null);
        }

    }

    // 删除操作,返回是否有数据被删除
    public static boolean delete(String sql, Object... args) {
        // 1.获取数据库的连接
        Connection conn = null;
        // 2.获取一个PreparedStatement的对象
        PreparedStatement ps = null;
        try {
            conn = JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
            // 3.通过PreparedStatement的对象执行sql语句
            int i = ps.executeUpdate();
            if (i > 0) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 4.关闭操作
            JDBCUtils.closeResource(conn, ps, null);
        }
        return false;
    }
	}

通用的查询操作(customer表)

customer类准备:封装所有属性,提供空参带参构造器,重写tostring方法。
在这里插入图片描述

package JavaWeb.JDBC.day2.java;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import JavaWeb.JDBC.day2.bean.Customer;
import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;


/**
 * 针对于Customers表的通用查询操作
 * 通用:查询的字段个数、字段名不确定
 * @author Administrator
 */
public class CustomersQueryTest {

@Test
public void testGetInstance() {
	String sql = "select id ,name,birth from customers where name = ?";
	Customer customer = getInstance(sql,"周杰伦");
	System.out.println(customer);
}

在这里插入图片描述
单元测试结果
在这里插入图片描述
重点★

//Customers表的通用查询操作
public Customer getInstance(String sql,Object ... args) {

	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		// 1.获取连接
		conn = JDBCUtils.getConnection();
		// 2.预编译sql语句
		ps = conn.prepareStatement(sql);

		// 3.填充占位符
		for(int i = 0;i < args.length;i++) {
			ps.setObject(i + 1, args[i]);
		}

		// 4.调用executeQuery(),获取结果集
		rs = ps.executeQuery();
		
		//5.获取结果集的元数据
		ResultSetMetaData rsmd = rs.getMetaData();
		//6.获取结果集中列的个数
		int columnCount = rsmd.getColumnCount();
		
		// 5.处理结果集
		if (rs.next()) {// ①判断指针的下一个位置是否有数据 ②如果返回true,指针下移。如果返回false,指针不下移。
			Customer cust = new Customer();
			
			for(int i = 0;i < columnCount ;i++) {
				
				Object columnValue = rs.getObject(i + 1);//获取列值
				
				String columnLabel = rsmd.getColumnLabel(i + 1);//获取结果集中列的名称
				//反射
				Class clazz = Customer.class;
				Field field = clazz.getDeclaredField(columnLabel);
				field.setAccessible(true);
				field.set(cust, columnValue);
				
			}
			
			return cust;
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 7.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);

	}

	return null;
}

// 查询操作
/*
 * ORM的思想(object relational mapping) 
 * 一个数据表 与 一个java类对应 
 * 表中的一个列 与 java类的一个属性对应
 * 表中的一个行 与 java类的一个对象对应
 * 
 */
@Test
public void testQuery1() {
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		// 1.获取连接
		conn = JDBCUtils.getConnection();
		// 2.提供sql语句(包含占位符)
		String sql = "select id,name,email,birth from customers where id = ?";
		// 3.预编译sql语句
		ps = conn.prepareStatement(sql);

		// 4.填充占位符
		ps.setInt(1, 18);

		// 5.调用executeQuery(),获取结果集
		rs = ps.executeQuery();
		// 6.处理结果集
		if (rs.next()) {// ①判断指针的下一个位置是否有数据 ②如果返回true,指针下移。如果返回false,指针不下移。

			// int id = rs.getInt(1);
			// String name = rs.getString(2);
			// String email = rs.getString(3);
			// Date birth = rs.getDate(4);
			// 或者
			int id = rs.getInt("id");
			String name = rs.getString("name");
			String email = rs.getString("email");
			Date birth = rs.getDate("birth");

			// 方式一:
			// System.out.println("id : " + id + "name : " + name
			// + ",email : " + email + ",birth :" + birth);

			// 方式二:Object[] 不建议
			// 方式三:封装为对象
			Customer cust = new Customer(id, name, email, birth);
			System.out.println(cust);

		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 7.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);

	}
}	}

在这里插入图片描述

通用的查询操作(order表)

order类准备:封装所有属性,提供空参带参构造器,重写tostring方法。
在这里插入图片描述
order表
在这里插入图片描述

package JavaWeb.JDBC.day2.java;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

import JavaWeb.JDBC.day2.bean.Order;
import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;

/**
 * 针对于order表的查询操作
 */
public class OrderQueryTest {

/**
 * 如果表的字段名和类的属性名不一致,要求:
 * 查询的语句中,使用类的属性名作为字段的别名出现。
 */
@Test
public void testGetInstance() {
	
	String sql = "select order_id orderId,order_name orderName from `order` where order_id = ?";
	Order order = getInstance(sql, 1);
	System.out.println(order);
}

在这里插入图片描述
注意:此处若不使用别名就报错

// order表的通用查询操作
public Order getInstance(String sql, Object... args) {

	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		// 1.获取连接
		conn = JDBCUtils.getConnection();
		// 2.预编译sql语句
		ps = conn.prepareStatement(sql);

		// 3.填充占位符
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}

		// 4.调用executeQuery(),获取结果集
		rs = ps.executeQuery();

		// 5.获取结果集的元数据
		ResultSetMetaData rsmd = rs.getMetaData();
		// 6.获取结果集中列的个数
		int columnCount = rsmd.getColumnCount();

		// 5.处理结果集
		if (rs.next()) {// ①判断指针的下一个位置是否有数据 ②如果返回true,指针下移。如果返回false,指针不下移。
			Order order = new Order();

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

				Object columnValue = rs.getObject(i + 1);// 获取列值

				String columnLabel = rsmd.getColumnLabel(i + 1);// 获取结果集中列的别名 
				
				System.out.println(columnLabel);
				// 反射
				Class clazz = Order.class;
				Field field = clazz.getDeclaredField(columnLabel);
				field.setAccessible(true);
				field.set(order, columnValue);

			}

			return order;
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 7.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);

	}

	return null;
}

@Test
public void testQuery1() {
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		// 1.获取连接
		conn = JDBCUtils.getConnection();
		// 2.提供sql语句(包含占位符)
		// String sql = "select id,name,email,birth from customers where id = ?";
		String sql = "select order_id,order_name,order_date from `order` where order_id = ?";
		// 3.预编译sql语句
		ps = conn.prepareStatement(sql);

		// 4.填充占位符
		ps.setInt(1, 1);

		// 5.调用executeQuery(),获取结果集
		rs = ps.executeQuery();
		// 6.处理结果集
		if (rs.next()) {// ①判断指针的下一个位置是否有数据 ②如果返回true,指针下移。如果返回false,指针不下移。

			// int id = rs.getInt(1);
			// String name = rs.getString(2);
			// String email = rs.getString(3);
			// Date birth = rs.getDate(4);
			// 封装为对象
			// Customer cust = new Customer(id, name, email, birth);
			// System.out.println(cust);

			int orderId = rs.getInt(1);
			String orderName = rs.getString(2);
			Date orderDate = rs.getDate(3);

			Order order = new Order(orderId, orderName, orderDate);
			System.out.println(order);

		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 7.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);

	}
}
}

在这里插入图片描述

使用PreparedStatement实现数据表中数据的增删改操作★

package JavaWeb.JDBC.day2.java;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;


/**
 * 使用PreparedStatement实现数据表中数据的增删改操作。
 * 
 * 1.PreparedStatement 是 java.sql下定义的一个接口,是Statement的子接口
 * 
 * @author Administrator
 *
 */
public class PreparedStatementTest {

//测试
@Test
public void testCommonUpdate() {
//		String sql = "delete from customers where id = ?";
//		update(sql,20);
		String sql = "update `order` set order_name = ? where order_id = ?";
		update(sql,"MM","4");
	}

在这里插入图片描述
单元测试结果
在这里插入图片描述

// 使用PreparedStatement实现通用的增、删、改操作。
// 通用:① 增、删、改操作都可以使用 ② 针对于数据库下的不同的表都可以用
public void update(String sql, Object... args) {
	Connection conn = null;
	PreparedStatement ps = null;
	try {
		// 1.
		conn = JDBCUtils.getConnection();
		// 2.
		ps = conn.prepareStatement(sql);
		// 3.填充占位符
		for(int i = 0;i < args.length;i++) {
			ps.setObject(i + 1, args[i]);
		}
		
		// 4.执行
		int count = ps.executeUpdate();

		System.out.println("影响了" + count + "条数据");
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 6.
		JDBCUtils.closeResource(conn, ps,null);
	}

}

// 使用PreparedStatement实现数据的修改
@Test
public void testUpdate() {

	Connection conn = null;
	PreparedStatement ps = null;
	try {
		// 1.
		conn = JDBCUtils.getConnection();
		// 2.
		String sql = "update customers set email = ? where id >= ?";
		// 3.
		ps = conn.prepareStatement(sql);
		// 4.
		ps.setString(1, "yinfei@126.com");
		ps.setInt(2, 19);
		// 5.
		int count = ps.executeUpdate();

		System.out.println("修改了" + count + "条数据");
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 6.
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

在这里插入图片描述
单元测试结果
在这里插入图片描述

// 使用PreparedStatement实现数据的添加
@Test
public void testInsert() {

	Connection conn = null;
	PreparedStatement ps = null;
	try {
		// 1. 获取数据库的连接
		conn = JDBCUtils.getConnection();
		// 2.提供一个包含占位符的sql语句
		// ?:占位符
		String sql = "insert into customers(name,email,birth)values(?,?,?)";
		// 3. 调用Connection的方法,获取一个PreparedStatement:预编译sql语句
		ps = conn.prepareStatement(sql);
		// 4.填充占位符
		ps.setString(1, "银飞");
		ps.setString(2, "jinfei@126.com");
		ps.setDate(3, new Date(235432532532L));// 数据库中的Date 对应java中的java.sql.Date
		// 5.执行
		// ps.execute();
		// 返回修改的条数
		int count = ps.executeUpdate();
		System.out.println("添加了" + count + "条记录");

	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 6.资源的关闭
		if (conn != null) {

			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}

		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}
	}
}

在这里插入图片描述
单元测试结果
在这里插入图片描述

// 测试连接
@Test
public void testConnection() throws Exception {
	Connection conn = JDBCUtils.getConnection();
	System.out.println(conn);
}
}

针对于不同的表,使用PreparedStatement实现通过的查询操作

package JavaWeb.JDBC.day2.java;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import JavaWeb.JDBC.day2.bean.Customer;
import JavaWeb.JDBC.day2.bean.Order;
import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;


/**
 * 针对于不同的表,使用PreparedStatement实现通过的查询操作
 * @author Administrator

 * 体会: 两种思想:①面向接口编程 ②ORM思想 两种技术:
 * ① 结果集的元数据:ResultSetMetaData ② 反射的技术
 */
public class PreparedStatementTest1 {
	
	@Test
	public void testGetForList() {
		String sql = "select id,name,birth from customers where id < ?";
		List<Customer> list = getForList(Customer.class, sql, 12);
	
	list.forEach(System.out::println);

	}

在这里插入图片描述

	// 通用的查询,返回多条记录
	public <T> List<T> getForList(Class<T> clazz, String sql, Object... args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<T> list = new ArrayList<>();
		try {
			// 1.获取连接
			conn = JDBCUtils.getConnection();
			// 2.预编译sql语句
			ps = conn.prepareStatement(sql);

		// 3.填充占位符
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}

		// 4.调用executeQuery(),获取结果集
		rs = ps.executeQuery();

		// 5.获取结果集的元数据
		ResultSetMetaData rsmd = rs.getMetaData();
		// 6.获取结果集中列的个数
		int columnCount = rsmd.getColumnCount();

		// 7.处理结果集
		while (rs.next()) {// ①判断指针的下一个位置是否有数据 ②如果返回true,指针下移。如果返回false,指针不下移。
			T t = clazz.newInstance();

			for (int i = 0; i < columnCount; i++) {// 处理列

				Object columnValue = rs.getObject(i + 1);// 获取列值

				String columnLabel = rsmd.getColumnLabel(i + 1);// 获取结果集中列的别名

				// 反射
				Field field = clazz.getDeclaredField(columnLabel);
				field.setAccessible(true);
				field.set(t, columnValue);

			}

			list.add(t);
		}
		return list;
		
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 8.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);

	}

	return null;
	}

	@Test
	public void testGetInstance() {
		String sql = "select id,name,birth from customers where id = ?";
		Customer cust = getInstance(Customer.class, sql, 12);
		System.out.println(cust);

	String sql1 = "select order_id orderId,order_name orderName from `order` where order_id = ?";
	Order order = getInstance(Order.class, sql1, 1);
	System.out.println(order);
	}

在这里插入图片描述

	// 通用的查询,返回一条记录
	public <T> T getInstance(Class<T> clazz, String sql, Object... args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			// 1.获取连接
			conn = JDBCUtils.getConnection();
			// 2.预编译sql语句
			ps = conn.prepareStatement(sql);

		// 3.填充占位符
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}

		// 4.调用executeQuery(),获取结果集
		rs = ps.executeQuery();

		// 5.获取结果集的元数据
		ResultSetMetaData rsmd = rs.getMetaData();
		// 6.获取结果集中列的个数
		int columnCount = rsmd.getColumnCount();

		// 7.处理结果集
		if (rs.next()) {// ①判断指针的下一个位置是否有数据 ②如果返回true,指针下移。如果返回false,指针不下移。

			T t = clazz.newInstance();

			for (int i = 0; i < columnCount; i++) {// 处理列

				Object columnValue = rs.getObject(i + 1);// 获取列值

				String columnLabel = rsmd.getColumnLabel(i + 1);// 获取结果集中列的别名

				// 反射
				Field field = clazz.getDeclaredField(columnLabel);
				field.setAccessible(true);
				field.set(t, columnValue);

			}

			return t;
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 8.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);

	}

	return null;
	}
	}

PreparedStatement解决Statement的弊端

package JavaWeb.JDBC.day2.java;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Scanner;

import JavaWeb.JDBC.day2.bean.User;
import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;


/**
 * PreparedStatement解决Statement的弊端
 * 1.解决拼串的问题:参照 课后练习2
 * 2.解决sql注入问题
 */
public class PreparedStatementTest2 {

	@Test
	public void testLogin() {
		Scanner s = new Scanner(System.in);
		System.out.println("用户名:");
		String user = s.nextLine();

	System.out.println("密码:");
	String password = s.nextLine();
	// select user,password from user_table where user = '' and password = '';
	//select user,password from user_table where user = '1' or ' and password = ' = '1' or '1' = '1';
	String sql = "SELECT user,password FROM user_table WHERE USER = ? AND PASSWORD = ?";

	User u = getInstance(User.class,sql,user,password);
	if (u != null) {
		System.out.println("登录成功");
	} else {
		System.out.println("登录失败");
	}

	}

输入错的密码
在这里插入图片描述
在这里插入图片描述
输入正确密码
在这里插入图片描述

	// 通用的查询,返回一条记录
	public <T> T getInstance(Class<T> clazz, String sql, Object... args) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			// 1.获取连接
			conn = JDBCUtils.getConnection();
			// 2.预编译sql语句
			ps = conn.prepareStatement(sql);

		// 3.填充占位符
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}

		// 4.调用executeQuery(),获取结果集
		rs = ps.executeQuery();

		// 5.获取结果集的元数据
		ResultSetMetaData rsmd = rs.getMetaData();
		// 6.获取结果集中列的个数
		int columnCount = rsmd.getColumnCount();

		// 7.处理结果集
		if (rs.next()) {// ①判断指针的下一个位置是否有数据 ②如果返回true,指针下移。如果返回false,指针不下移。

			T t = clazz.newInstance();

			for (int i = 0; i < columnCount; i++) {// 处理列

				Object columnValue = rs.getObject(i + 1);// 获取列值

				String columnLabel = rsmd.getColumnLabel(i + 1);// 获取结果集中列的别名

				// 反射
				Field field = clazz.getDeclaredField(columnLabel);
				field.setAccessible(true);
				field.set(t, columnValue);

			}

			return t;
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 8.关闭资源
		JDBCUtils.closeResource(conn, ps, rs);

	}

	return null;
	}
	}

Blob接口

package JavaWeb.JDBC.day2.java1;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import JavaWeb.JDBC.day2.bean.Customer;
import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;


public class BlobTest {

//2.从数据表中读取Blob类型的数据
//使用try-catch-finally处理异常
@Test
public void testQueryBlob() throws Exception {
	Connection conn = JDBCUtils.getConnection();
	
	String sql = "select id,name,email,birth,photo from customers where id = ?";
	PreparedStatement ps = conn.prepareStatement(sql);
	
	ps.setObject(1, 21);
	
	ResultSet rs = ps.executeQuery();
	InputStream is = null;
	FileOutputStream fos = null;
	if(rs.next()) {
		//
		int id = rs.getInt("id");
		String name = rs.getString("name");
		String email = rs.getString("email");
		Date birth = rs.getDate("birth");
		
		Customer cust = new Customer(id, name, email, birth);
		System.out.println(cust);
		
		//读取Blob类型
		Blob blob = rs.getBlob("photo");
		is = blob.getBinaryStream();
		fos = new FileOutputStream("abc.png");
		byte[] buffer = new byte[1024];
		int len;
		while((len = is.read(buffer)) != -1) {
			fos.write(buffer, 0, len);
		}
		
	}
	
	JDBCUtils.closeResource(conn, ps, rs);
	
	if(is != null) {
		is.close();
	}
	if(fos != null) {
		fos.close();
	}
}


//1.向数据表中插入Blob类型的变量
//使用try-catch-finally处理异常
@Test
public void testInsertBlob() throws Exception {
	
	Connection conn = JDBCUtils.getConnection();
	
	String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)";
	
	PreparedStatement ps = conn.prepareStatement(sql);
	//
	ps.setObject(1, "张益达");
	ps.setObject(2, "dada@126.com");
	ps.setObject(3, "1998-09-08");
	FileInputStream fis = new FileInputStream("beauty.png");
	ps.setBlob(4, fis);
	
	//
	ps.executeUpdate();
	
	JDBCUtils.closeResource(conn, ps);
	if(fis != null) {
		fis.close();
	}
}
}

在这里插入图片描述

使用PreparedStatement实现批量操作,这里主要指的是批量插入

package JavaWeb.JDBC.day2.java1;

import java.sql.Connection;
import java.sql.PreparedStatement;

import JavaWeb.JDBC.day2.util.JDBCUtils;
import org.junit.Test;


/**
 * 使用PreparedStatement实现批量操作,这里主要指的是批量插入
 * 
 * 	insert / update / delete / select 
 * 
 *  方式一:使用Statement实现
 *  
 *  Statement st = conn.createStatement();
 *  for(int i = 1;i <= 20000;i++){
 *  	String sql = "insert into goods(name)values('name_' " + i +")";
 *  	st.execute(sql);
 *  }
 *  
 *
 */
public class PreparedStatementTest {

/**
 * 方式四:
 * Connection 的 setAutoCommit(false)  /  commit()
 */
@Test
public void testInsert3() throws Exception {
	Connection conn = JDBCUtils.getConnection();
	
	//a. 不要自动提交数据
	conn.setAutoCommit(false);
	
	
	long start = System.currentTimeMillis();
	String sql = "insert into goods(name)values(?)";
	//预编译sql语句
	PreparedStatement ps = conn.prepareStatement(sql);
	for(int i = 1; i <= 1000000;i++) {
		ps.setObject(1, "name_" + i);
		//1.“攒”sql
		ps.addBatch();
		
		if( i % 500 == 0) {
			//2.执行
			ps.executeBatch();
			
			//3.清空
			ps.clearBatch();
		}
	}
	
	//b.提交数据
	conn.commit();
	
	long end = System.currentTimeMillis();
	System.out.println("花费的时间为:" + (end - start));//71526 - 387
	//1000000:16047 - 4945
	JDBCUtils.closeResource(conn, ps);
	
}

/**
 * 方式三:
 * ① 使用 addBatch() / executeBatch() / clearBatch()
 * ② ?rewriteBatchedStatements=true&useServerPrepStmts=false
 * ③ 使用更新的mysql 驱动:
 * mysql-connector-java-5.1.37-bin.jar
 * 
 */
@Test
public void testInsert2() throws Exception {
	Connection conn = JDBCUtils.getConnection();
	long start = System.currentTimeMillis();
	String sql = "insert into goods(name)values(?)";
	//预编译sql语句
	PreparedStatement ps = conn.prepareStatement(sql);
	for(int i = 1; i <= 1000000;i++) {
		ps.setObject(1, "name_" + i);
		//1.“攒”sql
		ps.addBatch();
		
		if( i % 500 == 0) {
			//2.执行
			ps.executeBatch();
			
			//3.清空
			ps.clearBatch();
		}
	}
	
	long end = System.currentTimeMillis();
	System.out.println("花费的时间为:" + (end - start));//71526 - 387
	//1000000:16047
	
	JDBCUtils.closeResource(conn, ps);
	
}


/**
 * 方式二:使用PreparedStatement 替换Statement
 * @throws Exception 
 */
@Test
public void testInsert1() throws Exception {
	Connection conn = JDBCUtils.getConnection();
	long start = System.currentTimeMillis();
	String sql = "insert into goods(name)values(?)";
	//预编译sql语句
	PreparedStatement ps = conn.prepareStatement(sql);
	for(int i = 1; i <= 20000;i++) {
		ps.setObject(1, "name_" + i);
		ps.execute();
		
	}
	
	long end = System.currentTimeMillis();
	System.out.println("花费的时间为:" + (end - start));//71526
	
	JDBCUtils.closeResource(conn, ps);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值