学习javaweb第十二天

JDBC

什么是JDBC
其实JDBC就是一套统一的java代码,这套代码,可以操作所有的关系型数据库。
接口需要实现类,每一个不同的数据库产商定义了不同的实现类,但是每一个实现类都实现类了相同的JDBC接口。
我们写代码的时候,只需要实现接口的调用,实现类是由不同的数据库厂商来实现的。(实现类也叫数据库驱动)

JDBC的本质
官方(sun)公司定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行代码是驱动jar包中的实现类。

两个层次:
面向应用的API:Java API,抽象接口,供应用程序开发人员使用(连接数据库,执行SQL语句,获得结果)。
面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
JDBC驱动程序:各个数据库厂商根据JDBC的规范制作的 JDBC 实现类的类库
JDBC驱动程序总共有四种类型:
第一类:JDBC-ODBC桥。
第二类:部分本地API部分Java的驱动程序。
第三类:JDBC网络纯Java驱动程序。
第四类:本地协议的纯 Java 驱动程序。

JDBC常用的API

一、Driver接口
Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。
在编写JDBC程序时,必须把所使用的数据库驱动程序或者类库加载到项目的classpath中(这里指MySQL驱动JAR包)

二、DriverManager类
DriverManager类用于加载JDBC驱动,并且创建与数据库的连接

在DriverManager类中,定义了两个比较重要的静态方法。

方法名称功能描述
static void registerDriver(Driver driver)该方法用于向DriverManager中注册给定的JDBC驱动程序
static Connection getConnection(String url,String user,String pwd)该方法用于建立和数据库的连接,并返回表示连接的Connection对象

三、Connection接口
Connection接口代表Java程序和数据库的连接,只有获得该连接对象后,才能访问数据库,并操作数据表

方法名称功能描述
DatabaseMetaData getMetaData()该方法用于返回表示数据库的元数据的DatabaseMetaData对象
Statement createStatement()用于创建一个Statement对象来将SQL语句发送到数据库
PreparedStatement preparStatement(String sql)用于创建一个PreparedStatement对象来将参数化的SQL语句发送到数据库
CallableStatement prepareCall(String sql)用于创建一个CallableStatement对象来调用数据库存储过程

四、Statement接口
Statement接口用于执行静态的SQL语句,并返回一个结果对象。

Statement接口对象可以通过Connection实例的createStatement()方法获取,该对象会把静态的SQL语句发送到数据库中编译执行,然后返回数据库的处理结果。

在Statement接口中,提供了3个常用的执行SQL语句的方法

方法名称功能描述
boolean execute(String sql)用于执行各种SQL语句,该方法返回一个Boolean类型的值,如果为true,表示所执行的SQL语句有查询结果,可通过Statement的getResultSet()方法获得查询结果
int executeUpdate(String sql)用于执行SQL中的insert、update和delete语句。该方法返回一个int类型的值,表示数据库中受该SQL语句影响的记录条数
ResultSet executeQuecry(String sql)用于执行SQl中的select语句,该方法返回一个表示查询结果的ResultSet对象

五、PreparedStatement接口
PreparedStatement 是 Statement的子接口,用于执行预编译的SQL语句。

该接口扩展了带有参数SQL语句的执行操作,应用该接口中的SQL语句可以使用占位符 “?” 来替代其参数,然后通过 setXxx()方法为SQL 语句的参数赋值。

方法名称功能描述
int executeUpdate()在此PreparedStatement对象中执行SQL语句,该语句必须是一个DML语句或者是无返回内容的SQL语句,如DDL语句
ResultSet executeQuery()在此PreparedStatement对象中执行SQL查询,该方法返回的是ResultSet对象
void setInt(int parameterIndex,int x)将指定参数设置为给定的int值
void setFloat(int parameterIndex,float x)将指定参数设置为给定的float值
void setString(int parameterIndex,String x)将指定参数设置为给定的String值
void setDate(int parameterIndex,Date x)将指定参数设置为给定的Date值
将一组参数添加到此Pre对象的处理命令

在通过setXxx()方法为SQL语句中的参数赋值时,可以通过输入参数的已定义SQL类型兼容的方法(例如,如果参数具有SQL类型为Integer,那么应该使用setInt()方法,也可以通过setObject()方法设置多种类型的输入参数)

