Java连接MySQL数据库技术JDBC

一、JDBC概述

JDBC:Java DataBase Connectivity,java动态数据库连接技术是一种用于执行SQL语句的Java API。JDBC可以有多套实现类,例如:Mysql、Oracle、SqlServer等数据库。JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。例如mysql-connector-java-5.1.6.jar

1、JDBC与数据库驱动

在这里插入图片描述
JDBC与数据库驱动的关系本质上就是接口与实现的关系。
Sun公司提供了供程序员调用的类和接口,集成在了java.sql和javax.sql包里,例如:

  • DriverManager:用于注册驱动的类,管理各种不同的JDBC驱动
  • Connection:负责连接数据库以及担任传送数据的任务
  • Statement:由Connection产生的执行sql语句的类
  • ResultSet:用于保存Statement执行后产生的结果集

2、JDBC的原理

  1. 客户端向服务器发起连接请求,DriverManager根据客户端提供的JDBC驱动来判断客户端使用的哪个数据库;
  2. DriverManager根据客户端提供数据库的URL、端口号、用户名、密码等信息对数据库开启一个客户端与服务器之间的通道(Connection)并进行连接。
  3. 建立通道后,就可以通过Statement对服务器发起sql语句的执行;
  4. 服务器执行这条sql语句,如果有查询结果,服务器将通过ResultSet的形式将数据集返回给客户端。

二、JDBC的开发步骤

1、添加驱动

以eclipsed的Java项目和mysql-connector-java-5.1.6.jar驱动为例,将mysql-connector-java-5.1.6.jar添加到Libraries里。
具体做法:

  1. 将mysql-connector-java-5.1.6.jar添加到Java项目里(最好在项目里建个专门用于存放jar包的文件夹,将其放在文件夹里)
  2. 右键项目名 -> Build Path -> Configure Build Path -> LibRaries -> AddJARs…
  3. 在打开的对话框中选择项目,点击Apply->OK就添到项目里了。

2、编写代码

案例:查询jdbcdb数据库中person表的全部数据

package com.gaj.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


/**
 * 用java代码连接数据库测试
 * JDBC技术
 * @author Jan
 *
 */
public class JDBCTest {

