0


Java连接mysql数据库

文章目录

一、Java连接mysql数据库

1.1 流程

java连接mysql大致需要这六步:

  1. 导入驱动包:这里我使用的是mysql-connector-java-8.0.17.jar(点击下载),这个包连接mysql5.6,5.7,8.0版本都没问题。Class.forName("com.mysql.cj.jdbc.Driver");
  2. url和账户名密码 JDBC连接串:jdbc:mysql://<地址>:<端口>/<数据库>
  3. 获取连接DriverManager.getConnection(url, user, password);
  4. 执行sql的Statement对象connection.createStatement();
  5. 执行SQL
  6. 释放连接

1.2 一个测试连接的java程序

JdbcFirstDemo.java

packagecom.peng.less01;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassJdbcFirstDemo{publicstaticvoidmain(String[] args)throwsClassNotFoundException,SQLException{// 1.导入驱动类Class.forName("com.mysql.cj.jdbc.Driver");// 2.用户信息和urlString url ="jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=false";String user ="root";String password ="12345678";// 3.获取连接Connection conn =DriverManager.getConnection(url, user, password);// 4.执行SQL的对象Statement sta =  conn.createStatement();// 5.执行SQLString sql ="select * from account";ResultSet rs = sta.executeQuery(sql);while(rs.next()){System.out.println("id= "+ rs.getObject("id"));System.out.println("name= "+ rs.getObject("name"));System.out.println("money= "+ rs.getObject("money"));System.out.println("=========================================");}// 6.释放连接
        rs.close();
        sta.close();
        conn.close();}}

这里使用的是VScode,connector包放到了lib目录下,代码放在了src/com/peng/less01下。
执行结果如下,显示了shop.account表下面的三条记录。
在这里插入图片描述

二、优化:创建一个工具类

2.1 存在的问题

1、JDBC连接串,用户名,密码等都存在于代码中,需要进行解耦

2、创建连接,释放连接这些操作都是固定的,没必要每次都重复写这些代码(创建函数解决

2.2 创建配置文件和工具类

src/db.properties 文件中记录driver,url,user,password

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=false
user=root
password=12345678

src/com/peng/less02/utils/JdbcUtils.java 工具类:读取properties配置文件
自动读取配置信息,加载mysql驱动。

packagecom.peng.less02.utils;importjava.io.InputStream;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.util.Properties;// 这是一个工具类,用来减少重复操作publicclassJdbcUtils{privatestaticString driver =null;privatestaticString url =null;privatestaticString user =null;privatestaticString password =null;static{try{// 读取db.propertiesInputStream in =JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");Properties properties =newProperties();
            properties.load(in);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");// 加载驱动Class.forName(driver);}catch(Exception e){
            e.printStackTrace();}}// 创建连接publicstaticConnectiongetConnection()throwsSQLException{returnDriverManager.getConnection(url,user,password);}// 释放连接publicstaticvoidreleaseConnection(Connection conn,Statement sta,ResultSet rs){if(rs !=null){try{
                rs.close();}catch(SQLException e){// TODO Auto-generated catch block
                e.printStackTrace();}}if(sta !=null){try{
                sta.close();}catch(SQLException e){// TODO Auto-generated catch block
                e.printStackTrace();}}if(conn !=null){try{
                conn.close();}catch(SQLException e){// TODO Auto-generated catch block
                e.printStackTrace();}}}}

2.3 测试使用工具类进行CRUD操作

**

测试插入操作

**
src/com/peng/less02/TestInsert.java

packagecom.peng.less02;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importcom.peng.less02.utils.JdbcUtils;publicclassTestInsert{publicstaticvoidmain(String[] args){Connection conn =null;Statement sta =null;ResultSet rs =null;try{
            conn =JdbcUtils.getConnection();
            sta = conn.createStatement();String sql ="insert into account(`id`,`name`,`money`) values(4,'药水哥',4698888)";int i = sta.executeUpdate(sql);if(i >0){System.out.println("插入成功!");}}catch(SQLException e){// TODO Auto-generated catch block
            e.printStackTrace();}finally{JdbcUtils.releaseConnection(conn, sta, rs);}}}

**

测试更新操作

**
src/com/peng/less02/TestUpdate.java

packagecom.peng.less02;importjava.sql.*;importcom.peng.less02.utils.JdbcUtils;publicclassTestUpdate{publicstaticvoidmain(String[] args){Connection conn =null;Statement sta =null;try{
            conn =JdbcUtils.getConnection();
            sta = conn.createStatement();String sql ="update account set `money`=238888 where id=3";int i = sta.executeUpdate(sql);if(i >0){System.out.println("更新成功");}}catch(SQLException e){// TODO Auto-generated catch block
            e.printStackTrace();}finally{JdbcUtils.releaseConnection(conn, sta,null);}}}

**

测试读取操作

**

packagecom.peng.less02;importjava.sql.*;importcom.peng.less02.utils.JdbcUtils;publicclassTestSelect{publicstaticvoidmain(String[] args){Connection conn =null;Statement sta =null;ResultSet rs =null;try{
            conn =JdbcUtils.getConnection();
            sta = conn.createStatement();String sql ="select * from account";
            rs = sta.executeQuery(sql);while(rs.next()){System.out.println("id= "+ rs.getInt("id"));System.out.println("name= "+ rs.getString("name"));System.out.println("money= "+ rs.getObject("money"));System.out.println("======================================================");}}catch(SQLException e){// TODO Auto-generated catch block
            e.printStackTrace();}finally{JdbcUtils.releaseConnection(conn, sta, rs);}}}