需要注意的是,表中的setDate()方法可以设置日期内容,但参数Date的类型是java.sql.Date,而不是java.util.Date

六、ResultSet接口

ResultSet接口用于保存JDBC执行查询时返回的结果集,该结果集封装再一个逻辑表格中。在ResultSet接口内部有一个指向表格数据行的游标(或指针),ResultSet对象初始化时,游标在表格的第一行之前,调用next()方法作为while循环的条件来迭代ResultSet结果集。ResultSet接口中的常用方法如下所示。

ResultSet接口定义了大量的getXxx()方法,而采用哪种getXxx()方法取决于字段的数据类型。程序既可以通过字段的名称来获取指定数据,也可以通过字段的索引来获取指定的数据,字段的索引是从1开始编号的。例如,数据表的第一列字段名为id,字段类型为int,那么既可以使用getInt(1)获取该列的值,也可以使用getInt(“id”)获取该列的值。

实现第一个JDBC程序
1.搭建数据库环境
在MySQL中创建一一个名称为jdbc 的数据库,然后在该数据库中创建一一个users表,并向其插入数据
在这里插入图片描述
2.创建项目环境,导入数据库驱动
在Eclipse中新建一一个名称为chapter09的Web项目,将下载好的MySQL的数据库驱动文件mysql-connector-java-5.0.8- bnjan复制到项目的ib目录中,并发布到类路径下(MsSQL驱动文件可以在其官网地址: ht:/:/v.mysal.om/downloadsco.e.cor/页面中下载在浏览器中输入该地址后即可进入下载页面,单击页面Generally Available (GA) Releases窗口中的Looking for previous GA versions超链接后,在显示出的下拉框中下载所需的驱动版本即可
在这里插入图片描述
编写JDBC程序
在项目chapter09的srC目录下,新建一一个名称为cn.itcast.jdbc.example的包,在该包中创建类Example01,该类用于读取数据库中的users表,并将结果输出到控制台

package cn.itcast.jbdc.example;

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

public class Example01 {
     public static void main(String[] args) throws SQLException {
		Statement stmt=null;
		ResultSet rs=null;
		Connection conn=null;
		try {
			//1.注册数据库的驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.通过DriverManager获取数据库连接
			String url = "jdbc:mysql://localhost:3306/jdbc";
			String username = "root";
			String password = "123456";
			conn=DriverManager.getConnection(url, username, password);
			//3.通过Connection对象获取Statement对象
			stmt=conn.createStatement();
			//4.使用Statement执行SQL语句
			String sql="select * from users";
			rs=stmt.executeQuery(sql);
			//5.操作ResultSet结果集
			System.out.println("id | name  | password | email  | birthday");
			while (rs.next()) {
				int id=rs.getInt("id"); //通过列名获取指定字段的值
				String name = rs.getString("name");
				String psw = rs.getString("password");
				String email = rs.getString("email");
				String birthday = rs.getString("birthday");
				System.out.println(id + " | " + name + " | " + psw + " | " + email + " | " + birthday);
			}
		}catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
		   //6.回收数据库资源
			   	   
			   if(rs!=null) {
				   try {
					   rs.close();
				   } catch (SQLException e) {
					   e.printStackTrace();
				   }
				    rs=null;
			   }
			   if(stmt!=null) {
				   try {
					   stmt.close();
				   } catch (SQLException e) {
					   e.printStackTrace();
				   }
				    stmt=null;
			   }
			   if(conn!=null) {
				   try {
					   conn.close();
				   } catch (SQLException e) {
					   e.printStackTrace();
				   }
				    conn=null;
			   }
           }
      }
  }

PreparedStatement 对象
创建一个名称为Example02的类,在该类中使用PreparedStatement 对象对数据库进行插入数据的操作

package cn.itcast.jbdc.example;

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

