JDBC连接数据库步骤(入门到进阶全)

news/2024/11/14 15:55:04/

目录

一、JDBC是什么?

二,JDBC的本质是什么?

为什么要用面向接口编程?

 三、JDBC实现原理

 四、使用idea开发JDBC代码配置驱动

​编辑 五、JDBC编程六步概述

 六、JDBC编程实现

1.插入实现

2.删除与更新实现

3 .类加载的方式注册驱动

​编辑 4. 从属性资源文件中读取数据库信息

 5.查询结果集实现

​编辑 6.模拟用户登陆​编辑

7.JDBC事务机制

 账户转账案例演示

七、 JDBC工具类的封装


一、JDBC是什么?

Java DataBase Conectivity(Java语言连接数据库)

二,JDBC的本质是什么?

JDBC是SUN公司制定的一套接口,在java.sql.*包,属于面向接口编程。

接口都有调用者和实现着,面向接口调用、面向接口写实现类,这都属于面向接口编程。

为什么要用面向接口编程?

  解耦合:降低程序的耦合度,提高程序的扩展力(耦合是指两个子类的关联程度)

多态机制就是典型的面向抽象编程(接口是抽象的)。

多态:父类型引用指向子类型对象

Animal是父类,cat、dog是子类

其中feed方法,写了cat只能喂养cat,写了dog只能喂养dog,但写animal既可以喂养dog也可以喂养cat。这就是面向抽象编程
 

 

 三、JDBC实现原理

 四、使用idea开发JDBC代码配置驱动

1.先从官网下载对应的驱动jar包

2.建立idea项目后

 3.

 4.找到自己下载jar包的位置并选择

5.点击应用、OK后会看到导入到jar包 

 五、JDBC编程六步概述

 

 六、JDBC编程实现

1.插入实现

 

 

public class ConnectionTest {public static void main(String[] args)  {Connection conn = null;Statement stmt = null;try {
//            注册驱动Driver driver = new  com.mysql.cj.jdbc.Driver();DriverManager.registerDriver(driver  );
//获取链接//  127.0.0.1 主机地址表示本机,3306 数据库端口号,test:数据库名称 问号部分表示时区,有的数据库版本可不加String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT";
//root 数据库连接名String user= "root";
//数据库密码String password = "123456";conn = DriverManager.getConnection(url,user,password);System.out.println("数据库连接对象"+conn);
//            获取数据库操作对象(Statement专门执行SQL语句的)stmt = conn.createStatement();
//          执行SQLString sql = "insert into student(id) values(1)";
//专门执行DML语句返回值是数据库中记录条数int count = stmt.executeUpdate(sql);System.out.println(count == 1?"保存成功":"保存失败");} catch (Exception e) {e.printStackTrace();
//释放资源
//            为了保证资源一定释放。在finally语句块关闭资源并且从小到依次关闭,必须分开try}finally{if(stmt != null){try {stmt.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn != null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}
//通过coon连接对象开启stmt,就得先关闭stmt}}

2.删除与更新实现

