29.jdbc基础

@一贤不穿小鞋

1.jdbc:java连接数据库的技术.

2.jdbc工作原理

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

3.导入Jar包的方式

在这里插入图片描述

4.jdbc常用接口和类

  • DriverManager类的常用方法
    在这里插入图片描述
  • statement的常用方法
    在这里插入图片描述
  • ResultSet的常用方法
    在这里插入图片描述

5.用jdbc对数据库中数据作增加,修改,删除操作

eg:	//声明连接对象和执行对象
		Connection conn=null;
		Statement state=null;
		
		try {
			//1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.创建连接
			 conn=DriverManager.getConnection(
			 "jdbc:mysql://localhost:3306/2008myschool", "root", "root");
			//3.准备sql语句
			 //新增
			//String sql="
			insert into t_student(sid,sname,sage,ssex,saddress,cid) 
			values(12,'小明',18,'男',default,3)";
			//修改
			//String sql="update t_student set saddress='深圳'  where sid=12";
			 //删除
			 String sql="delete from t_student where sid=12";
			 
			 //4.创建执行对象
			state=conn.createStatement();
			//5.用执行对象调用方法将sql语句传到数据库中去执行,并得到结果
			int result=state.executeUpdate(sql);
			//6.处理结果
			if (result>0) {
				System.out.println("操作成功!");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//7.关闭对象
			if (state!=null) {
				state.close();
			}
			if (conn!=null) {
				conn.close();
			}
		}
	}

6.用jdbc对数据库中数据进行查询

eg:public static void main(String[] args) throws Exception {
		//声明连接对象,执行对象,结果集对象
		Connection conn=null;
		Statement state=null;
		ResultSet rs=null;
		
		try {
			//1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.创建连接对象
			conn=DriverManager.getConnection(
			"jdbc:mysql://localhost:3306/2008myschool", "root", "root");
			//3.准备sql语句
			String sql="select sid,sname,sage,ssex,saddress,cid from t_student";
			//4.创建执行对象
			state=conn.createStatement();
			//5.用执行对象将sql语句传到数据库中去执行,并得到结果
			rs=state.executeQuery(sql);
			//6.处理结果
			System.out.println("学号\t姓名\t年龄\t性别\t地址\t班级编号");
			while (rs.next()) {
				//通过列名获得当前这一行每列的值并存在变量(推荐)
				int id=rs.getInt("sid");
				String name=rs.getString("sname");
				int age=rs.getInt("sage");
				String sex=rs.getString("ssex");
				String address=rs.getString("saddress");
				int className=rs.getInt("cid");
				
				//通过列的编号获得当前这一行每列的值并存在变量中
//				int id=rs.getInt(1);
//				String name=rs.getString(2);
//				int age=rs.getInt(3);
//				String sex=rs.getString(4);
//				String address=rs.getString(5);
//				int className=rs.getInt(6);
				
				System.out.println(id+"\t"+name+"\t"+age+"\t"+sex+"\t"+address+"\t"+className);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//7.关对象
			if (rs!=null) {
				rs.close();
			}
			if (state!=null) {
				state.close();
			}
			if (conn!=null) {
				conn.close();
			}
		}
	}

7.PreparedStatement预编译的执行对象.是statement的子接口.

7.1:PreparedStatement配合占位传参方法一起使用,可以有效的防止Sql注入.

7.2:PreparedStatement比statement执行效率和灵活性更高.

在这里插入图片描述

	eg:public static void main(String[] args) throws Exception {
		Scanner input=new Scanner(System.in);
		
		System.out.println("请输入用户名:");
		String uname=input.next();
		System.out.println("请输入密码:");
		String upwd=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/2008myschool", "root", "root");
			//3.准备sql语句,?是sql语句中占位符
			String sql=
			"select account,user,password,money from t_bank where user=? and password=? ";
			System.out.println(sql);
			//4.创建预编译的执行对象
			state=conn.prepareStatement(sql);
			
			//给执行对象中sql语句的占位符传递
			state.setString(1, uname);
			state.setString(2, upwd);
			
			//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();
			}
		}
	}