public class Example02 {
     public static void main(String[] args) throws SQLException {
		Connection conn=null;
		PreparedStatement preStmt=null;
		    try {
		    	//加载数据库驱动
		    	Class.forName("com.mysql.jdbc.Driver");
		    	String url="jdbc:mysql://localhost:3306/jdbc";
		    	String username="root";
		    	String password="123456";
		    	//创建应用程序与数据库连接的Connection对象
		    	conn = DriverManager.getConnection(url, username, password);
		    	//执行的SQL语句
		    	String sql="INSERT INTO users(name,password,email,birthday)"
		    			+ "VALUES(?,?,?,?)";
		    	//创建执行SQL语句的PreparedStatement对象
		    	preStmt=conn.prepareStatement(sql);
		    	preStmt.setString(1, "zl");
		    	preStmt.setString(2, "123456");
		    	preStmt.setString(3, "zl@sina.com");
		    	preStmt.setString(4, "1789-12-23");
		    	preStmt.executeUpdate();
		    } catch (ClassNotFoundException e) {
		    	e.printStackTrace();
		    } finally {    //释放资源
		    	if (preStmt != null) {
		    		try {
		    			preStmt.close();
		    		} catch (SQLException e) {
		    			e.printStackTrace();
		    		}
		    		preStmt = null;
		    	}
		    	if (conn != null) {
		    		try {
		    			conn.close();
		    		} catch (SQLException e) {
		    			e.printStackTrace();
		    		}
		    		conn = null;
		    	}
		    }
	}
}

ResultSet 对象
ResultSet主要用于存储结果集,可以通过nex:()方法由前向后逐个获取结果集中的数据。如果想获取结果集中任意位置的数据,则需要在创建Statement对象时,设置两个ResutSet定义的常量,具体设置方式如下。

创建一个名称为Example03 的类,该类中使用ResultSet对象取出指定数据的信息

package cn.itcast.jbdc.example;

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

public class Example03 {
     public static void main(String[] args) {
		Connection conn = null;
		Statement stmt = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql://localhost:3306/jdbc";
			String username = "root";
			String password = "123456";
			//1.获取Connection对象
			conn = DriverManager.getConnection(url, username, password);
			String sql = "select * from users";
			//2.创建Statement对象并设置常量
			Statement st=conn.createStatement(
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
		    //3.执行SQL并将获取的数据信息存放在ResultSet中
			ResultSet rs=st.executeQuery(sql);
			//4.取出ResultSet中指定数据的信息
			System.out.println("第2条数据的name值为:");
			rs.absolute(2);     //将指针定位到结果集中的第2行数据
			System.out.println(rs.getString("name"));
			System.out.println("第1条数据的name值为:");
			rs.beforeFirst();   //将指针定位到结果集中的第1行数据之前
			rs.next();          //将指针向后滚动
			System.out.println(rs.getString("name"));
			System.out.println("第4条数据的name值为:");
			rs.afterLast();     //将指针定位到结果集中最后一条数据之后
			rs.previous();         //将指针向前滚动
			System.out.println(rs.getString("name"));		
		} catch (Exception e) {
	    	e.printStackTrace();
	    } finally {    //释放资源
	    	if (stmt != null) {
	    		try {
	    			stmt.close();
	    		} catch (SQLException e) {
	    			e.printStackTrace();
	    		}
	    		stmt = null;
	    	}
	    	if (conn != null) {
	    		try {
	    			conn.close();
	    		} catch (SQLException e) {
	    			e.printStackTrace();
	    		}
	    		conn = null;
	    	}
	    }
	}
}

创建一个名称为example03test的类,该类中使用ResultSet对象取出指定数据的信息

package cn.itcast.jbdc.example;

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

public class example03test {
     public static void main(String[] args) {
    	    	Connection con=null;
    	    	Statement stmt=null;
    	    	ResultSet rs=null;
    	    	try {    	    		
    			//1.注册驱动
    	    	Class.forName("com.mysql.jdbc.Driver");
    	    	//2.连接数据库
    	    	con=DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","123456");
    	    	//3.获取查询数据库
    	    	stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
    	    	//4.执行查询语句
    	    	rs=stmt.executeQuery("select * from users");
    	    	
    	    	rs.absolute(2);
    	    	System.out.println("第二行的数据"+rs.getString("name"));
    	    	rs.beforeFirst();
    	    	rs.next();
    	    	System.out.println("第一行的数据"+rs.getString("name"));
    	    	
    	    	
    	    	rs.afterLast();
    	    	rs.previous();
    	    	System.out.println("最后一行"+rs.getString("name"));
    	    }catch(Exception e) {
    	    	throw new RuntimeException(e);
    	    	
     }finally {
    	 //6.关闭连接,释放资源
    	 System.out.println("资源会被关闭吗----");
    	 
    	 if(rs!=null) {
    		 
    	 }
	   }
    }
}

