MySQL 之 JDBC 编程增删改查
- 2022 年 8 月 11 日 湖南
本文字数:8944 字
阅读完需:约 29 分钟
MySQL 之 JDBC
一、JDBC 是什么
Java DatabaseConnectivity (java 语言连接数据库)
二、JDBC 的本质
JDBC 是 SUN 公司制定的一套接口(interface)。
接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。
三、为什么要面向接口编程
解耦合:降低程序的耦合度,提高程序的扩展力。解耦合可以理解为淘宝的两个页面,你在将商品加入订单的时候出现错误,但是不会影响你在主页浏览商品,就是两个模块之间的联系不那么紧密,说明两个模块内聚就高。
四、为什么 SUN 制定一套 JDBC 接口
因为每一个数据库产品都有自己独特的实现原理
五、JDBC 编程六步
1、注册驱动(告诉 Java 程序要连接哪个品牌的数据库)
2、获取连接(表示 JVM 的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
3、获取数据库操作对象(专门执行 sql 语句的对象)
4、执行 SQL 语句(DQL,DML...)
5、处理查询结果集 (只有当第四步执行的是 select 语句的时候,才有本步)
6、释放资源(使用完资源后一定要关闭资源,Java 和数据库之间属于进程间的通信,开启之后一定要记得关闭)
六、IDEA 编写 JDBC 连接 MySQL
第一种方法:
1.进入 mysql 官网
2.点击下载 downloads
3.点击下载社区版[MySQL Community (GPL) Downloads »]
4.选择 jdbc 连接器 Connector/J
5.选择 Archives 下载 5.1 版本的(支持的数据库版本更多)
两个都可以下载,自己选一个
6.解压后拿到一个 mysql-connector-java-5.1.49.jar 的包
7.在 idea 创建一个工程,点击 file
8.点击 Java,选择你解压后的 jar 包,不要选择带 bin 的,是二进制的意思。点击 ok 就行。
第二种方法
先检查 jar 包位置:在目录里新建一个文件夹 libs,把 jar 包复制进去
然后右键选择新建文件夹 libs 转成 library
然后就可以写代码啦!
七、jdbc 连接 mysql 程序编写
7.1 第一种注册驱动方式
public class JDBCTest1 { private static Statement stat; private static Connection conn; public static void main(String[] args) { //1.注册驱动 try { DriverManager.registerDriver(new Driver()); //2.获取连接// DriverManager.getConnection("jdbc:mysql://192.168.137.150:3306?" +// "useUnicode=true&characterEncoding=utf8&useSSL=false","root","123456"); /* url: 统一资源定位系统 * http/https: 通过网络请求去访问网络上的资源 * jdbc:mysql: 是驱动提供的请求头 * 请求的地址: 指定mysql的服务器地址:192.168.254.150 * 端口号: 3306 * useUnicode=true&characterCharset=utf8 */ String url ="jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false"; String user = "root"; String password = "123456"; conn = DriverManager.getConnection(url, user, password); System.out.println("与mysql连接成功"+conn); //获取数据库操作对象 stat = conn.createStatement(); //DQL //ResultSet executeQuery(String sql) //执行给定的SQL语句,该语句返回单个 ResultSet对象。 //DML(数据库操作语言,增删改) //int executeUpdate(String sql) //执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。 // 方法的返回值指的是受影响的行数: Affected rows: 1 int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(50,'教学部','合肥')"); System.out.println(count==1?"数据保存成功":"数据保存失败"); } catch (SQLException e) { e.printStackTrace(); }finally { //释放资源 if (stat!=null){ try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }}
7.2 第二种注册驱动方式
public class JDBCTest2 { public static void main(String[] args) { //注册驱动的第二种方式 //注册驱动底层实际上就是用驱动包中对应的类,而驱动包中的类都是class后缀的编译好的文件 // 要想直接使用编译好的类,使用反射来实现。 // 想一想,反射是如何获取一个类的class文件对象呢?3种方式 // 1、getClass // 2、.class // 3、Class.forName() Connection conn = null; Statement stat = null; try { //加载驱动 Class.forName("com.mysql.jdbc.Driver"); //创建与数据库连接的对象 String url = "jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false"; String user="root"; String password="123456"; conn = DriverManager.getConnection(url, user, password); //获取与操作数据库的对象 stat = conn.createStatement(); //编写sql语句并执行 //增 String sql="insert into dept(deptno,dname,loc) values(60,'行政部','合肥')"; int count2 = stat.executeUpdate(sql); System.out.println(count2==1?"数据增加成功":"数据增加失败"); //改 String sql1 ="update dept set dname='研发部'where deptno=60"; int count3 = stat.executeUpdate(sql1); System.out.println(count3==1?"数据修改成功":"数据修改失败"); //删 String sql2 = "delete from dept where deptno=50"; int count4 = stat.executeUpdate(sql2); System.out.println(count4==1?"数据删除成功":"数据删除失败"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally{ if (stat!=null){ try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }}
7.3 将连接数据库的所有信息配置到配置文件中
public class JDBCTest3 { /* 使用配置文件将连接数据库的相关参数进行保存,然后在代码中使用 使用jdk自身提供的Properties类来加载配置文件 */ public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { //使用无参构造方法创建Properties类的对象 Properties prop = new Properties(); //使用字符流读取配置文件 BufferedReader br = new BufferedReader(new FileReader("F:\\software\\IdeaProjects\\bigdata19_mysql\\resource\\jdbc.properties")); prop.load(br); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String user = prop.getProperty("user"); String password = prop.getProperty("password"); //加载驱动 Class.forName(driver); //获取连接对象 Connection conn = DriverManager.getConnection(url, user, password); //获取数据库操作对象 Statement stat = conn.createStatement(); //执行sql语句 int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(70,'教学部','合肥')"); System.out.println(count==1?"数据插入成功":"数据插入失败"); //释放资源 if (stat!=null){ stat.close(); } if (conn!=null){ conn.close(); } }}
7.4 处理查询
工具类封装
public class MySqlTool { /* 工具类 1.不能让外界实例化(构造方法私有化) 2.方法必须是静态 */ private static Connection conn; private MySqlTool(){} public static Connection init(){ try { Properties prop = new Properties(); //使用字符流读取配置文件 BufferedReader br = new BufferedReader(new FileReader("F:\\software\\IdeaProjects\\bigdata19_mysql\\resource\\jdbc.properties")); prop.load(br); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String user = prop.getProperty("user"); String password = prop.getProperty("password"); //加载驱动 Class.forName(driver); //获取连接对象 conn = DriverManager.getConnection(url, user, password); }catch (Exception e){ e.printStackTrace(); } return conn; }}
public class JDBCTest4 { public static void main(String[] args) throws SQLException { //通过工具类获取数据库连接对象 Connection conn = MySqlTool.init(); //获取数据库操作对象 Statement stat = conn.createStatement(); //执行sql语句 ResultSet result = stat.executeQuery("select deptno,dname,loc from dept"); //处理查询结果集 boolean b = result.next(); //将光标从当前位置向前移动一行。 //如果光标移动的位置有值,这里的返回值是true// if (b){// //获取一行中每一列的数值,第一种方式// String deptno = result.getString(1);// String dname = result.getString(2);// String loc = result.getString(3);// System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc);//// } //正常情况下,一张结果表的行数我们不确定,但是我们知道,当next的结果是false的时候,表示读取到末尾 while(result.next()){ //获取一行中每一列的数值,第一种方式// String deptno = result.getString(1);// String dname = result.getString(2);// String loc = result.getString(3);// System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); //第二种方式,根据列名获取对应的列值 //注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名 String deptno = result.getString("deptno"); String dname = result.getString("dname"); String loc = result.getString("loc"); System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); } //注意事项2:同一个结果resultSet对象,只能遍历一次 System.out.println("========================="); //再次遍历,结果不显示 while(result.next()){ //获取一行中每一列的数值,第一种方式// String deptno = result.getString(1);// String dname = result.getString(2);// String loc = result.getString(3);// System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); //第二种方式,根据列名获取对应的列值 //注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名 String deptno = result.getString("deptno"); String dname = result.getString("dname"); String loc = result.getString("loc"); System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); } //释放资源 if (stat!=null){ stat.close(); } if (conn!=null){ conn.close(); } }}
7.5 登录注册案例
public class JDBCTest5 { public static void main(String[] args) throws SQLException { /* 使用jdbc模拟登录注册案例 1、注册账号:往数据库插入一条数据 2、登录账号:查询数据库 */ //1.建表user //创建键盘录入对象 System.out.println("欢迎来到提瓦特大陆,准备好开始冒险了吗?"); Scanner scanner = new Scanner(System.in); System.out.println("请输入旅行者的名字:"); String username = scanner.next(); System.out.println("请输入密码:"); String password = scanner.next(); //创建数据库驱动// try {// DriverManager.registerDriver(new Driver());// } catch (SQLException e) {// e.printStackTrace();// }//// Connection conn = DriverManager.getConnection(); //直接采用工具类获取与数据库的连接对象 Connection conn = MySqlTool.init(); //获取数据库操作对象 Statement stat = conn.createStatement(); //编写sql语句 String sql= "select username,password from user where username='"+username+"'and password='"+password+"'"; //执行sql语句 ResultSet rs = stat.executeQuery(sql); //处理查询结果集 boolean b = rs.next(); if (b){ System.out.println("旅行者"+username+",欢迎来到提瓦特大陆!"); }else{ System.out.println("您还未注册成为旅行者,是否注册(Y/N)"); String choice = scanner.next(); if ("Y".equals(choice)){ while (true){ System.out.println("请输入旅行者的名字:"); String new_username = scanner.next(); System.out.println("请输入密码:"); String new_password = scanner.next(); System.out.println("请确认密码:"); String again_password = scanner.next(); if (again_password.equals(new_password)) { UUID uuid = UUID.randomUUID();//随机生成uuid String new_uuid = uuid + "-" + System.currentTimeMillis(); String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')"; int count = stat.executeUpdate(sql2); if (count == 1) { System.out.println("注册成功"); } else { System.out.println("注册失败"); } break; }else { System.out.println("两次密码输入不一致,请重新输入:"); } } } } stat.close(); conn.close(); }}
7.6 解决 sql 注入问题
public class JDBCTest6 { public static void main(String[] args) throws SQLException { /* 我们写完程序后发现,当我们将密码输入成1234' or '1'='1这个样子的时候,发现登录成功 原因:sql在编译的时候,会将我们输入的内容存在关键字or,会把or当作sql语法关键字进行执行 如何解决呢? 这样的问题,称之为sql注入的问题 解决的思路就是在sql编译完后再传入数据 获取数据库操作对象另外一种方式,预编译的方式 */ /* 使用jdbc模拟登录注册案例 1、注册账号:往数据库插入一条数据 2、登录账号:查询数据库 */ //1.建表user //创建键盘录入对象 System.out.println("欢迎来到提瓦特大陆,准备好开始冒险了吗?"); Scanner scanner = new Scanner(System.in); System.out.println("请输入旅行者的名字:"); String username = scanner.nextLine(); System.out.println("请输入密码:"); String password = scanner.nextLine(); //创建数据库驱动// try {// DriverManager.registerDriver(new Driver());// } catch (SQLException e) {// e.printStackTrace();// }//// Connection conn = DriverManager.getConnection(); //直接采用工具类获取与数据库的连接对象 Connection conn = MySqlTool.init();// //获取数据库操作对象// Statement stat = conn.createStatement();//// //编写sql语句// String sql= "select username,password from user where username='"+username+"'and password='"+password+"'";// //执行sql语句// ResultSet rs = stat.executeQuery(sql); //这里的问号相当于一个占位符,为了后面传值 String sql = "select username,password from user where username=? and password=?"; //创建预编译数据库操作对象 PreparedStatement pps = conn.prepareStatement(sql); //将sql中的占位符附上值 //第一个参数表示给第几个问号传值,第二个参数表示具体的值,序号从1开始 pps.setString(1,username); pps.setString(2,password); //执行sql语句 ResultSet rs = pps.executeQuery(); //处理查询结果集 boolean b = rs.next(); if (b){ System.out.println("旅行者"+username+",欢迎来到提瓦特大陆!"); }else{ System.out.println("您还未注册成为旅行者,是否注册(Y/N)"); String choice = scanner.next(); if ("Y".equals(choice)){ while (true){ System.out.println("请输入旅行者的名字:"); String new_username = scanner.next(); System.out.println("请输入密码:"); String new_password = scanner.next(); System.out.println("请确认密码:"); String again_password = scanner.next(); if (again_password.equals(new_password)) { UUID uuid = UUID.randomUUID();//随机生成uuid String new_uuid = uuid + "-" + System.currentTimeMillis(); String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')"; int count = pps.executeUpdate(sql2); if (count == 1) { System.out.println("注册成功"); } else { System.out.println("注册失败"); } break; }else { System.out.println("两次密码输入不一致,请重新输入:"); } } } } pps.close(); conn.close(); }}
7.7JDBC 实现模糊查询
public class JDBCTest7 { public static void main(String[] args) throws SQLException { //获取数据库连接对象 Connection conn = MySqlTool.init(); //获取预编译数据库操作对象 String sql="select uid,username,password from user where username like ?"; PreparedStatement pps = conn.prepareStatement(sql); pps.setString(1,"%bfy%"); //执行sql语句 ResultSet rs = pps.executeQuery(); //处理查询结果集 while (rs.next()){ String uid=rs.getString(1); String username=rs.getString(2); String password=rs.getString(3); System.out.println(uid+','+username+','+password); } pps.close(); conn.close(); }}
了不起的程序猿
不定期更新Java开发工具及Java面试干货技巧 2021.12.12 加入
Java后端工程师,十年大厂经验。具有扎实的Java、JEE基础知识。熟悉Spring、SpringMVC、Struts MyBatisHibernate等JEE常用框架。
评论