 public static void main(String[] args) {Connection conn1 = null;Statement stat1 = null;try {
//            1.注册驱动DriverManager.registerDriver( new com.mysql.cj.jdbc.Driver());
//            2.获取链接conn1 = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root","123456");
//            3.获取数据库操作对象stat1 = conn1.createStatement();//             4.执行SQL语句
//            String  str1 = "delete from student where id = 3";
//            String str1 = "insert into student(id) value (3)";String str1 ="update user_table set password = 'abc123',balance = '1000' where user = 'AA'";int count = stat1.executeUpdate(str1);//System.out.println(count == 1?"删除成功" :" 删除失败");}catch (SQLException e){e.printStackTrace();}finally {if (stat1 !=null){try {stat1.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn1 !=null) {try {conn1.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}

3 .类加载的方式注册驱动

 4. 从属性资源文件中读取数据库信息

1.创建配置文件

2.配置文件内容

注意:必须将配置文件放在src文件下 

 

public static void main(String[] args) {
//        使用资源绑定器绑定属性配置文件ResourceBundle bundle = ResourceBundle.getBundle("jdbc1");String driver = bundle.getString("driver");String url = bundle.getString("url");String user = bundle.getString("user");String password = bundle.getString("password");Connection conn = null;Statement stat = null;try {
//            注册成功Class.forName(driver);
//            获取链接conn = DriverManager.getConnection(url,user,password);
//            获取数据库操作对象stat = conn.createStatement();
//            执行SQL语句String str = "insert into student(id) values(2)";int count = stat.executeUpdate(str);System.out.println(count == 1 ?"插入成功":"插入失败");} catch (Exception e) {e.printStackTrace();}finally {
//            释放资源if(stat != null){try {stat.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn != null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}

 5.查询结果集实现

public static void main(String[] args) {Statement stat = null;Connection conn = null;//  rs封装查询结果集,有查询结果集必须带这句ResultSet rs = null;try {//        注册成功Class.forName("com.mysql.cj.jdbc.Driver");
//            获取链接conn =  DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root","123456");
//            连接数据库操作对象stat = conn.createStatement();
//            执行sqlString sal = "select name as n,id,email,birth from customers";
//            int excuteUpdate(insert/delete/update)
//            ResultSet excuteQuery(select)rs = stat.executeQuery(sal);
//            处理查询结果集
/*boolean flag1 = rs.next();//next()表示指向标中数据下一行
if(flag1){
//如果光标指向的行有数据取数据,
//getstring方法特点:不管数据库中的数据类型是什么,都以String的形式取出String name = rs.getString(1);//JDBC中所以下标从一开书。。String id = rs.getString(2);String email = rs.getString(3);String birth = rs.getString(4);System.out.println(name+","+id+","+email+","+birth);
}*/
while(rs.next()){/*String name = rs.getString("n");//没有别名可以直接写数据库表属性名String id = rs.getString("id");String email = rs.getString("email");String birth = rs.getString("birth");System.out.println(name+","+id+","+email+","+birth) ;*///1234表示表列数,类型和数据库表属性类型相一致,优势:方便计算,如工资涨100可直接输出salary+100String name = rs.getString(1);int id = rs.getInt(2);String email = rs.getString(3);String photo = rs.getString(4);System.out.println(name+","+id+","+email+","+"birth") ;
}} catch (Exception e) {e.printStackTrace();}finally{if(rs!=null){try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(stat!=null){try {stat.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn!=null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}

next()方法


 6.模拟用户登陆

 建立数据库表

 

  public static void main(String[] args) {
//        初始化一个界面Map<String,String> usserLoginInfo = initUI();
//        验证用户名和密码boolean loginSuccess =login(usserLoginInfo);
//        最后输出结果System.out.println(loginSuccess ? "登陆成功" :"登陆失败");}/**** @param usserLoginInfo 用户登录信息* @return false表示失败 true表示成功*/private static boolean login(Map<String, String> usserLoginInfo) {boolean loginSuccess =false;Statement stat = null;Connection conn = null;ResultSet rs = null;String loginName = usserLoginInfo.get("loginName");String loginPwd = usserLoginInfo.get("loginPwd");try {
//            注册驱动Class.forName("com.mysql.cj.jdbc.Driver");
//            获取链接conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root","123456");
//            连接数据库操作对象stat = conn.createStatement();
//            执行sqlString str = "select * from t_user where loginName = '"+loginName+"' and loginPwd = '"+loginPwd+"'";rs = stat.executeQuery(str);
//             处理结果集if(rs.next()){loginSuccess = true;//如果查询到结果,赋予true}} catch (Exception e) {e.printStackTrace();}finally {if(rs!=null){try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(stat!=null){try {stat.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn!=null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}return loginSuccess;}/*** 初始化用户界面@return 用户输入的用户名和密码*/private static Map<String, String> initUI() {Scanner s = new Scanner(System.in);System.out.println("用户名");String loginName = s.nextLine();System.out.println("密码");String  loginPwd = s.nextLine();
//        用户名和密码都有了接下来组装一个MAP集合Map<String,String> userLoginInfo1 = new HashMap<>();userLoginInfo1.put("loginName",loginName);userLoginInfo1.put("loginPwd",loginPwd);return userLoginInfo1;}

但当前程序存在问题 

 

 (该程序将1=1恒成立编译到SQL语句,程序识别为TRUE即可登录进去)

解决SQL注入

 

 public static void main(String[] args) {
//        初始化一个界面Map<String,String> userLoginInfo =initUi();
//        验证用户名和密码boolean loginSuccess =  login(userLoginInfo);//        最后输出结果System.out.println(loginSuccess ? "登陆成功" :"登陆失败");}/**** @param userLoginInfo 用户登录信息* @return false表示失败,true表示成功*/private static boolean login(Map<String, String> userLoginInfo) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;boolean loginSuccess =false;String loginName =  userLoginInfo.get("loginName");String loginPwd = userLoginInfo.get("loginPwd");try {Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root","123456");//程序执行到此处会发送SQL语句框子给DBMS,然后DBMS进行SQL语句的预先编译String str = "select * from t_user where loginName = ?  and loginPwd = ?";ps= conn.prepareStatement(str);ps.setString(1,loginName);ps.setString(2,loginPwd);rs=ps.executeQuery();if(rs.next()){loginSuccess = true;}} catch (Exception e) {e.printStackTrace();}finally {if(rs!=null){try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(ps!=null){try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn!=null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}return loginSuccess;}/*** 初筛化用户界面* @return 用户输入的用户名和密码*/private static Map<String, String> initUi() {Scanner s = new Scanner(System.in);System.out.println("用户名");String loginName = s.nextLine();System.out.println("密码");String loginPwd = s.nextLine();Map<String ,String > userLoginInfo = new HashMap<>();userLoginInfo.put("loginName",loginName);userLoginInfo.put("loginPwd",loginPwd);return userLoginInfo;}

 

7.JDBC事务机制

 

 账户转账案例演示

 

使用自动提交则是一条SQL语句执行一次提交一次,发生异常时会导致数据丢失。如本案例111给222转账发生异常111丢失10000,222未收到10000;

 public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {
//            注册驱动Class.forName("com.mysql.cj.jdbc.Driver");
//            获取链接conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root","123456");
//将自动提交事务改成手动提交setAutoCommit(false);传FALSE表示禁用手动提交//            连接数据库操作对象String sal =  "update t_act set balance = ? where actno = ?  ";ps = conn.prepareStatement(sal);ps.setString(1,"10000");ps.setString(2,"111");int count = ps.executeUpdate();//            添加空指针,查看是否会发生异常后转账钱数丢失String s =null;s.toString();ps.setString(1,"10000");ps.setString(2,"222");count += ps.executeUpdate();System.out.println(count == 2 ?"转账成功":"转账失败");
//程序只要能走到这说明程序没有异常,事务结束,手动提交数据} catch (Exception e) {e.printStackTrace();}finally {if(rs!=null){try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(ps!=null){try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn!=null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}

 发生空指针异常 ,丢失10000

使用手动提交则是所有SQL语句执行完一起提交发生异常事务回滚数据不会丢失,发生异常时会导致数据丢失。如本案例111给222转账发生异常111还是20000,222是0;

 public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {
//            注册驱动Class.forName("com.mysql.cj.jdbc.Driver");
//            获取链接conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root","123456");
//将自动提交事务改成手动提交setAutoCommit(false);传FALSE表示禁用手动提交conn.setAutoCommit(false);//开启事务//            连接数据库操作对象String sal =  "update t_act set balance = ? where actno = ?  ";ps = conn.prepareStatement(sal);ps.setString(1,"10000");ps.setString(2,"111");int count = ps.executeUpdate();//            添加空指针,查看是否会发生异常后转账钱数丢失
//            String s =null;
//            s.toString();ps.setString(1,"10000");ps.setString(2,"222");count += ps.executeUpdate();System.out.println(count == 2 ?"转账成功":"转账失败");
//程序只要能走到这说明程序没有异常,事务结束,手动提交数据conn.commit();//提交事务} catch (Exception e) {
//            为了保证数据的安全性,必须回滚事务if(conn !=null){try {conn.rollback();//回滚事务} catch (SQLException throwables) {throwables.printStackTrace();}}e.printStackTrace();}finally {if(rs!=null){try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(ps!=null){try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn!=null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}

发生 空指针异常情况 

 不发生异常

七、 JDBC工具类的封装

封装后可直接调用,不用一遍一遍的写

public class DBUtil {
/*** 工具类的构造方法都是私有的* 应为工具类当中的方法都是静态的,不需要new对象,直接采纳类名调用*/
private DBUtil(){}//    静态代码块在类加载时执行,并且只执行一次static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}
}
/*** 获取数据库连接对象* @return 连接对象* @thrown SQLException*/
//工具类确实一般不处理异常  直接抛出  谁来调用你谁来try catch
public static Connection getConnection() throws SQLException {return DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT","root","123456");}/*** 关闭资源* @param conn 连接对象* @param ps 数据库操作对象* @param rs 结果集*/public static void close(Connection conn, Statement ps, ResultSet rs){if(rs!=null){try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(ps!=null){try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(conn!=null){try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}

调用封装类 

  public static void main(String[] args) {Connection conn =null;PreparedStatement ps = null;ResultSet rs = null;try {
//            获取链接conn = DBUtil.getConnection();
//            获取预编译操作对象String str = "select name from user where name like ?";ps = conn.prepareStatement(str);ps.setString(1,"_子%");rs = ps.executeQuery();while (rs.next()){System.out.println(rs.getString("name"));}} catch (Exception throwables) {throwables.printStackTrace();}finally {DBUtil.close(conn,ps,rs);}}


http://www.ppmy.cn/news/269621.html

相关文章

《Python程序设计与算法基础教程(第二版)》江红 余青松 课后选择题 课后填空题答案

目录 第一章一、选择题二、填空题 第二章一、选择题二、填空题 第三章一、选择题二、填空题 第四章一、选择题二、填空题 第五章一、选择题二、填空题 第八章一、选择题二、填空题 第一章 一、选择题 Python语言属于 C A.机器语言 B.汇编语言 C.高级语言 D.以上都不是 在下列…

HCIA-NAT

目录 NAT&#xff1a;网络地址转换 NAT原理&#xff1a; NAT转换原理图&#xff1a; 静态NAT 静态NAT的工作原理&#xff1a; 静态NAT配置命令 静态NAT配置实例&#xff1a; 动态NAT 动态NAT的工作原理 动态NAT&#xff1a; 动态NAT配置命令 动态NAT案例 NAPT NA…

HTC 系列手机解锁,刷recovery以及刷Rom教程

安智论坛中有很多关于android的实用帖子&#xff0c;这里转载一个 HTC系列的手机的解锁&#xff0c;刷recovery以及刷Rom教程

HTC手机解锁 root 刷机的各种问题

新入手了一部HTC手机&#xff0c;一直为ROOT和刷机头疼着&#xff0c;因为我是做安卓开发的。 以前用的那部手机不是高端机&#xff0c;所以当时ROOT很简单。 而HTC手机ROOT之前要进行解锁操作&#xff0c;所以小弟在此总结下HTC的ROOT&#xff1a; ROOT之前要解锁。 建议大家…

htc one s 进入bootloadert和recovery方式

首先要是安装htc one s驱动 把手机设置为USB调试 下载adb.exe文件 adb reboot-bootloader (进入bootloader&#xff09; adb reboot recovery &#xff08;进入recovery&#xff09; 建立一个bootloader.bat文件在adb.exe目录 然后 输入一行命令 adb reboot-boo…

m8解锁后一键root,M87怎么解锁

htc m8 怎么没办法一键root 一、建议考虑系统安全锁开启了的机型&#xff0c;需要先解锁。无锁机及安全锁关闭的机型才能一键root。 二、查看安全锁情况。 1、进入手机设置—电源—取消“快速启动”后面的勾&#xff08;有些机型没有快速启动功能。可以不用管&#xff09;。…

htc328d屏幕排线怎么换_详细的HTC T328D一键解锁教程(图文)

看到很多HTC T328D的机友都还没有解锁呢&#xff0c;而网上很多的解锁的教程又显的特别的繁琐&#xff0c;所以在这里给大家分享一下比较简单的解锁教程吧&#xff0c;这个解锁教程采用的是一键解锁的方式&#xff0c;下面来看看具体的解锁步骤吧&#xff1a; 一&#xff1a;准…

htcd816+android密码,HTC Desire 816刷机解锁教程

一、解锁前的准备&#xff1a; 1.解锁将会丢失所有数据&#xff0c;请先做好备份&#xff0c;如电话本、短信、照片、应用程序。 2.下载并安装驱动程序HTC Driver。 3.注册HTC Dev帐号&#xff0c;为提交解锁码做好准备。 4.下载并解压 “Desire 816 解锁工具”&#xff1a; 5.…