JDBC基础

1 数据库驱动
.png)
程序通过数据库驱动和数据库交互
2 JDBC
为了简化对(数据库的统一)操作,提供了一个(java操作数据库的)规范,简称JDBC
.png)
需要的包:
- java.sql
- javax.sql
- 数据库驱动:mysql-connector-java-5.1.47.jar
3 JDBC程序
创建测试数据库
xxxxxxxxxx1171CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;2
3USE jdbcStudy;4
5CREATE TABLE `users`(6    id INT PRIMARY KEY,7    NAME VARCHAR(40),8    PASSWORD VARCHAR(40),9    email VARCHAR(60),10    birthday DATE11);12
13INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)14VALUES(1,zhansan,123456,zs@sina.com,1980-12-04),15(2,lisi,123456,lisi@sina.com,1981-12-04),16(3,wangwu,123456,wangwu@sina.com,1979-12-04)创建JAVA项目 导入数据库驱动
在项目创建lib目录并将jar包拷入,添加为Library

连接数据库测试:
x
1391/*第一个JDBC程序*/2public class jdbcFirstDemo {3    public static void main(String[] args) throws ClassNotFoundException, SQLException {4        //1.加载数据库驱动5        Class.forName("com.mysql.jdbc.Driver");//加载驱动6
7        //2.输入用户信息与URL8        //useUnicode使用Unicode编码 characterEncoding设置编码utf8 useSSL使用安全连接9        String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";10        String username = "root";11        String password = "123456";12
13        //3.连接数据库,获得数据库对象 Connection数据库对象14        Connection connection = DriverManager.getConnection(url,username,password);15
16        //4.获得执行SQL的对象 Statement执行sql的对象17        Statement statement = connection.createStatement();18
19        //5.执行SQL20        String sqlStr = "SELECT * FROM `users`;";21
22        ResultSet resultSet = statement.executeQuery(sqlStr);//返回结果集,结果集封装全部查询的结果23
24        while (resultSet.next()){25            System.out.println("-------------------------");26            System.out.println("id=" + resultSet.getObject("id"));27            System.out.println("name=" + resultSet.getObject("NAME"));28            System.out.println("pwd=" + resultSet.getObject("PASSWORD"));29            System.out.println("email=" + resultSet.getObject("email"));30            System.out.println("birth=" + resultSet.getObject("birthday"));31        }32
33        //6.关闭连接34        resultSet.close();35        statement.close();36        connection.close();37
38    }39}总结步骤:
- 1.加载驱动
- 2.连接数据库 DriverManager
- 3.获得sql对象
- 4.获得返回结果集
- 5.释放连接
加载驱动
xxxxxxxxxx1Class.forName("com.mysql.jdbc.Driver");//加载驱动 固定写法
URL
x
1String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";2
3// 协议://主机:端口/数据库名?参数1&参数2&... 连接数据库
x
1//DriverManager2Connection connection = DriverManager.getConnection(url,username,password);3//Connection 代表数据库,可以执行数据库级别的操作4//提交事务,设置自动提交...执行
x
1Statement statement = connection.createStatement();2//Statement执行SQL的对象3String sqlStr = "SELECT * FROM `users`";//编写SQL语句4
5statement.executeQuery(sqlStr);// 查询操作DQL,返回ResultSet6statement.executeUpdate(sqlStr);// 更新,插入,删除数据DML,返回影响的行数7statement.execute(sqlStr);//执行任何SQL 查询结果
x
131//不知道数据类型2resultSet.getObject(columnName);3//知道指定数据类型4resultSet.getString(columnName);5resultSet.getInt(columnName);6resultSet.getFloat(columnName);7resultSet.getDate(columnName);8//遍历结果集 (链表)9resultSet.beforeFirst();//移动到最前面10resultSet.afterLast();//移动到最后面11resultSet.next();//移动到下一个12resultSet.previous();//移动到前一个13resultSet.absolute(row);//移动到指定行释放资源
41//释放连接2resultSet.close();3statement.close();4connection.close();4 Statement对象
JDBC的Statement对象用于向指定数据库发送SQL语句
插入
实例:
x
1Statement statement = connection.createStatement();//创建对象2String sqlStr = "INSERT INTO `users`(`name`) VALUES('张三')";//SQL语句编写3int res = statement.executeUpdate(sqlStr);//执行SQL4if(res>0){5    System.out.println("成功插入");6}删除
实例:
x
1Statement statement = connection.createStatement();//创建对象2String sqlStr = "DELETE FROM `users` WHERE `id`=1";//SQL语句编写3int res = statement.executeUpdate(sqlStr);//执行SQL4if(res>0){5    System.out.println("成功删除");6}更新
实例:
x
1Statement statement = connection.createStatement();//创建对象2String sqlStr = "UPDATE `users` SET `name`='张三' WHERE `id`=1";//SQL语句编写3int res = statement.executeUpdate(sqlStr);//执行SQL4if(res>0){5    System.out.println("成功更新");6}查询
实例:
x
1Statement statement = connection.createStatement();//创建对象2String sqlStr = "SELECT * FROM `users`";//SQL语句编写3ResultSet resultSet = statement.executeQuery(sqlStr);//执行SQL4while(resultSet.next()){5    System.out.println(resultSet.getString(columnName));6}5 CURD测试
数据库连接配置文件db.properties
xxxxxxxxxx11driver = com.mysql.jdbc.Driver2url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false3username = root4password = 123456数据库连接工具类
xxxxxxxxxx1551public class jdbcUtils {2    private static String url = null;3    private static String username = null;4    private static String password = null;5
6    static {7        try{8            InputStream in = jdbcUtils.class.getClassLoader().getResourceAsStream("Config/db.properties");9            Properties properties = new Properties();10            properties.load(in);11
12            String driver = properties.getProperty("driver");13            url = properties.getProperty("url");14            username = properties.getProperty("username");15            password = properties.getProperty("password");16
17            //1.驱动只用加载一次18            Class.forName(driver);19
20        }catch (Exception e){21            e.printStackTrace();22        }23    }24
25    //获取连接26    public static Connection getConnection() throws SQLException {27        return DriverManager.getConnection(url,username,password);28    }29
30    //释放资源31    public static void release(Connection conn, Statement st, ResultSet rs){32        if (rs != null){33            try {34                rs.close();35            } catch (SQLException e) {36                e.printStackTrace();37            }38        }39        if (st != null){40            try {41                st.close();42            } catch (SQLException e) {43                e.printStackTrace();44            }45        }46        if (conn != null){47            try {48                conn.close();49            } catch (SQLException e) {50                e.printStackTrace();51            }52        }53    }54}插入
xxxxxxxxxx1231public class TestInsert {2    public static void main(String[] args) {3        Connection connection = null;4        Statement statement = null;5
6        try {7            connection = jdbcUtils.getConnection();8            //获取statement对象9            statement = connection.createStatement();10            String sqlStr = "INSERT INTO `users` (`id`,`NAME`,`PASSWORD`,`email`,`birthday`) VALUES"                             +"(4,'张三','123456','123123@qq.com','2000-01-01')";11            int res = statement.executeUpdate(sqlStr);12            if(res>0){13                System.out.println("插入成功");14            }15
16        } catch (SQLException e) {17            e.printStackTrace();18        } finally {19            jdbcUtils.release(connection,statement,null);20        }21    }22}更新
xxxxxxxxxx1221public class TestUpdate {2    public static void main(String[] args) {3        Connection connection = null;4        Statement statement = null;5
6        try {7            connection = jdbcUtils.getConnection();8            //获取statement对象9            statement = connection.createStatement();10            String sqlStr = "UPDATE `users` SET `NAME`='张三',email='123123@qq.com' WHERE id = 1";11            int res = statement.executeUpdate(sqlStr);12            if(res>0){13                System.out.println("修改成功");14            }15
16        } catch (SQLException e) {17            e.printStackTrace();18        } finally {19            jdbcUtils.release(connection,statement,null);20        }21    }22}删除
xxxxxxxxxx1231public class TestDelete {2    public static void main(String[] args) {3        Connection connection = null;4        Statement statement = null;5
6        try {7            connection = jdbcUtils.getConnection();8            //获取statement对象9            statement = connection.createStatement();10            String sqlStr = "DELETE FROM `users` WHERE `id`=4";11            int res = statement.executeUpdate(sqlStr);12            if(res>0){13                System.out.println("删除成功");14            }15
16        } catch (SQLException e) {17            e.printStackTrace();18        } finally {19            jdbcUtils.release(connection,statement,null);20        }21    }22}查询
xxxxxxxxxx1281public class TestQuery{2    public static void main(String[] args) {3        Connection connection = null;4        Statement statement = null;5        ResultSet resultSet = null;6
7        try {8            connection = jdbcUtils.getConnection();9
10            statement = connection.createStatement();11            String sqlStr = "SELECT * FROM `users`";12            resultSet = statement.executeQuery(sqlStr);13            while (resultSet.next()){14                System.out.println("--------------");15                System.out.println("id= " + resultSet.getInt("id"));16                System.out.println("name= " + resultSet.getString("NAME"));17                System.out.println("password= " + resultSet.getString("PASSWORD"));18                System.out.println("email= " + resultSet.getString("email"));19                System.out.println("birth= " + resultSet.getDate("birthday"));20            }21
22        } catch (SQLException e) {23            e.printStackTrace();24        } finally {25            jdbcUtils.release(connection,statement,resultSet);26        }27    }28}6 SQL注入
sql注入攻击:由于程序漏洞导致,用户输入数据时输入了恶意SQL语句导致数据库信息泄露
解决:对SQL语句关键字进行屏蔽过滤
测试:
341public class SqlInjection {2    public static void main(String[] args) {3        //login("张三","123456"); //正常登录4        login(" 'or '1=1","'or '1=1");//sql注入5    }6
7    //登录操作8    public  static void login(String username,String password){9        Connection connection = null;10        Statement statement = null;11        ResultSet resultSet = null;12
13        try {14            connection = jdbcUtils.getConnection();15
16            statement = connection.createStatement();17            String sqlStr = "SELECT * FROM `users` WHERE `NAME`='"+username+"' AND                                               `PASSWORD`='"+password+"'";18            resultSet = statement.executeQuery(sqlStr);19            while (resultSet.next()){20                System.out.println("--------------");21                System.out.println("id= " + resultSet.getInt("id"));22                System.out.println("name= " + resultSet.getString("NAME"));23                System.out.println("password= " + resultSet.getString("PASSWORD"));24                System.out.println("email= " + resultSet.getString("email"));25                System.out.println("birth= " + resultSet.getDate("birthday"));26            }27
28        } catch (SQLException e) {29            e.printStackTrace();30        } finally {31            jdbcUtils.release(connection,statement,resultSet);32        }33    }34}7 PreparedStatement对象
PreparedStatement可以防止SQL注入,效率更高
插入
x
331public class TestPreInsert {2    public static void main(String[] args) {3        Connection connection = null;4        PreparedStatement statement = null;5
6        try {7            connection = jdbcUtils.getConnection();8            //在获取statement前传入SQL语句 ?为占位符9            String sqlStr = "INSERT INTO jdbcstudy.users (id, NAME, PASSWORD, email, birthday) VALUES                              (?,?,?,?,?)";10
11            statement =  connection.prepareStatement(sqlStr);12            //手动传参赋值13            statement.setInt(1,4);14            statement.setString(2,"张三");15            statement.setString(3,"123456");16            statement.setString(4,"123123@qq.com");17            statement.setDate(5,new java.sql.Date(new Date().getTime()));18
19            //执行20            int res = statement.executeUpdate();21            if (res>0){22                System.out.println("插入成功");23            }24
25
26        } catch (SQLException e) {27            e.printStackTrace();28        } finally {29            jdbcUtils.release(connection,statement,null);30        }31
32    }33}删除
x
301public class TestPreDelete {2    public static void main(String[] args) {3        Connection connection = null;4        PreparedStatement statement = null;5
6        try {7            connection = jdbcUtils.getConnection();8            //在获取statement前传入SQL语句 ?为占位符9            String sqlStr = "DELETE FROM jdbcstudy.users WHERE id=?";10
11            statement =  connection.prepareStatement(sqlStr);12            //手动传参赋值13            statement.setInt(1,4);14
15            //执行16            int res = statement.executeUpdate();17            if (res>0){18                System.out.println("删除成功");19            }20
21
22        } catch (SQLException e) {23            e.printStackTrace();24        } finally {25            jdbcUtils.release(connection,statement,null);26        }27
28    }29}更新
x
291public class TestPreUpdate {2    public static void main(String[] args) {3        Connection connection = null;4        PreparedStatement statement = null;5
6        try {7            connection = jdbcUtils.getConnection();8            //在获取statement前传入SQL语句 ?为占位符9            String sqlStr = "UPDATE jdbcstudy.users SET NAME=? WHERE id = ?";10
11            statement =  connection.prepareStatement(sqlStr);12            //手动传参赋值13            statement.setString(1,"小明");14            statement.setInt(2,1);15
16            //执行17            int res = statement.executeUpdate();18            if (res>0){19                System.out.println("更新成功");20            }21
22        } catch (SQLException e) {23            e.printStackTrace();24        } finally {25            jdbcUtils.release(connection,statement,null);26        }27
28    }29}查询
x
1public class TestPreQuery {2    public static void main(String[] args) {3        Connection connection = null;4        PreparedStatement statement = null;5        ResultSet resultSet = null;6
7        try {8            connection = jdbcUtils.getConnection();9
10            String sqlStr = "SELECT * FROM jdbcstudy.users WHERE id=?";11
12            statement = connection.prepareStatement(sqlStr);13
14            statement.setInt(1,2);15
16            resultSet = statement.executeQuery();17
18            while (resultSet.next()){19                System.out.println("id=" + resultSet.getInt("id"));20                System.out.println("name=" + resultSet.getString("NAME"));21                System.out.println("password=" + resultSet.getString("password"));22                System.out.println("email=" + resultSet.getString("email"));23                System.out.println("birth=" + resultSet.getDate("birthday"));24            }25
26        } catch (SQLException e) {27            e.printStackTrace();28        } finally {29            jdbcUtils.release(connection,statement,resultSet);30        }31    }32}prepareStatement防止SQL注入:把传递的参数当做字符,特殊字符就会被转义而不是拼接字符串
8 事务
ACID原则:原子性,一致性,隔离性,持久性
- 原子性:一个事务包含的步骤,要不都完成要不都失败,不存在中间态
- 一致性:数据库操作数据符合运算规则
- 隔离性:多个事务同时执行互相不干扰
- 持久性:一但提交数据持久化到数据库,不可逆
- 隔离性问题: - 脏读:一个事务读取另一个事务没有提交的值
- 不可重复读:在同一个事务内,重复读取表中的数据,表数据发生改变
- 幻读:在一个事务内读取到别的事务插入的数据
 
程序模拟:
x
1public class TestTransaction {2    public static void main(String[] args) {3        TransferAccount(200,"a","b");4    }5
6    public static void TransferAccount(int money, String a, String b){7        Connection connection = null;8        PreparedStatement statement = null;9
10        try {11            connection = jdbcUtils.getConnection();12            //关闭自动提交 自动开启事务13            connection.setAutoCommit(false);14
15            String sqlStr1 = "UPDATE account SET money = money-? WHERE name = ?";16            statement = connection.prepareStatement(sqlStr1);17            statement.setInt(1,money);18            statement.setString(2,a);19            int res1 = statement.executeUpdate();20            if (res1>0){21                System.out.println("扣款完成");22            }else {23                throw new Exception("更新失败,扣款失败");24            }25
26            String sqlStr2 = "UPDATE account SET money = money+? WHERE name = ?";27            statement = connection.prepareStatement(sqlStr2);28            statement.setInt(1,money);29            statement.setString(2,b);30            int res2 = statement.executeUpdate();31            if (res2>0){32                System.out.println("加款完成");33            }else {34                throw new Exception("更新失败,加款失败");35            }36
37            connection.commit();38            System.out.println("成功");39
40        } catch (Exception e) {41            try {42                //这里失败会默认回滚 显式定义方便查看43                connection.rollback();44            } catch (SQLException e1) {45                e1.printStackTrace();46            }47            e.printStackTrace();48        } finally {49            jdbcUtils.release(connection,statement,null);50        }51    }52}总结步骤:
- 1.开启事务 connection.setAutoCommit(false);
- 2.执行SQL
- 3.若事务完成则提交事务 connection.commit();
- 4.捕获到异常自动回滚,也可以在catch显式定义 connection.rollback();
9 数据库连接池
正常程序执行流程:数据库连接->执行->释放连接
连接与释放需要耗费大量系统资源
池化技术:(线程池类似)预先创建连接,使用时直接使用连接好的
- 最小连接数:按常用连接数来设置
- 最大连接数:业务承载的上限 超过则等待
- 等待超时:等待时长超过此时长断开请求
开源数据源
- DBCP
- C3P0
- Druid
编写连接池:实现DataSource接口
DBCP
- commons-dbcp-1.4.jar
- commons-pool-1.6.jar
测试程序:
配置文件dbcpconfig.properties:
xxxxxxxxxx1341#连接设置2#这里驱动是5.1.47的版本3driverClassName=com.mysql.jdbc.Driver4url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false5username=root6password=1234567
8#初始化连接9initialSize=1010
11#最大连接数量12maxActive=5013
14#最大空闲连接15maxIdle=2016
17#最小空闲连接18minIdle=519
20#超时等待时间以毫秒为单位 6000毫秒/1000等于60秒21maxWait=6000022
23
24#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]25#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。26connectionProperties=useUnicode=true;characterEncoding=utf827
28#指定由连接池所创建的连接的自动提交(auto-commit)状态。29defaultAutoCommit=true30
31#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。32#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE33defaultTransactionIsolation=READ_UNCOMMITTED工具类jdbcUtils_DBCP:
x
1public class jdbcUtils_DBCP {2
3    private static DataSource dataSource = null;4
5    static {6        try{7            InputStream in = jdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("Config/dbcpconfig.properties");8            Properties properties = new Properties();9            properties.load(in);10
11            //创建数据源 工厂模式 -> 创建12            dataSource = BasicDataSourceFactory.createDataSource(properties);13
14        }catch (Exception e){15            e.printStackTrace();16        }17    }18
19    //获取连接20    public static Connection getConnection() throws SQLException {21        return dataSource.getConnection();//从数据源获取连接22    }23}测试程序:
x
1public class TestDBCP {2    public static void main(String[] args) {3        Connection connection = null;4        PreparedStatement statement = null;5
6        try {7            connection = jdbcUtils_DBCP.getConnection();8            //在获取statement前传入SQL语句 ?为占位符9            String sqlStr = "INSERT INTO jdbcstudy.users (id, NAME, PASSWORD, email, birthday) VALUES                              (?,?,?,?,?)";10
11            statement =  connection.prepareStatement(sqlStr);12            //手动传参赋值13            statement.setInt(1,4);14            statement.setString(2,"张三");15            statement.setString(3,"123456");16            statement.setString(4,"123123@qq.com");17            statement.setDate(5,new java.sql.Date(new Date().getTime()));18
19            //执行20            int res = statement.executeUpdate();21            if (res>0){22                System.out.println("插入成功");23            }24
25
26        } catch (SQLException e) {27            e.printStackTrace();28        } finally {29            jdbcUtils.release(connection,statement,null);30        }31    }32}C3P0
准备jar包:下载C3P0
- c3p0-0.9.5.5.jar
- mchange-commons-java-0.2.19.jar
测试程序:
配置文件c3p0-config.xml
xxxxxxxxxx1341 2
3<c3p0-config>4    <!-- 默认配置,如果没有指定则使用这个配置 -->5    <default-config>6        <property name="driverClass">com.mysql.jdbc.Driver</property>7        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false</property>8        <property name="user">root</property>9        <property name="password">123456</property>10
11
12        <property name="checkoutTimeout">30000</property>13        <property name="initialPoolSize">10</property>14        <property name="acquireIncrement">5</property>15        <property name="maxPoolSize">20</property>16        <property name="minPoolSize">5</property>17    </default-config>18    <!-- 命名的配置,可以通过方法调用实现 -->19    <named-config name="MySQL">20        <property name="driverClass">com.mysql.jdbc.Driver</property>21        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false</property>22        <property name="user">root</property>23        <property name="password">123456</property>24
25        <!-- 如果池中数据连接不够时一次增长多少个 -->26        <property name="acquireIncrement">5</property>27        <!-- 初始化数据库连接池时连接的数量 -->28        <property name="initialPoolSize">10</property>29        <!-- 数据库连接池中的最大的数据库连接数 -->30        <property name="maxPoolSize">20</property>31        <!-- 数据库连接池中的最小的数据库连接数 -->32        <property name="minPoolSize">5</property>33    </named-config>34</c3p0-config>工具类jdbcUtils_C3P0:
x
1public class jdbcUtils_C3P0 {2    private static ComboPooledDataSource dataSource = null;3    static {4        try{5            /*代码配置6            * dataSource = new ComboPooledDataSource();7            * dataSource.setDriverClass();8            * dataSource.setUser();9            * dataSource.setPassword();10            * dataSource.setJdbcUrl();11            *12            * dataSource.setMaxPoolSize();13            * dataSource.setMinPoolSize();*/14
15            //创建数据源 工厂模式 -> 创建16            dataSource = new ComboPooledDataSource("MySQL"); //配置文件写法17
18        }catch (Exception e){19            e.printStackTrace();20        }21    }22
23    //获取连接24    public static Connection getConnection() throws SQLException {25        return dataSource.getConnection();//从数据源获取连接26    }27}测试程序:
xxxxxxxxxx1321public class TestC3P0 {2    public static void main(String[] args) {3        Connection connection = null;4        PreparedStatement statement = null;5
6        try {7            connection = jdbcUtils_C3P0.getConnection();8            //在获取statement前传入SQL语句 ?为占位符9            String sqlStr = "INSERT INTO jdbcstudy.users (id, NAME, PASSWORD, email, birthday) VALUES                              (?,?,?,?,?)";10
11            statement =  connection.prepareStatement(sqlStr);12            //手动传参赋值13            statement.setInt(1,5);14            statement.setString(2,"张四");15            statement.setString(3,"122456");16            statement.setString(4,"123123@qq.com");17            statement.setDate(5,new java.sql.Date(new Date().getTime()));18
19            //执行20            int res = statement.executeUpdate();21            if (res>0){22                System.out.println("插入成功");23            }24        } catch (SQLException e) {25            e.printStackTrace();26        } finally {27            jdbcUtils.release(connection,statement,null);28        }29    }30}
posted on 2021-11-27 05:42 Egoistic_Flowers 阅读(35) 评论(0) 收藏 举报
 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号