8.单元测试:是指对软件中的最小可测试单元进行检查和验证.

  • 编写一段测试某个方法是否能按正常流程来执行.

8.1:单元测试规范

  • 选中项目名->右键new->Source Folder->新建一个test文件夹->选中test文件夹新建一个与原类相同的包名,再创建一个测试类,测试类的类名由原类名Test组成.

8.2:注意事项

  • 单元测试的方法不能是静态方法.单元测试的方法一般无参无返回值的.

8.3:单元测试的使用步骤:

8.3.1:导测试包:选中项目名右键->Build path->Add Libraries->Junit->选择一个版本的包->finish.

8.3.2:在测试类中测试方法前面@org.junit.Test

8.3.3:选中测试方法名->右键->run as->Junit Test

9.jdbc工具类的封装:

9.1:为了调用方法

  • 工具类中方法一般声明为静态方法,又因为静态方法中只能直接调用静态变量,所以工具类中成员变量声明为静态变量.

9.2:将固定步骤封装到方法中,将变量数据作方法的参数或返回值.

  • 一般情况下,将执行功能的所需要的数据封装成方法参数.
  • 方法执行的结果作为方法的返回值.
eg:public class DBUtils {
	/*
	 * 声明连接对象和执行对象,结果集对象
	 */
	public static Connection conn=null;
	public static PreparedStatement state=null;
	public static ResultSet rs=null;
	
	/**
	 * 获得连接对象的方法
	 * @return Connection
	 */
	public static Connection getConnection() {
		try {
			//1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2.创建连接对象
			conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/2008myschool", "root", "root");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	/**
	 * 执行增加,修改,删除的sql语句
	 * @param sql 要执行的sql语句
	 * @param args sql参数,要求sql语句的参数按占符符顺序来传参
	 * @return int
	 */
	public static int update(String sql,Object...args) {
		//声明一个变量存结果
		int result1=0;
		try {
			//调用获得连接对象的方法
			conn=getConnection();

			 //4.创建执行对象
			state=conn.prepareStatement(sql);
			//给预编译的执行对象传递参数
			if (args!=null) {
				for (int i = 0; i < args.length; i++) {
					//要求sql语句的参数按占符符顺序来传参
					state.setObject(i+1, args[i]);
				}
			}
			
			//5.用执行对象调用方法将sql语句传到数据库中去执行,并得到结果
			result1=state.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result1;
	}

	/**
	 * 执行查询的sql语句
	 * @param sql 要执行的sql语句
	 * @param args sql参数,要求sql语句的参数按占符符顺序来传参
	 * @return
	 */
	public static ResultSet query(String sql,Object...args) {
		try {
			//调用获得连接对象的方法
			conn=getConnection();
			
			//4.创建预编译的执行对象
			state=conn.prepareStatement(sql);
			
			//给预编译的执行对象传递参数
			if (args!=null) {
				for (int i = 0; i < args.length; i++) {
					//要求sql语句的参数按占符符顺序来传参
					state.setObject(i+1, args[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();
		}
	}
}

9.3:升级jdbc工具类

  • 将原来工具类中以硬编码(直接写代码)获取配置信息,以软编码(配置文件的方式存配置信息,再加载配置信息)来升级,让jdbc可以跨应用系统.
eg:/**
 * 封装jdbc工具类
 * @author sx
 * @version 1.0 2020年11月13日
 */
public class DBUtils {
	/*
	 * 声明连接对象和执行对象,结果集对象
	 */
	public static Connection conn=null;
	public static PreparedStatement state=null;
	public static ResultSet rs=null;
	public static Properties p1=null;
	
	static {
		try {
			/*第二种:以配置文件方式存配置信息,用流读取*/
			//创建配置文件对象
			p1=new Properties();
			//用对象调用方法读取配置文件
			//p1.load(new FileInputStream("src/jdbc.properties"));//直接读
			//取src路径下配置文件,适用于java工程
			//用流读取编译后bin目录下jdbc.properties
			p1.load(DBUtilsTest1.class.getClassLoader()
			.getResourceAsStream("jdbc.properties"));//适用于所有java工程
			//1.加载驱动
			Class.forName(p1.getProperty("driver"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获得连接对象的方法
	 * @return Connection
	 */
	public static Connection getConnection() {
		try {
			/*第一种:以硬编码的方式写配置信息*/
//			//1.加载驱动
//			Class.forName("com.mysql.jdbc.Driver");
//			//2.创建连接对象
//			conn=DriverManager.getConnection(
				"jdbc:mysql://localhost:3306/2008myschool", "root", "root");
			
			//2.创建连接对象
			conn=DriverManager.getConnection(
			p1.getProperty("url"), p1.getProperty("username"), p1.getProperty("password"));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	/**
	 * 执行增加,修改,删除的sql语句
	 * @param sql 要执行的sql语句
	 * @param args sql参数,要求sql语句的参数按占符符顺序来传参
	 * @return int
	 */
	public static int update(String sql,Object...args) {
		//声明一个变量存结果
		int result1=0;
		try {
			//调用获得连接对象的方法
			conn=getConnection();

			 //4.创建执行对象
			state=conn.prepareStatement(sql);
			//给预编译的执行对象传递参数
			if (args!=null) {
				for (int i = 0; i < args.length; i++) {
					//要求sql语句的参数按占符符顺序来传参
					state.setObject(i+1, args[i]);
				}
			}
			
			//5.用执行对象调用方法将sql语句传到数据库中去执行,并得到结果
			result1=state.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result1;
	}

	/**
	 * 执行查询的sql语句
	 * @param sql 要执行的sql语句
	 * @param args sql参数,要求sql语句的参数按占符符顺序来传参
	 * @return
	 */
	public static ResultSet query(String sql,Object...args) {
		try {
			//调用获得连接对象的方法
			conn=getConnection();
			
			//4.创建预编译的执行对象
			state=conn.prepareStatement(sql);
			
			//给预编译的执行对象传递参数
			if (args!=null) {
				for (int i = 0; i < args.length; i++) {
					//要求sql语句的参数按占符符顺序来传参
					state.setObject(i+1, args[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();
		}
	}
	
	/**
	 * 关闭所有实现了AutoCloseable对象的方法
	 */
	public static void closeObject2(AutoCloseable...obs) {
		for (int i = 0; i < obs.length; i++) {
			try {
				obs[i].close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

10.编码问题

  • 用jdbc将java程序中数据存储到数据库中时如果有乱码问题解决:

10.1:解决方案一

  • 将编译器工作空间的编码方式与MySql数据库管理系统的编码,以及创建数据库编码都设置为utf-8.

10.2:解决方案二

  • 在连接字符串中设置编码
  • url=jdbc:mysql://localhost:3306/companydb?useUnicode=true&characterEncoding=utf8

10.3:如果控制台接收中文数据是gbk,编译器工作空间是utf-8,接收数据乱码问题解决

  • String s1=接收控制台中文数据;
    s1=new String(s1.getBytes(“gbk”), “utf-8”);

10.4:如果mysql高版本时区问题,在连接字符串设置时区

  • url=jdbc:mysql://localhost:3306/2008mysql? &useSSL=false&serverTimezone=UTC&serverTimezone=GMT%2B8

总结:
1.sql的DCL,重点掌握数据库的备份和还原
2.事务(重点)
3.视图
4.jdbc的工作原理(重点)
5.jdbc的四大金刚及常用方法(重点)
6.jdbc的执行增加,修改,删除操作(重点)
7.jdbc的执行查询操作(重点)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值