	public static void main(String[] args) {
		// 定义mysql的驱动类 用于反射
		String driver = "com.mysql.jdbc.Driver";
		// 定义mysql数据库的url
		String url = "jdbc:mysql://127.0.0.1:3306/jdbcdb?characterEncoding=UTF-8";
		// 定义连接数据库的用户名
		String user = "root";
		// 定义连接数据库的密码
		String password = "root";
		// 定义sql语句
		String sql = "select * from person";
		// 声明
		Connection conn = null;
		Statement stat = null;
		ResultSet rs = null;
		try {
			// 1.加载JDBC驱动类
			// 方法一:注册驱动
//			DriverManager.registerDriver(new Driver());
			
			// 方法二:反射
//			Driver d = (Driver) Class.forName(driver).newInstance();
//			DriverManager.registerDriver(d);
			
			// 方法三:反射简写(JDK1.6之后可以省略)
			// 程序运行期间DriverManager会根据驱动类型自动匹配
			Class.forName(driver);
			// 2.获取连接数据库的对象 与数据库建立连接
			conn = DriverManager.getConnection(url, user, password);
			// 3.创建操作数据库的对象
			stat = conn.createStatement();
			// 4.执行查询得到数据结果集
			rs = stat.executeQuery(sql);
			// 5.解析结果集 使用游标判断是否还有数据 
			System.out.println("id\tname\tsex\tage\tfrom");
			while(rs.next()){
				// int getInt(int columnIndex) 按列的序号获取数据,从1开始
				System.out.println(rs.getInt(1) + "\t" + rs.getString(2) + "\t" +  rs.getString(3) + "\t" +  rs.getInt(4) + "\t" +  rs.getString(5));
				// int getInt(String columnLabel) 按列名获取数据
//				System.out.println(rs.getInt("id") + "\t" + rs.getString("name") + "\t" +  rs.getString("sex") + "\t" +  rs.getInt("age") + "\t" +  rs.getString("from"));
				// int -> String 自动转换
//				System.out.println(rs.getString("id") + "\t" + rs.getString("name") + "\t" +  rs.getString("sex") + "\t" +  rs.getString("age") + "\t" +  rs.getString("from"));
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			if(rs != null){
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if(stat != null){
				try {
					stat.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if(conn != null){
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

三、JDBC API详解

1、java.sql.DriverManager类注册驱动

Class.forName("com.mysql.jdbc.Driver"):
  • DriverManger需要一个java.sql.Driver的实现类,com.mysql.jdbc.Driver(驱动实现类) implements java.sql.Driver,因此创建com.mysql.jdbc.Driver这个类的对象供数据库使用,程序运行期间DriverManager根据驱动类型自动匹配

JDK1.6之后DriverManger借助ServiceLoader会在程序运行期间加载导入的mysqljar包然后找到驱动自动注册,不需要再手工注册,也就是说只要你导入JAR包其实不用指定驱动DriverManager也能找到某个类型的驱动自己进行设置。
ServiceLoader与ClassLoader是Java中2个即相互区别又相互联系的加载器。JVM利用ClassLoader将类载入内存,这是一个类生命周期的第一步(一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直接被使用的情况)。
ServiceLoader是一个简单的服务提供者加载设施。服务是一个熟知的接口和类(通常为抽象类)集合。服务提供者是服务的特定实现。提供者中的类通常实现接口,并子类化在服务本身中定义的子类。服务提供者可以以扩展的形式安装在Java平台的实现中,也就是将jar文件放入任意常用的扩展目录中。也可通过将提供者加入应用程序类路径,或者通过其他某些特定于平台的方式使其可用。唯一强制要求的是,提供者类必须具有不带参数的构造方法,以便它们可以在加载中被实例化。

2、getConnection()获取连接

  • DriverManager的静态方法,建立到给定URL数据库的连接:
    public static Connection getConnection(String url, String user, String password)
  • URL(Uniform Resource Locator):统一资源定位器,可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
  • Java程序与数据库之间采用TCP协议连接,所以传输字符的时候最好设置下编码,要不然可能会乱码
  • URL包含模式(或称协议)、服务器名称(或IP地址)、路径和文件名
  • URL完整格式:协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志
  • jdbc:mysql://127.0.0.1:3306/jdbcdb?characterEncoding=UTF-8,本地连接还可以简写为jdbc:mysql:///jdbcdb

3、java.sql.Connection接口

  • 接口的实现在数据库驱动中,所有与数据库交互都是基于连接对象的。
  • Connection接口的方法,用于创建操作sql语句的对象:Statement createStatement();

4、java.sql.Statement接口

  • 操作sql语句,并返回结果,具体结果看具体的执行方法。
  • 通过Connection接口的createStatement()方法返回一个Statement对象:Statement stmt = conn.createStatement();
  • 常用方法:
方法名说明
ResultSet executeQuery(String sql)执行SQL查询并获取到ResultSet对象
int executeUpdate(String sql)执行插入、删除、更新等操作,返回值是执行sql所影响的行数
boolean execute(String sql)执行任意sql语句,获得一个布尔值,表示是否返回ResultSet

5、java.sql.ResultSet接口

  • ResultSet表示数据库结果集的数据表,通常由执行查询数据库的语句生成,DML(增删改操作)是不会产生数据集的。
  • ResultSet对象维护一个指向其当前数据行的游标。最初,游标定位在第一行之前。下一个方法将光标移动到下一行,因为当ResultSet对象中没有更多行时,它返回false,所以可以在while循环中使用它进行迭代。
  • 常用方法:
方法名说明
boolean next()将游标从当前位置向下移动一行
boolean previous()将游标从当前位置向上移动一行
void clsoe()关闭ResultSet对象
int getInt(int colIndex)以int形式获取结果集当前行指定列号值
int getInt(String colLabel)以int形式获取结果集当前行指定列名值
float getFloat(int colIndex)以float形式获取结果集当前行指定列号值
float getFloat(String colLabel)以float形式获取结果集当前行指定列名值
String getString(int colIndex)以String形式获取结果集当前行指定列号值
String getString(String colLabel)以String形式获取结果集当前行指定列名值

6、close()资源释放

  • 立即释放当前对象的数据库和JDBC资源,而不是等待
  • 关闭的顺序是先得到的后关闭,后得到的先关闭

四、JDBC的CURD(基础版)

1、Insert操作

	// 添加数据
	@Test
	public void insertTest() throws Exception{
		// 定义驱动类
		String driver = "com.mysql.jdbc.Driver";
		// 定义URL
		String url = "jdbc:mysql://127.0.0.1:3306/jdbcdb?characterEncoding=utf-8";
		// 定义user
		String user = "root";
		// 定义password
		String password = "root";
		// 定义sql
		String sql = "insert into person(`id`, `name`, `sex`, `age`, `from`) values(null, '王小花', '女', 18, '湖南省');";
		// 1.加载驱动类
		Class.forName(driver);
		// 2.获取数据库连接
		Connection conn = DriverManager.getConnection(url, user, password);
		// 3.创建操作数据库对象
		Statement stat = conn.createStatement();
		// 4.执行结果 int executeUpdate(String sql) 返回int值,代表影响行数
		int count = stat.executeUpdate(sql);
		// 5.判断结果 影响行数如果大于0说明执行成功
		System.out.println((count > 0) ? "执行成功!" : "执行失败!");
		// 6.关闭连接
		stat.close();
		conn.close();
	}

2、Delete操作

	// 删除数据
	@Test
	public void deleteTest() throws Exception{
		// 定义驱动类
		String driver = "com.mysql.jdbc.Driver";
		// 定义URL
		String url = "jdbc:mysql://127.0.0.1:3306/jdbcdb?characterEncoding=utf-8";
		// 定义user
		String user = "root";
		// 定义password
		String password = "root";
		// 定义sql
		String sql = "delete from person where id = 3";
		// 1.加载驱动类
		Class.forName(driver);
		// 2.获取数据库连接
		Connection conn = DriverManager.getConnection(url, user, password);
		// 3.创建数据库操作对象
		Statement stat = conn.createStatement();
		// 4.操作数据
		int count = stat.executeUpdate(sql);
		// 5.判断结果
		System.out.println((count > 0) ? "执行成功!" : "执行失败!");
		// 6.关闭连接
		stat.close();
		conn.close();
	}

3、Update操作

// 修改数据
	@Test
	public void updateTest() throws Exception{
		// 定义Driver类
		String driver = "com.mysql.jdbc.Driver";
		// 定义URL
		String url = "jdbc:mysql://127.0.0.1:3306/jdbcdb?characterEncoding=utf-8";
		// 定义user
		String user = "root";
		// 定义password
		String password = "root";
		// 定义sql
		String sql = "update person set `name`='李建军', `age`=28 where `id` = 4;";
		// 1.加载驱动类
		Class.forName(driver);
		// 2. 获取连接数据库对象
		Connection conn = DriverManager.getConnection(url, user, password);
		// 3. 创建数据库操作对象
		Statement stat = conn.createStatement();
		// 4. 执行sql
		int count = stat.executeUpdate(sql);
		// 5. 判断结果
		System.out.println((count > 0) ? "执行成功!" : "执行失败!");
		// 6. 关闭数据库连接
		stat.close();
		conn.close();
	}

4、Query操作

// 查询数据
	@Test
	public void queryAllTest() throws Exception{
		// 定义驱动类
		String driver = "com.mysql.jdbc.Driver";
		// 定义URL 简写 默认连接本机数据库 字符集默认utf-8
		String url = "jdbc:mysql:///jdbcdb";
		// 定义user
		String user = "root";
		// 定义password
		String password = "root";
		// 定义sql
		String sql = "select * from person";
		// 1.加载驱动类
		Class.forName(driver);
		// 2.获取连接数据库对象
		Connection conn = DriverManager.getConnection(url, user, password);
		// 3.创建数据库操作对象
		Statement stat = conn.createStatement();
		// 4.执行sql
		ResultSet rs = stat.executeQuery(sql);
		// 5.解析结果集
		System.out.println("id\tname\tsex\tage\tfrom");
		while(rs.next()){
			System.out.println(rs.getInt(1) + "\t" + rs.getString(2) +  "\t" + rs.getString(3) + "\t" + rs.getInt(4) + "\t" + rs.getString(5));
		}
		// 6.关闭数据库资源
		rs.close();
		stat.close();
		conn.close();
	}

五、JDBC工具类和sql注入问题

1、自定义JDBC工具类

  • 由于代码重复率比较高,因此抽出重复率较高的部分,例如数据库连接的获取部分以及关闭部分
package com.gaj.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtil {
	
	// 定义mysql数据库驱动需要加载的类
	private static final String CONN_DRIVER = "com.mysql.jdbc.Driver";
	// 定义需要连接数据库的URL
	private static final String CONN_URL = "jdbc:mysql://127.0.0.1:3306/jdbcdb?charaterEncoding=utf8";
	// 定义连接数据库的用户名
	private static final String CONN_USER = "root";
	// 定义连接数据库的密码
	private static final String CONN_PASS = "root";
	
	
	/**
	 * 获取数据连接对象
	 * @return 返回一个数据库连接对象
	 */
	public static Connection getConnection(){
		Connection conn = null;
		try {
			// 加载数据库驱动
			Class.forName(CONN_DRIVER);
			// 获取数据库连接
			conn = DriverManager.getConnection(CONN_URL, CONN_USER, CONN_PASS);
		} catch (ClassNotFoundException e) {
			System.out.println("没有找到驱动类:" + e.getMessage());
			e.printStackTrace();
		} catch (SQLException e) {
			System.out.println("数据库连接失败:" + e.getMessage());
			e.printStackTrace();
		}
		return conn;
	}
	
	/**
	 * 释放资源
	 * 关个连接也能报错???
	 * 关闭所有数据库连接,如果没有创建该对象直接填null就好了
	 * @param conn 数据库连接对象
	 * @param stat 数据库操作对象
	 * @param rs   数据结果集对象
	 */
	public static void closeAllConnection(Connection conn, Statement stat, ResultSet rs){
		// 先开后关原则
		if(null != rs){
			try {
				rs.close();
			} catch (SQLException e) {
				System.out.println("关闭数据结果集出错:" + e.getMessage());
				e.printStackTrace();
			}
		}
		if(null != stat){
			try {
				stat.close();
			} catch (SQLException e) {
				System.out.println("关闭数据库操作对象出错:" + e.getMessage());
				e.printStackTrace();
			}
		}
		if(null != conn){
			try {
				conn.close();
			} catch (SQLException e) {
				System.out.println("关闭数据库连接出错:" + e.getMessage());
				e.printStackTrace();
			}
		}
	}
}

2、SQL注入问题

SQL注入:用户输入的内容作为了SQL语句语法的一部分,改变了原有SQL真正的意义。

  • 定义一个根据姓名查询人员信息的方法
	// 根据姓名查询人员的数据
	public void findPersonByName(String name) throws Exception{
		Connection conn = JDBCUtil.getConnection();
		String sql = "select * from person where `name` = " + name;
		Statement stat = conn.createStatement();
		ResultSet rs = stat.executeQuery(sql);
		while(rs.next()){
			System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\t" + rs.getString(4) + "\t" + rs.getString(5));
		}
		JDBCUtil.closeAllConnection(conn, stat, rs);
	}
  • 正常查询
	// 测试findPersonById()
	@Test
	public void findPersonByIdTest() throws Exception{
		// 正常查询
		findPersonByName("'张三'");
	}

结果:只有一条数据信息

	// 测试findPersonById()
	@Test
	public void findPersonByIdTest() throws Exception{
		// 注入问题存在
		findPersonByName("'张三' or true");
	}

结果:本来只想查询一条数据,但由于某某修改参数将所有数据都查询出来了,将原有的意义给改了。
原因:statement对象只能机械的执行SQL语句,其他的一律不管

3、预处理对象

  • java.sql.preparedStatement继承自java.sql.Statement,预编译对象,是Statement对象的子类。
    特点:性能高;会将sql语句先编译;能过滤用户输入的关键字
  • PreparedStatement预处理对象,处理的每条sql语句中所有的实际参数,都必须使用占位符?替换
	// 根据姓名查询人员的数据
	public void findPersonByName(String name) throws Exception{
		Connection conn = JDBCUtil.getConnection();
		// sql语句 占位符占位
		String sql = "select * from person where `name` = ?";
		// 将sql传入预编译prepareStatement()方法 进行预编译
		PreparedStatement ps = conn.prepareStatement(sql);
		// 给占位符赋值
		ps.setString(1, name);
		// 执行获得结果集 这里由于之前传过参了,因此不用再传
		ResultSet rs = ps.executeQuery();
		while(rs.next()){
			System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\t" + rs.getString(4) + "\t" + rs.getString(5));
		}
		JDBCUtil.closeAllConnection(conn, ps, rs);
	}
  • PreparedStatement对象在创建的时候就预编译了SQL语句,这样比Statement执行的时候再编译,这种方式省去了编译步骤从而提高性能。并且PreparedStatement执行的SQL语句采用占位符的形式避免了拼接,这样可以在输入参数的时候就进行类型验证还能简化SQL的编写难度;
	// 测试findPersonByName()
	@Test
	public void findPersonByNameTest() throws Exception{
		// 正常查询 正常结果
//		findPersonByName("张三");
		// 过滤了关键字,查询不到数据了,避免了注入
		findPersonByName("张三 or true");
	}

六、JDBC的CURD(改进版)

改进版新增如下几点:

  • 数据库中的一条记录对应Java中的一个对象,他们应该是一一对应的,表对应类,字段对应属性
  • 操作Person实体类对象,OOP思想的体现
  • 将JDBC的CURD操作封装成功能函数
  • 使用自己封装的JDBCUtil类简化获取连接和关闭资源
  • 使用PreparedStatement 解决SQL注解问题

1、person实体类

package com.gaj.entity;

/**
 * JDBC需要操作的人员实体类
 * 属性需要与数据库的字段类型相匹配
 * 属性名称可以不匹配 在不修改数据库字段的前提下 可以使用sql语句的as重命名 来保证字段名一致
 * @author Jan
 *
 */
public class Person {
	private Integer pid;
	private String pname;
	private String sex;
	private Integer age;
	private String from;
	public Integer getPid() {
		return pid;
	}
	public void setPid(Integer pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getFrom() {
		return from;
	}
	public void setFrom(String from) {
		this.from = from;
	}
	@Override
	public String toString() {
		return "Person [pid=" + pid + ", pname=" + pname + ", sex=" + sex + ", age=" + age + ", from=" + from + "]";
	}
}

2、改进版的CURD功能函数

package com.gaj.function;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.gaj.entity.Person;
import com.gaj.utils.JDBCUtil;

/**
 * 改进版 
 * JDBC连接数据库的CURD操作 
 * 1.操作实体类对象 OOP思想的体现 
 * 2.封装功能函数
 * 3.使用自己封装的DBUtil类简化获取连接和关闭资源
 * 4.PreparedStatement 注解问题的解决 
 * 
 * @author Jan
 * @version 2.0
 * 
 */
public class JDBCFunction {
	// 新增操作
	public static int insert(Person person) throws Exception {
		// 1.使用自己封装的JDBCUtil加载驱动类并创建数据库连接对象
		Connection conn = JDBCUtil.getConnection();
		// 2.定义sql语句 使用占位符占位
		String sql = "insert into person values(null,?,?,?,?);";
		// 3.创建数据库预编译操作对象 传入sql语句进行预编译
		PreparedStatement ps = conn.prepareStatement(sql);
		// 4.占位符赋值
		// void setString(int parameterIndex, String x) 占位符的位置,设置的值
		ps.setString(1, person.getPname());
		ps.setString(2, person.getSex());
		ps.setInt(3, person.getAge());
		ps.setString(4, person.getFrom());
		// 5.执行sql语句 之前预编译过了 因此这里不用传参
		int count = ps.executeUpdate();
		// 6.关闭数据库连接
		JDBCUtil.closeAllConnection(conn, ps, null);
		// 7.返回影响行数
		return count;
	}

	// 删除操作
	public static int delete(Person person) throws Exception{
		// 获取连接
		Connection conn = JDBCUtil.getConnection();
		// sql 占位符
		String sql = "delete from person where id = ?";
		// 创建预编译执行对象
		PreparedStatement ps = conn.prepareStatement(sql);
		// 占位符赋值
		ps.setInt(1, person.getPid());
		// 执行sql
		int count = ps.executeUpdate();
		// 释放资源
		JDBCUtil.closeAllConnection(conn, ps, null);
		// 返回影响行数
		return count;
	}
	
	// 修改操作
	public static int update(Person person) throws Exception{
		// 获取连接
		Connection conn = JDBCUtil.getConnection();
		// 编写sql
		String sql = "update person set name =?, sex=?,age=?,`from`=? where id=?";
		// 预编译
		PreparedStatement ps = conn.prepareStatement(sql);
		// 占位符赋值
		ps.setString(1, person.getPname());
		ps.setString(2, person.getSex());
		ps.setInt(3, person.getAge());
		ps.setString(4, person.getFrom());
		ps.setInt(5, person.getPid());
		// 执行sql
		int count = ps.executeUpdate();
		// 关闭资源
		JDBCUtil.closeAllConnection(conn, ps, null);
		// 返回影响行数
		return count;
	}
	
	// 查询操作
	public static List<Person> queryAll() throws Exception{
		// 获取连接
		Connection conn = JDBCUtil.getConnection();
		// 编写sql语句
		String sql = "select * from person";
		// 创建执行数据库执行对象
		PreparedStatement ps = conn.prepareStatement(sql);
		// 执行sql语句
		ResultSet rs = ps.executeQuery();
		// 解析结果集
		List<Person> list = new ArrayList<>();
		Person person = null;
		while(rs.next()){
			person = new Person();
			person.setPid(rs.getInt("id"));
			person.setPname(rs.getString("name"));
			person.setSex(rs.getString("sex"));
			person.setAge(rs.getInt("age"));
			person.setFrom(rs.getString("from"));
			// 添加到list集合
			list.add(person);
		}
		// 关闭连接
		JDBCUtil.closeAllConnection(conn, ps, rs);
		// 返回person数组
		return list;
	}
	
	
	/**
	 * 按id查找该对象是否存在,存在返回该对象,不存在返回null
	 * @param id 
	 * @return 返回Person类的一个对象
	 * @throws Exception
	 */
	public static Person findPeresonById(Integer id) throws Exception{
		// 定义person对象
		Person person = null;
		// 获取数据库连接
		Connection conn = JDBCUtil.getConnection();
		// 编写sql
		String sql = "select * from Person where id = ?";
		// 预编译
		PreparedStatement ps = conn.prepareStatement(sql);
		// 占位符
		ps.setInt(1, id);
		// 执行
		ResultSet rs = ps.executeQuery();
		// 解析一行
		if(rs.next()){
			// 创建person对象
			person = new Person();
			// 给person类赋值
			person.setPid(rs.getInt("id"));
			person.setPname(rs.getString("name"));
			person.setSex(rs.getString("sex"));
			person.setAge(rs.getInt("age"));
			person.setFrom(rs.getString("from"));
		}
		// 关闭资源
		JDBCUtil.closeAllConnection(conn, ps, rs);
		// 返回person类
		return person;
	}

	// 根据姓名查询人员的数据
	public static void findPersonByName(String name) throws Exception{
		Connection conn = JDBCUtil.getConnection();
		String sql = "select * from person where `name` = ?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, name);
		ResultSet rs = ps.executeQuery();
		while(rs.next()){
			System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\t" + rs.getString(4) + "\t" + rs.getString(5));
		}
		JDBCUtil.closeAllConnection(conn, ps, rs);
	}
	
}

3、测试类

package com.gaj.test;

import java.util.List;
import org.junit.Test;

import com.gaj.entity.Person;
import com.gaj.function.JDBCFunction;

/**
 * 测试类 测试JDBCFunction的CURD操作
 * @author Jan
 *
 */
public class Test2 {
	/**
	 * 测试按Id查找
	 * @throws Exception
	 */
	@Test
	public void findPersonByIdTest() throws Exception{
		Person person = JDBCFunction.findPeresonById(11);
		System.out.println(person);
	}


	/**
	 * 测试新增人员信息
	 * @throws Exception
	 */
	@Test
	public void insertTest() throws Exception {
		// 创建Person对象
		Person person = new Person();
		// 给Person对象赋值
		person.setPname("张三");
		person.setSex("男");
		person.setAge(22);
		person.setFrom("江西省");
		// 执行新增操作
		int count = JDBCFunction.insert(person);
		// 判断执行结果
		System.out.println(count > 0 ? "Insert Successed!" : "Insert Failed!");
	}
	
	/**
	 * 测试删除人员信息
	 * @throws Exception
	 */
	@Test
	public void deleteTest() throws Exception{
		Person person = JDBCFunction.findPeresonById(7);
		if(person != null){
			int count = JDBCFunction.delete(person);
			System.out.println(count > 0 ? "Delete Successed!" : "Delete Failed!");
		}else{
			System.out.println("The object not exists!");
		}
	}
	
	/**
	 * 测试修改人员信息
	 * @throws Exception
	 */
	@Test 
	public void updateTest() throws Exception{
		Person person = JDBCFunction.findPeresonById(6);
		if(person != null){
			person.setPname("李四");
			person.setAge(20);
			person.setSex("男");
			person.setFrom("浙江省");
			int count = JDBCFunction.update(person);
			System.out.println(count > 0 ? "Update Successed!" : "Update Failed!");
		}else{
			System.out.println("The object not exists!");
		}
	}
	
	
	/**
	 * 测试查询全部
	 * @throws Exception
	 */
	@Test
	public void QueryAllTest() throws Exception{
		List<Person> list = JDBCFunction.queryAll();
		for (Person person : list) {
			System.out.println(person);
		}
	}
	
	/**
	 * 按名字查询一条数据
	 * @throws Exception
	 */
	@Test
	public void findPersonByNameTest() throws Exception{
		// 正常查询
//		JDBCFunction.findPersonByName("张三");
		// 查询不到数据
		JDBCFunction.findPersonByName("张三 or true");
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值