三、SQL注入问题

这里写一个登录认证程序,如果账号,密码输入正确则允许登录。为了测试,这里的允许登录改为输出账号密码。

还使用前面写的JdbcUtils工具类

可以看到,这里我输入的用户名/密码是:’ or '1=1****’ or '1=1
然后输出了user表中的所有数据,这明显是不合法的。存在sql注入的问题

问题就在于这段代码,sql是拼接而成的。

String sql ="select * from user where `username`='"+ username +"' and `password`='"+ password +"'";

拼接的sql为:

select * from user where `username`='' or '1=1' and `password`='' or '1=1';

3.1 SQL注入示例

SqlInjection.java

packagecom.peng.less02;importcom.peng.less02.utils.JdbcUtils;importjava.sql.*;publicclassSqlInjection{publicstaticvoidmain(String[] args){login("' or '1=1","' or '1=1");}// 登录功能publicstaticvoidlogin(String username,String password){Connection conn =null;Statement sta =null;ResultSet rs =null;try{
            conn =JdbcUtils.getConnection();
            sta = conn.createStatement();//这段代码中sql是变量拼接而成的String sql ="select * from user where `username`='"+ username +"' and `password`='"+ password +"'";
            rs = sta.executeQuery(sql);//输入正确的账号密码就能够登录,这里为了测试就(输入正确输出账号密码)while(rs.next()){System.out.println("id= "+ rs.getInt("id"));System.out.println("username= "+ rs.getString("username"));System.out.println("password= "+ rs.getObject("password"));System.out.println("======================================================");}}catch(SQLException e){// TODO Auto-generated catch block
            e.printStackTrace();}finally{JdbcUtils.releaseConnection(conn, sta, rs);}}}

在这里插入图片描述

四、使用PreparedStatement防止SQL注入

  • 使用PreparedStatement,防止SQL注入,同时对于执行多次的SQL更加高效

PreparedStatement

对sql进行了预编译

,传入的参数只会被当作字符串来处理,而不会像前面对sql进行了拼接。

**

流程如下:

**

先编写sql --> 进行预编译 --> 增加sql参数值 --> 执行sql

SqlInjection.java

packagecom.peng.less03;importcom.peng.less02.utils.JdbcUtils;importjava.sql.*;publicclassSqlInjection{publicstaticvoidmain(String[] args){// login("'' or 1=1", "'' or 1=1");login("张三","zhangsan");}// 登录功能publicstaticvoidlogin(String username,String password){Connection conn =null;PreparedStatement psta =null;ResultSet rs =null;try{
            conn =JdbcUtils.getConnection();//这里使用 ? 占位符来代替String sql ="select * from user where `username`=? and `password`=?";//使用PreparedStatement,防止SQL注入,同时对于执行多次的SQL更加高效
            psta = conn.prepareStatement(sql);
            psta.setString(1,username);
            psta.setObject(2,password);
            rs = psta.executeQuery();//输入正确的账号密码就能够登录,这里为了测试就(输入正确输出账号密码)while(rs.next()){System.out.println("id= "+ rs.getInt("id"));System.out.println("username= "+ rs.getString("username"));System.out.println("password= "+ rs.getObject("password"));System.out.println("======================================================");}}catch(SQLException e){// TODO Auto-generated catch block
            e.printStackTrace();}finally{JdbcUtils.releaseConnection(conn, psta, rs);}}}

五、JDBC操作事务

和用sql执行事务类似,创建连接后

setAutoCommit(false)

,最后

commit()

,失败则

rollback()


注意:rollback()部分可以不用写,事务失败会自动回滚。

TestTransaction.java

packagecom.peng.less04;importjava.sql.*;// 仍然使用前面写的JdbcUtils工具类importcom.peng.less02.utils.JdbcUtils;publicclassTestTransaction{publicstaticvoidmain(String[] args){Connection conn =null;PreparedStatement pst =null;try{
            conn =JdbcUtils.getConnection();// 关闭自动提交,开启事务
            conn.setAutoCommit(false);//模拟一个转账事务,A向大帅哥转账100块String sql1 ="update account set `money`=money - 100 where `name`='A'";
            pst = conn.prepareStatement(sql1);
            pst.executeUpdate();// int x = 1/0;String sql2 ="update account set `money`=money + 100 where `name`='大帅哥'";
            conn.prepareStatement(sql2).executeUpdate();

            conn.commit();System.out.println("Success!");}catch(SQLException e){// TODO Auto-generated catch blocktry{// rollback()可以不用写,失败的话会自动回滚
                conn.rollback();}catch(SQLException e1){// TODO Auto-generated catch block
                e1.printStackTrace();}
            e.printStackTrace();}finally{JdbcUtils.releaseConnection(conn, pst,null);}}}
标签: 数据库 mysql java

本文转载自: https://blog.csdn.net/qq_46480020/article/details/127605538
版权归原作者 银痕 所有, 如有侵权,请联系我们删除。

“Java连接mysql数据库”的评论:

还没有评论