使用JDBC完成数据的增删改查
1.创建JavaBean
创建一个用于保存用户数据的User类

package cn.itcast.jbdc.example;

import java.sql.Date;

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private Date birthDay;
    public int grtId() {
    	return id;
    }
    public void setId(int id) {
    	this.id=id;
    }
    public String getUsername() {
    	return username;
    }
    public void setUsername(String username) {
        this.username=username;
    }
    public String getPassword() {
    	return password;
    }
    public void setPassword(String password) {
    	this.password=password;
    }
    public String getEmail() {
    	return email;
    }
    public void setEmail(String email) {
    	this.email=email;
    }
    public Date getBirthDay() {
    	return birthDay;
    }
    public void setBirthDay(Date birthDay) {
    	this.birthDay=birthDay;
    }
}

2.创建工具类
由于每次操作数据库时,都需要加载数据库驱动、建立数据库连接以及关闭数据库连接,为了避免代码的重复书写,下面建立一个专门用于数据库相关操作的工具类

创建JDBCUtils工具类

package cn.itcast.jbdc.example;

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

public class JDBCUtils {
   //获取连接对象的方法
	public static Connection getCon() throws Exception{
		//1.注册和加载驱动
		Class.forName("com.mysql.jdbc.Driver");
		//2.获取连接
		Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","123456");
		return con;
	}
	
	//关闭连接,释放资源
	public static void realse(ResultSet rs,Statement stmt,Connection con) {
		if(rs!=null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			stmt=null;
		}
		if(con!=null) {
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			con=null;
		}
	}
}

3.创建DAO
创建一个名称为UsersDao的类,该类中封装了对表users 的添加、查询、删除和更新等操作

package cn.itcast.jbdc.example;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

