JDBC入门2

JDBC

1.PreparedStatement预编译的执行对象.是statement的子接口.
1.1:PreparedStatement配合占位传参方法一起使用,可以有效的防止Sql注入.
1.2:PreparedStatement比statement执行效率和灵活性更高.
在这里插入图片描述

public static void main(String[] args) throws SQLException {
		Scanner input=new Scanner(System.in);
		/*从键盘上接收登录信息*/
		System.out.println("请输入登录名:");
		String loginName=input.next();
		System.out.println("请输入登录密码:");
		String loginPwd=input.next();
		
		//声明连接对象,执行对象,结果集对象
		Connection conn=null;
		PreparedStatement state=null;
		ResultSet rs=null;
		
		try {
			//1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.创建连接对象
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool","root","root");
			//3.准备Sql语句,?表示占位符,占位符从1开始计数的
			String sql="select uid,uname,age,address,upassword " 
					+" from t_user where uname=? and upassword=?";
			System.out.println("***"+sql);
			//4.创建预编译执行对象,将sql语句编译好
			state=conn.prepareStatement(sql);
			//向sql语句中占位符的位置上传参数,第一个参数是占位符的位置,第二个参数是要传的参数
			state.setString(1, loginName);
			state.setString(2, loginPwd);
			
			//5.用执行对象调用相应的方法将Sql语句传到数据库中去执行,并得到返回结果
			rs=state.executeQuery();
			//6.处理结果
			//读取结果集中第一行,如果第一行有数据说明登录成功,没有数据说明登录失败
			if (rs.next()) {
				System.out.println("登录成功");
			}else {
				System.out.println("登录失败");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//7.关闭对象,释放资源,先开后关
			if (rs!=null) {
				rs.close();
			}
			if (state!=null) {
				state.close();
			}
			if (conn!=null) {
				conn.close();
			}
		}
	}

2.jdbc工具类:
2.1:为了调用方法:工具类中方法一般声明为静态方法,又因为静态方法中只能直接调用 静态变量,所以工具类中成员变量声明为静态变量.
2.2:将固定步骤封装到方法中,将变量数据作方法的参数或返回值.
一般情况下,将执行功能的所需要的数据封装成方法参数.
方法执行的结果作为方法的返回值.

/**
 * jdbc工具类
 */
public class DBUtils {
	/**
	 * 声明连接对象,执行对象,结果集对象
	 */
	public static Connection conn=null;
	public static PreparedStatement state=null;
	public static ResultSet rs=null;
	
	/**
	 * 获得连接对象的方法
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 */
	public static Connection getConnection() throws ClassNotFoundException, SQLException {
		//1.加载驱动
		Class.forName("com.mysql.jdbc.Driver");
		//2.创建数据连接对象
		conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool", "root", "root");
		return conn;
	}
	
	/**
	 * 用jdbc执行增加,修改,删除的Sql语句 
	 * @param sql 要执行的sql语句
	 * @param obs Sql语句的动态参数
	 * @return int
	 */
	public static int update(String sql,Object...obs) {
		//声明一个变量存执行的结果
		int result=0;
		try {
			//调用获得连接对象的方法
			conn=getConnection();
			
			//4.创建执行对象
			state=conn.prepareStatement(sql);
			//给执行对象中sql语句传参
			for (int i = 0; i < obs.length; i++) {
				state.setObject(i+1, obs[i]);
			}
			
			//5.让执行对象调用相应的方法将Sql语句传到数据库去执行,并接收结果
			result=state.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 *  用jdbc执行查询的Sql语句 
	 * @param sql 要执行sql语句
	 * @param obs sql的动态参数
	 * @return ResultSet
	 */
	public static ResultSet query(String sql,Object...obs) {
		try {
			//调用获得连接对象的方法
			conn=getConnection();
			
			//4.创建执行对象
			state=conn.prepareStatement(sql);
			//给执行对象中的Sql语句传参,数组的索引从0开始,但是点位符索引从1开始的
			for (int i = 0; i < obs.length; i++) {
				state.setObject(i+1, obs[i]);
			}
			
			//5.用执行对象调用相应的方法将Sql语句传到数据库中去执行,并接收执行结果
			 rs=state.executeQuery();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rs;
	}
	
	/**
	 * 关闭jdbc对象的方法
	 */
	public static void closeObject() {
		try {
			if (rs!=null) {
				rs.close();
			}
			if (state!=null) {
				state.close();
			}
			if (conn!=null) {
				conn.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

3.单元测试:是指对软件中的最小可测试单元进行检查和验证.(编写一段测试某个方法是否能 按正常流程来执行.);
3.1:单元测试规范:选中项目名->右键new->Source Folder->新建一个test文件夹->选中 test文件夹新建一个与原类相同的包名,再创建一个测试类,测试类的类 名由原类名Test组成.
3.2:注意事项:单元测试的方法不能是静态方法.单元测试的方法一般无参无返回值的.
3.3:单元测试的使用步骤:
3.3.1:导测试包:选中项目名右键->Build path->Add Libraries->Junit->选择一 个版本的包->finish.
3.3.2:在测试类中测试方法前面@org.junit.Test
3.3.3:选中测试方法名->右键->run as->Junit Test

:import org.junit.Test;

/**
 * 测试类
 * @author sx
 * @version 2020年2月14日
 */
public class DBUtilsTest {
	/**
	 * 测试工具类中插入sql的方法
	 */
	@Test
	public void updateTest1() {
		//准备sql语句
		String sql="insert into t_user(uname,age,address,upassword) values(?,?,?,?)";
		//调用工具类中相应的方法
		int result=DBUtils.update(sql,"杨旭辉",20,"千锋","123456");
		//处理结果
		if (result>0) {
			System.out.println("操作成功");
		} else {
			System.out.println("操作失败");
		}
		//调用工具类中关闭的方法
		DBUtils.closeObject();
	}
	
	/**
	 * 测试工具类中修改sql的方法
	 */
	@Test
	public void updateTest2() {
		//准备sql语句
		String sql="update t_user set age=? where uid=?";
		//调用工具类中相应的方法
		int result=DBUtils.update(sql,80,3);
		//处理结果
		if (result>0) {
			System.out.println("操作成功");
		} else {
			System.out.println("操作失败");
		}
		//调用工具类中关闭的方法
		DBUtils.closeObject();
	}
	
	/**
	 * 测试工具类中删除sql的方法
	 */
	@Test
	public void updateTest3() {
		//准备sql语句
		String sql="delete from t_user where uid=?";
		//调用工具类中相应的方法
		int result=DBUtils.update(sql,3);
		//处理结果
		if (result>0) {
			System.out.println("操作成功");
		} else {
			System.out.println("操作失败");
		}
		//调用工具类中关闭的方法
		DBUtils.closeObject();
	}
	
	/**
	 * 测试工具类中查询sql的方法
	 */
	@Test
	public void queryTest1() {
		
		 try {
			//准备sql语句
			String sql="select uid,uname,age,address,upassword from t_user";
			//调用工具类中相应的方法
			 DBUtils.rs=DBUtils.query(sql);
			//处理结果
			 System.out.println("编号\t用户名");
			while (DBUtils.rs.next()) {
				//读取当前行的结果,获得指定列的值并存入到变量中
				int uid=DBUtils.rs.getInt("uid");
				String uname=DBUtils.rs.getString("uname");
				 System.out.println(uid+"\t"+uname);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//调用工具类中关闭的方法
			DBUtils.closeObject();
		}
	}
	
	/**
	 * 测试工具类中查询sql的方法
	 */
	@Test
	public void queryTest2() {
		
		 try {
			//准备sql语句
			String sql="select count(uid) from t_user";
			//调用工具类中相应的方法
			 DBUtils.rs=DBUtils.query(sql);
			//处理结果
			while (DBUtils.rs.next()) {
				//读取当前行的结果,获得指定列的值并存入到变量中
				int count=DBUtils.rs.getInt(1);
				System.out.println("表中记录数为:"+count);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//调用工具类中关闭的方法
			DBUtils.closeObject();
		}
	}
}

4.批处理:一次性同时执行多条Sql语句.批处理是用于增加,修改,删除的Sql语句.
批处理的作用:减少应用程序与数据库的交互次数,提高效率.

5.批量执行多条不同Sql语句(用statement对象)

public static void main(String[] args) throws SQLException {
		//声明连接对象和执行对象
		Connection conn=null;
		Statement state=null;
		
		try {
			//1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.创建数据连接对象
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool", "root", "root");
			//3.准备Sql语句
			String sql1="insert into t_user(uname,age,address,upassword) values('吴慧贤',18,'千锋','123456')";
			String sql2="insert into t_user(uname,age,address,upassword) values('高圆圆',22,'千锋','123456')";
			String sql3="insert into t_user(uname,age,address,upassword) values('吴毅恒',22,'千锋','123456')";
			String sql4="insert into t_user(uname,age,address,upassword) values('张杨',24,'千锋','123456')";
			String sql5="update t_user set address='中国' where uid=2";
			String sql6="delete from t_user where uid=1";
			//4.创建执行对象
			state=conn.createStatement();
			//5.将Sql语句添加到执行对象的批处理中
			state.addBatch(sql1);
			state.addBatch(sql2);
			state.addBatch(sql3);
			state.addBatch(sql4);
			state.addBatch(sql5);
			state.addBatch(sql6);
			//6.用执行调用相应的方法将批处理sql语句传到数据库中去执行,并接收结果
			int[] results=state.executeBatch();
			//7.处理结果
			for (int i = 0; i < results.length; i++) {
				System.out.println(results[i]);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//8.关闭对象
			if (state!=null) {
				state.close();
			}
			if (conn!=null) {
				conn.close();
			}
		}
	}

6.批量执行多条相同Sql语句,sql参数数据不同(用PreparedStatement执行对象)

public static void main(String[] args) throws SQLException {
		//声明连接对象和执行对象
		Connection conn=null;
		PreparedStatement state=null;
		
		try {
			//1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.创建数据连接对象
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool", "root", "root");
			//3.准备Sql语句
			String sql="insert into t_user(uname,age,address,upassword) values(?,?,?,?)";
			//4.创建执行对象
			state=conn.prepareStatement(sql);
			
			//5.将Sql语句参数添加到执行对象的批处理中
			for (int i = 1; i <=100; i++) {
				state.setString(1, "张伟"+i);
				state.setInt(2, 20+i);
				state.setString(3, "千锋");
				state.setString(4, "123456"+i);
				//将当前这条Sql语句的参数传到批处理中
				state.addBatch();
			}
			
		
			//6.用执行调用相应的方法将批处理sql语句传到数据库中去执行,并接收结果
			int[] results=state.executeBatch();
			//7.处理结果
			for (int i = 0; i < results.length; i++) {
				System.out.print(results[i]);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//8.关闭对象
			if (state!=null) {
				state.close();
			}
			if (conn!=null) {
				conn.close();
			}
		}
	}

7.批量执行多条相同的Sql语句,参数不同,分批次提交(用preparedstatement)

public static void main(String[] args) throws SQLException {
		//声明连接对象和执行对象
		Connection conn=null;
		PreparedStatement state=null;
		
		try {
			//1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.创建数据连接对象
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool", "root", "root");
			//3.准备Sql语句
			String sql="insert into t_user(uname,age,address,upassword) values(?,?,?,?)";
			//4.创建执行对象
			state=conn.prepareStatement(sql);
			
			//5.将Sql语句参数添加到执行对象的批处理中
			for (int i = 1; i <=100; i++) {
				state.setString(1, "李盛升"+i);
				state.setInt(2, 20+i);
				state.setString(3, "千锋");
				state.setString(4, "123456"+i);
				//将当前这条Sql语句的参数传到批处理中
				state.addBatch();
				
				if (i%10==0) {
					//6.用执行调用相应的方法将批处理sql语句传到数据库中去执行,并接收结果
					int[] results=state.executeBatch();
					//7.处理结果
					for (int j = 0; j < results.length; j++) {
						System.out.print(results[j]+"\t");
					}
					//清空批处理中sql语句及参数
					state.clearBatch();
					//执行完一批处理就换行
					System.out.println();
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//8.关闭对象
			if (state!=null) {
				state.close();
			}
			if (conn!=null) {
				conn.close();
			}
		}
	}

课堂笔记,留着备用!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值