JAVA_JDBC

一、数据库驱动

程序通过数据库驱动与数据库交换数据

二、JDBC

SUN公司为了简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库)规范,俗称:JDBC
在这里插入图片描述
java.sql
javax.sql
还需导入数据库驱动包:mysql-connector-java-8.0.28.jar

三、第一个JDBC程序

package com.JJL.lesson01;

import java.nio.file.attribute.UserPrincipalLookupService;
import java.sql.*;

// 我的第一个JDBC程序
public class JdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");//固定写法

        //2.用户信息和url
        String url ="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=ut8&useSSL=true";
        String username="root";
        String password="1234qwer";

        //3.连接成功,数据库对象 Connection 代表数据库
        Connection connection= DriverManager.getConnection(url,username,password);

        //4.执行sql的对象 Statement执行sql的对象
        Statement statement=connection.createStatement();

        //5.执行SQL的对象 去执行SQL,可能存在结果,查看返回值
        String sql="select * from users;";
        ResultSet resultSet = statement.executeQuery(sql);//返回的结果

        while (resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("name="+resultSet.getObject("NAME"));
            System.out.println("pwd="+resultSet.getObject("PASSWORD"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("birth="+resultSet.getObject("birthday"));
        }

        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

步骤总结:
1、加载驱动
2、连接数据库
3、获得执行sql的对象
4、获得返回的结果集
5、释放连接

DriverManager

//DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
Class.forName("com.mysql.cj.jdbc.Driver");//固定写法

 Connection connection= DriverManager.getConnection(url,username,password);
 Connection  代表数据库
 数据库设置自动提交 connection.setAutoCommit();
 事物提交  connection.commit();
 事物回滚  connection.rollback(); 

URL
String url =“jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=ut8&useSSL=true”;
mysql—3306
协议://主机地址:端口/数据库名?参数1&参数2&参数3

Oracle
jdbc:oracle:thin:@localhost:1521:sid

Statement执行sql的对象
statement.executeQuery();//查询操作返回一个结果
statement.execute();//执行任何sql
statement.executeUpdate();//更新、插入、删除,都是用这个,返回一个受影响的行数

Resltset 返回的结果集,结果集中封装了我们全部的查询结果
resultSet.getObject();//在不知道列类型的情况下使用
//如果知道列的类型就用指定的类型
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();

遍历,指针
resultSet.next();

四、statement对象

jdbc中的statement对象用于向数据库发送sql语句。
statement.executeQuery();//查询操作返回一个结果
statement.execute();//执行任何sql
statement.executeUpdate();//更新、插入、删除,都是用这个,返回一个受影响的行数

1、在src目录下创建jdbc配置文件db.properties

driver=com.mysql.cj.jdbc.Driver
url =jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=ut8&useSSL=true
username=root
password=1234qwer

2、创建工具类

package com.JJL.lesson02.utls;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private  static String driver=null;
    private  static String url=null;
    private  static String username=null;
    private  static String password=null;
    static {
        try{
            InputStream in=JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            //1.驱动只用加载一次
            Class.forName(driver);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    //获取连接
    public static Connection getConneciton() throws SQLException {
        return DriverManager.getConnection(url, username, password);
    }


    //释放连接资源
    public static void release(Connection conn, Statement st, ResultSet rs) throws SQLException {
        if (rs!=null){rs.close();}
        if (rs!=null){st.close();}
        if (rs!=null){conn.close();}
    }
}

3、插入数据

package com.JJL.lesson02;
import com.JJL.lesson02.utls.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestInsert {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        Statement st = null;
        ResultSet rs =null;

        try {
            conn = JdbcUtils.getConneciton();//获取数据库连接
            st=conn.createStatement();//获取sql的执行对象
            String sql = "INSERT into users(id,`NAME`,`PASSWORD`,`email`,`birthday`)" +
                    "VALUES(5,'xl','1234','12314@qq.com','2022-03-26')";
            int i = st.executeUpdate(sql);
            if(i>0){
                System.out.println("insert 成功");
            }
        }catch (SQLException e){
            System.out.println("11111111111111");
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }

    }
}

4、删除数据

package com.JJL.lesson02;
import com.JJL.lesson02.utls.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDelete {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        Statement st = null;
        ResultSet rs =null;

        try {
            conn = JdbcUtils.getConneciton();//获取数据库连接
            st=conn.createStatement();//获取sql的执行对象
            String sql = "DELETE FROM users WHERE id=2;";
            int i = st.executeUpdate(sql);
            if(i>0){
                System.out.println("delete 成功");
            }
        }catch (SQLException e){
            System.out.println("11111111111111");
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

5、修改数据

package com.JJL.lesson02;
import com.JJL.lesson02.utls.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestUpdate {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        Statement st = null;
        ResultSet rs =null;

        try {
            conn = JdbcUtils.getConneciton();//获取数据库连接
            st=conn.createStatement();//获取sql的执行对象
            String sql = "UPDATE users set `NAME`='linlin' WHERE id=3;";
            int i = st.executeUpdate(sql);
            if(i>0){
                System.out.println("update 成功");
            }
        }catch (SQLException e){
            System.out.println("11111111111111");
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

6、查询数据

package com.JJL.lesson02;
import com.JJL.lesson02.utls.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Testselect {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        try {
            conn= JdbcUtils.getConneciton();//创建连接
            st = conn.createStatement();//创建执行对象
            //sql
            String sql="select * from users";
            rs = st.executeQuery(sql);//查询完毕会返回结果集
            while (rs.next()){
                System.out.println(rs.getString("NAME"));
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }

    }
}

五、SQL注入问题

sql存在漏洞,会被攻击,导致数据泄露

package com.JJL.lesson02.utls;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SQL注入 {
    public static void main(String[] args) throws SQLException {
        //输入正常的用户名密码
        //login("linlin","1234");
        //利用拼接字符串的方式,实现sql注入,查询出数据库所有的用户密码
        login(" ' or '1=1"," ' or '1=1");
    }
    public static void login(String username,String password) throws SQLException {
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        try {
            conn= JdbcUtils.getConneciton();//创建连接
            st = conn.createStatement();//创建执行对象
            //sql
            String sql="select * from users where NAME ='"+username+"'and password='"+password+"'";
            rs = st.executeQuery(sql);//查询完毕会返回结果集
            while (rs.next()){
                System.out.println(rs.getString("NAME"));
                System.out.println(rs.getString("password"));
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

六、PreparedStatement对象——防止sql注入

PreparedStatement可以防止sql注入
PreparedStatement会把传入的参数当作字符
如果字符里含有转义字符会直接忽略,比如单引号

1、插入记录

package com.JJL.lesson03;

import com.JJL.lesson02.utls.JdbcUtils;
import java.util.Date;
import java.sql.*;

public class TestInsert {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        PreparedStatement st =null;
        ResultSet rs = null;
        try{
            conn= JdbcUtils.getConneciton();

            //使用? 占位符代替参数
            String sql =  "INSERT into users(id,`NAME`,`PASSWORD`,`email`,`birthday`)VALUES(?,?,?,?,?)";
            st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
            //手动给参数赋值
            st.setInt(1,2);
            st.setString(2,"dier");
            st.setString(3,"1234qwer");
            st.setString(4,"wsdf@.com");
            //注意点:sql.Date是数据库的
            // util.Date Java new Date().getTime() 获得时间戳
            st.setDate(5,new java.sql.Date(new Date().getTime()));
            
            //执行sql
            int i = st.executeUpdate();
            if(i>0){
                System.out.println("成功插入:"+i+"行");
            }

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

2、删除记录

package com.JJL.lesson03;
import com.JJL.lesson02.utls.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestDelete {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        PreparedStatement st =null;
        ResultSet rs = null;
        try{
            conn= JdbcUtils.getConneciton();

            //使用? 占位符代替参数
            String sql =  "delete from users where id=?";
            st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
            //手动给参数赋值
            st.setInt(1,4);

            //执行sql
            int i = st.executeUpdate();
            if(i>0){
                System.out.println("成功删除:"+i+"行");
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

3、更新记录

package com.JJL.lesson03;

import com.JJL.lesson02.utls.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestUpdate {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        PreparedStatement st =null;
        ResultSet rs = null;
        try{
            conn= JdbcUtils.getConneciton();
            //使用? 占位符代替参数
            String sql =  "update users set `NAME`=? WHERE id=?";
            st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
            //手动给参数赋值
            st.setString(1,"第一");
            st.setInt(2,1);
            //执行sql
            int i = st.executeUpdate();
            if(i>0){
                System.out.println("成功更新:"+i+"行");
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

4、查询记录

package com.JJL.lesson03;
import com.JJL.lesson02.utls.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestSelect {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        PreparedStatement st =null;
        ResultSet rs = null;
        try{
            conn= JdbcUtils.getConneciton();

            //使用? 占位符代替参数
            String sql =  "select * from users where id=?";
            st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
            //手动给参数赋值
            st.setInt(1,5);

            //执行sql
            rs=st.executeQuery();
            if(rs.next()){
                System.out.println(rs.getString("NAME"));
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

七、使用IDEA连接数据库

在这里插入图片描述
连接成功
在这里插入图片描述
选择数据库
在这里插入图片描述
查看表数据
在这里插入图片描述
修改表数据
在这里插入图片描述
sql查询窗口
在这里插入图片描述

八、jdbc操作事务

要么都成功,要么都失败

ACID原则

原子性:要么全部完成,要么都不完成
一致性:总数不变
隔离性:多个进程互不干扰
持久性:一旦提交不可逆,持久化到数据库了

隔离性的问题:
脏读:一个事务读取了另一个美哟提交的事务
不可重复读:在同一个事物内,重复读取表中的数据,表数据发生了改变
虚读(幻读):在一个事物内,读取到了别人插入的数据,导致前后读取不一致

package com.JJL.lesson04;

import com.JJL.lesson02.utls.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestTransactions2 {
    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs=null;

        try {
            conn = JdbcUtils.getConneciton();
            //关闭数据库的自动提交功能,自动会开启事物
            conn.setAutoCommit(false);//开启事物
            String sql1 = "update account set money=money-100 where name='a'";
            String sql2 = "update account set money=money+100 where name='b'";
            st=conn.prepareStatement(sql1);
            st.executeUpdate();
            int x=1/0;//模拟sql执行失败后,会不会整体回滚
            st=conn.prepareStatement(sql2);
            st.executeUpdate();
            //提交事物
            conn.commit();
            System.out.println("执行成功");

        } catch (SQLException e) {
            try{
                conn.rollback();//如果失败回滚事物,其实这个地方不写也会回滚,默认回滚
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

1、开启事务conn.setAutoCommit(false)
2、一组业务执行完毕,提交事务
3、可以在catch语句中显示定义回滚语句,但默认失败就会回滚

九、数据库连接池

数据库连接–执行完毕–释放
连接–释放十分浪费系统资源
池化技术:准备一些预先的资源,过来就链接预先准备好的

最小连接数:
最大连接数:
等待超时间:

开源数据源实现
DBCP
C3P0
DRUID:阿里巴巴的

使用了这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库代码了

DBCP

commons-dbcp-1.4.jar
commons-pool-1.6.jar

1、dbcp配置文件

#连接设置 这里的名字,是DBCP数据源定义好的
driverClassName=com.mysql.cj.jdbc.Driver
url =jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charaterEncoding=ut8&useSSL=true
username=root
password=1234qwer
#初试连接数
initialSize=10
#最大连接数
maxActive=30
#最大空闲连接数
maxIdle=10
#最小空闲连接数
minIdle=5
#最长等待时间(毫秒)
maxWait=60000
#程序中的连接不使用后是否被连接池回收
#removeAbandoned=true
removeAbandonedOnMaintenance=true
removeAbandonedOnBorrow=true
#连接在所指定的秒数内未使用才会被删除()(为配合测试程序才配置为1)
removeAbandonedTimeout=1

2、工具类

package com.JJL.lesson05.utls;

import com.JJL.lesson02.utls.JdbcUtils;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils_DBCP {
    private static DataSource dataSource=null;
    static {
        try{
            InputStream in= JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);

            //创建数据源
            dataSource = BasicDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    //获取连接
    public static Connection getConneciton() throws SQLException {
        return dataSource.getConnection();//从数据源中获取连接
    }
    //释放连接资源
    public static void release(Connection conn, Statement st, ResultSet rs) throws SQLException {
        if (rs!=null){rs.close();}
        if (rs!=null){st.close();}
        if (rs!=null){conn.close();}
    }
}

3、实现插入数据,与jdbc没啥区别

package com.JJL.lesson05;

import com.JJL.lesson05.utls.JdbcUtils_DBCP;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

public class TestDBCP {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        PreparedStatement st =null;
        ResultSet rs = null;
        try{
            conn= JdbcUtils_DBCP.getConneciton();

            //使用? 占位符代替参数
            String sql =  "INSERT into users(id,`NAME`,`PASSWORD`,`email`,`birthday`)VALUES(?,?,?,?,?)";
            st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
            //手动给参数赋值
            st.setInt(1,6);
            st.setString(2,"di六");
            st.setString(3,"1234qwer");
            st.setString(4,"wsdf@.com");
            //注意点:sql.Date是数据库的
            // util.Date Java new Date().getTime() 获得时间戳
            st.setDate(5,new java.sql.Date(new Date().getTime()));

            //执行sql
            int i = st.executeUpdate();
            if(i>0){
                System.out.println("成功插入:"+i+"行");
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils_DBCP.release(conn,st,rs);
        }
    }
}

C3P0

c3p0-0.9.5.5.jar
mchange-commons-java-0.2.19.jar

1、配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 使用默认的配置读取连接池对象 -->
    <default-config>
        <!--  连接参数 -->
        <!--  驱动名称  -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <!--  数据库URL  -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=false&amp;serverTimezone=UTC</property>
        <!--  用户名  -->
        <property name="user">root</property>
        <!--  密码  -->
        <property name="password">1234qwer</property>
        <!-- 连接池参数 -->
        <property name="acquireIncrement">5</property>
        <!--  初始连接数量  -->
        <property name="initialPoolSize">5</property>
        <!--  最大连接数  -->
        <property name="maxPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <!--  超时时间  -->
        <property name="checkoutTimeout">3000</property>
    </default-config>

    <named-config name="MySQL">
        <!--  连接参数 -->
        <!--  驱动名称  -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <!--  数据库URL  -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=false&amp;serverTimezone=UTC</property>
        <!--  用户名  -->
        <property name="user">root</property>
        <!--  密码  -->
        <property name="password">1234qwer</property>
        <!-- 连接池参数 -->
        <property name="acquireIncrement">5</property>
        <!--  初始连接数量  -->
        <property name="initialPoolSize">5</property>
        <!--  最大连接数  -->
        <property name="maxPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <!--  超时时间  -->
        <property name="checkoutTimeout">3000</property>
    </named-config>
</c3p0-config>

2、工具类

package com.JJL.lesson05.utls;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcUtils_C3P0 {
    private static ComboPooledDataSource dataSource=null;
    static {
        try {
            dataSource = new ComboPooledDataSource();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConneciton() throws SQLException {
        return dataSource.getConnection();//从数据源中获取连接
    }


    //释放连接资源
    public static void release(Connection conn, Statement st, ResultSet rs) throws SQLException {
        if (rs!=null){rs.close();}
        if (rs!=null){st.close();}
        if (rs!=null){conn.close();}
    }
}

3、实现类

package com.JJL.lesson05;

import com.JJL.lesson05.utls.JdbcUtils_C3P0;
import com.JJL.lesson05.utls.JdbcUtils_DBCP;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

public class TestC3p0 {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        PreparedStatement st =null;
        ResultSet rs = null;
        try{
            conn = JdbcUtils_C3P0.getConneciton();

            //使用? 占位符代替参数
            String sql =  "INSERT into users(id,`NAME`,`PASSWORD`,`email`,`birthday`)VALUES(?,?,?,?,?)";
            st=conn.prepareStatement(sql);//预编译sql,先写sql,然后不执行
            //手动给参数赋值
            st.setInt(1,7);
            st.setString(2,"di七");
            st.setString(3,"1234qwer");
            st.setString(4,"wsdf@.com");
            //注意点:sql.Date是数据库的
            // util.Date Java new Date().getTime() 获得时间戳
            st.setDate(5,new java.sql.Date(new Date().getTime()));

            //执行sql
            int i = st.executeUpdate();
            if(i>0){
                System.out.println("成功插入:"+i+"行");
            }

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            JdbcUtils_DBCP.release(conn,st,rs);
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XL's妃妃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值