public class UsersDao {
    //添加用户的操作
	public boolean insert(User user) {
		Connection conn=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {
			//获得数据的连接
			conn=JDBCUtils.getCon();
			//获得Statement对象
			stmt=conn.createStatement();
			//发送SQL语句
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String birthday=sdf.format(user.getBirthDay());
			String sql="INSERT INTO users(id,name,password,email,birthday) "+
			"VALUES("
			+user.getId()+",'"
			+user.getUsername()+"','"
			+user.getPassword()+"','"
			+user.getEmail()+"','"
			+birthday + "')";
			int num=stmt.executeUpdate(sql);
			if(num>0) {
				return true;
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
		JDBCUtils.realse(rs, stmt, conn);
		}
		 return false;
	}
    //查询所有的User对象
    public ArrayList<User> findAll() {
    	Connection conn=null;
		Statement stmt=null;
		ResultSet rs=null;
		ArrayList<User> List = new ArrayList<User>();
		try {
			//获得数据的连接
			conn=JDBCUtils.getCon();
			//获得Statement对象
			stmt=conn.createStatement();
			//发送SQL语句
			String sql = "SELECT * FROM users";
			rs = stmt.executeQuery(sql);
			//处理结果集
			while (rs.next()) {
				User user = new User();
				user.setId(rs.getInt("id"));
				user.setUsername(rs.getString("name"));
				user.setPassword(rs.getString("password"));
				user.setEmail(rs.getString("email"));
				user.setBirthDay(rs.getDate("birthday"));
				List.add(user);
			}
			return List;
    } catch (Exception e) {
    	e.printStackTrace();
    } finally {
    	JDBCUtils.realse(rs, stmt, conn);
    }
    return null;
    }
	//根据id查找指定的user
	public User find(int id) {
		Connection conn=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {
			//获得数据的连接
			conn=JDBCUtils.getCon();
			//获得Statement对象
			stmt=conn.createStatement();
			//发送SQL语句
			String sql = "SELECT * FROM users WHERE id=" + id;
			rs = stmt.executeQuery(sql);
			//处理结果集
			while (rs.next()) {
				User user = new User();
				user.setId(rs.getInt("id"));
				user.setUsername(rs.getString("name"));
				user.setPassword(rs.getString("password"));
				user.setEmail(rs.getString("email"));
				user.setBirthDay(rs.getDate("birthday"));
				return user;
			}
			return null;
    } catch (Exception e) {
    	e.printStackTrace();
    } finally {
    	JDBCUtils.realse(rs, stmt, conn);
    }
    return null;
    }
	//删除方法
	public boolean delete(int id) {
		Connection conn=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {
			//获得数据的连接
			conn=JDBCUtils.getCon();
			//获得Statement对象
			stmt=conn.createStatement();
			//发送SQL语句
			String sql="DELETE FROM users WHERE id=" + id;
			int num=stmt.executeUpdate(sql);
			if(num>0) {
				return true;
			}
			return false;
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
		JDBCUtils.realse(rs, stmt, conn);
		}
		 return false;
	}
	//修改用户
	public boolean update(User user) {
		Connection conn=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {
			//获得数据的连接
			conn=JDBCUtils.getCon();
			//获得Statement对象
			stmt=conn.createStatement();
			//发送SQL语句
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String birthday=sdf.format(user.getBirthDay());
			String sql="UPDATE users set name='" + user.getUsername()
			+ "',password='" + user.getPassword() + "',email='"
			+user.getEmail() + "',birthday='" + birthday
			+ "' WHERE id=" + user.getId();    
			int num=stmt.executeUpdate(sql);
			if(num>0) {
				return true;
			}
			return false;
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
		JDBCUtils.realse(rs, stmt, conn);
		}
		 return false;
	}
}

4.创建测试类
编写测试类JdbcInsertTest实现向users 表中添加数据的操作

package cn.itcast.jbdc.example;

import java.sql.Date;
import cn.itcast.jbdc.example.UsersDao;
import cn.itcast.jbdc.example.User;
public class JdbcInsertTest {
     public static void main(String[] args) {
		//向user表插入一个用户信息
    	UsersDao ud=new UsersDao();
		User user=new User();
		
		user.setId(5);
		user.setUsername("hl");
		user.setPassword("123");
		user.setEmail("hl@sina.com");
		user.setBirthDay(new Date());
		
		boolean flag=ud.insert(user);
		
		System.out.println(flag);
	}
}

编写测试类FindAllUsersTest,该类用于实现读取users

package cn.itcast.jbdc.example;

import java.util.ArrayList;

public class FindAllUserTest {
     public static void main(String[] args) {
		//创建一个名称为usersDao的对象
    	 UsersDao usersDao=new UsersDao();
    	 //将UsersDao对象的findAll()方法执行后的结果放入list集合
    	 ArrayList<User> list = usersDao.findAll();
    	 //循环输出集合中的数据
    	 for (int i = 0; i < list.size(); i++) {
    		 System.out.println("第" + (i + 1) + "条数据的username值为:"
    				 + list.get(i).getUsername());
    	 }
	}
}

编写测试类FindUserByldTest,在该类中实现读取users表中指定的数据

package cn.itcast.jbdc.example;

public class FindUserByldTest {
     public static void main(String[] args) {
		UsersDao usersDao = new UsersDao();
		User user = usersDao.find(1);
		System.out.println("id为1的User对象的name值为:" + user.getUsername());
	}
}

编写测试类UpdateUserTest,在该类中实现修改sers表中数据的操作

package cn.itcast.jbdc.example;

public class UpdateUserTest {
    public static void main(String[] args) {
		//修改User对象的数据
    	UsersDao usersDao = new UsersDao();
    	User user = new User();
    	    user.setId(4);
    	    user.setUsername("zhaoxiaoliu");
    	    user.setPassword("456");
    	    user.setEmail("zhaoxiaoliu@sina.com");
    	    user.setBirthDay(new Date());
    	    boolean b = usersDao.update(user);
    	    System.out.println(b);
	}
}

编写测试类DeleteUserTest, 该类实现了删除users表中数据的操作

package cn.itcast.jbdc.example;
public class DeleteUserTest {
     public static void main(String[] args) {
		//删除操作
    	UsersDao usersDao=new UsersDao();
    	boolean b = usersDao.delete(4);
    	System.out.println(b);
	}
}

在这里插入图片描述


版权声明:本文为ll2487215826原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。