JDBC介绍

  • JDBC
    • JDBC介绍
      • 概念:Java DataBase Connectivity
      • 作用:使用Java来访问数据库,实现对数据库的操作
      • 本质上是一组接口,程序员针对接口进行编程。好处是:同一组代码可以访问不同的数据库。
      • 接口的实现类由数据库厂商实现,这个实现类其实就是数据库的驱动,需要jar包
      • 思维图解
    • JDBC API配置
      • 创建工程
      • 创建模块
        • 1. 创建lib目录,将mysql驱动复制到lib目录下
        • 2. 编写Java代码获取连接对象,验证是否成功
          • DriverManager.getConnection(连接字符串,用户名,密码) 
          • 如果使用JDBC添加汉字出现乱码,需要在连接字符串上,额外指定一个参数characterEncoding=utf8,参数与访问地址前面使用?分隔
    • JDBC的使用步骤
      • 1.注册驱动
      • 2.获取数据库连接
      • 3.获取执SQL语句对象
      • 4.执行SQL语句并返回结果
      • 5.处理结果
      • 6.释放资源
      • 这几个类都是在java.sql包中DriverManager: 用于注册驱动创建连接Connection: 表示数据库的连接Statement: 执行SQL语句的对象ResultSet: 结果集或一张虚拟表
    • Statement接口实现增删改查
      • 实现增删改DML操作
        • 步骤
          • 1. 通过DriverManager创建连接对象Connection
          • 2. 通过Connection创建Statement语句对象
          • 3. 使用executeUpdate(sql语句)执行SQL语句,返回影响的行数
          • 4. 关闭连接:先开后关,后开先关
        • 代码
          • package com.itheima;import org.junit.Test;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;/** * 实现增删改操作 */public class Demo2DML { //按下alt+enter,自动导入junit //添加,修改,删除的代码是一样的 @Test public void testAdd() throws SQLException { //1.创建连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.通过连接对象创建SQL语句对象,指定SQL语句 Statement statement = connection.createStatement(); //3.实现增删改操作,返回影响的行数 int row = statement.executeUpdate("insert into user values(null,'猪八戒','111'),(null,'牛魔王','222')"); System.out.println("添加了" + row + "行记录"); //4.释放资源(先开的后关,后开的先关) statement.close(); connection.close(); } //修改:唯一不同的就只是SQL语句不一样 @Test public void testUpdate() throws SQLException { //1.创建连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.通过连接对象创建SQL语句对象,指定SQL语句 Statement statement = connection.createStatement(); //3.实现增删改操作,返回影响的行数 int row = statement.executeUpdate("update user set name='铁扇公主',password='222' where id=4"); System.out.println("修改了" + row + "行记录"); //4.释放资源(先开的后关,后开的先关) statement.close(); connection.close(); } //删除:唯一不同的就只是SQL语句不一样 @Test public void testDelete() throws SQLException { //1.创建连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.通过连接对象创建SQL语句对象,指定SQL语句 Statement statement = connection.createStatement(); //3.实现增删改操作,返回影响的行数 int row = statement.executeUpdate("delete from user where id=2"); System.out.println("删除了" + row + "行记录"); //4.释放资源(先开的后关,后开的先关) statement.close(); connection.close(); }}
      • 实现DQL查询操作
        • 步骤
          • 1. 通过DriverManager创建连接对象Connection
          • 2. 通过Connection创建Statement语句对象
          • 3. 使用executeQuery(sql语句)执行SQL语句,返回数据集合
          • 5.使用next()方法,因为一次只能获取一条数据,所以用循环以及getXxx()方法获取每一个属性值
          • 6. 关闭连接:先开后关,后开先关
        • ResultSet结果集
          • next()
            • 1. 将指针向下移动一行
            • 2. 如果返回false表示遍历结束
          • get类型
            • 相应的方法
        • 代码
          • //查询操作@Testpublic void testFindAll() throws SQLException { //1.创建连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.通过连接对象创建SQL语句对象,指定SQL语句 Statement statement = connection.createStatement(); //3.实现查询操作,方法名不同,返回的是结果集 ResultSet resultSet = statement.executeQuery("select * from user"); /* 1. 向后移动一行 2. 如果返回false表示数据已经遍历结束 */ while(resultSet.next()) { //获取这一行的数据 int id = resultSet.getInt("id"); String name = resultSet.getString("name"); String password = resultSet.getString("password"); System.out.println("编号:" + id + ",姓名:" + name + ",密码:" + password); } //4.释放资源(先开的后关,后开的先关) //结果集也要关闭 resultSet.close(); statement.close(); connection.close();}
        • 封装结果集
          • ORM
            • Object Relational Mapping 对象关系映射
            • 映射机制
              • 表映射类
              • 字段映射成实体类的成员变量
              • 记录映射成对象
          • 封装原则
            • 1. 一条记录,封装成一个User对象,列名对应属性
            • 2. 多条记录,封装成List集合,其中每个元素是User对象
            • 3. 实体类中属性类型,基本类型建议使用包装类
      • SQL注入
        • 输入的字符串与系统的SQL语句拼接成另一个SQL语句,功能上发生变化,会有安全隐患。
        • 解决方法:使用Statement的子接口,即PreparedStatement
    • Statement的子接口PreparedStatement
      • 特点:
        • 1. 没有SQL注入的问题
        • 2. SQL语句是预先编译,执行效率更高
        • 3. 没有字符串拼接,代码可读性更好
      • 增删改步骤查数据的话,就步骤5的方法不同:executeQuery(),返回数据的集合
        • 1. 通过DriverManager创建连接对象Connection
        • 2. 通过Connection创建PreparedStatement语句对象connection.PreparedStatement(sql语句);看具体需求,条件里面的值替换成占位符?
        • 4.需要替换占位符:set类型(参数1, 参数2)【参数1是第几个问号,从1开始;参数2是给问号的赋值】
        • 5. 使用executeUpdate()执行SQL语句,返回影响的行数
        • 6. 关闭连接:先开后关,后开先关
      • 方法:
        • 创建子接口:connection.prepareStatement(SQL语句)
        • 需要替换占位符:set类型(参数1, 参数2)【参数1是第几个问号,从1开始;参数2是给问号的赋值】
        • 增删改:int executeUpdate()
        • 查:ResultSet executeQuery()
      • 与父接口statement的区别
        • 1.preparedStatement 在创建语句对象的时候就需要编译SQL语句,而statement在执行的时候才编译SQL语句
        • 2.preparedStatement 创建语句对象后,需要给占位符赋值
        • 3.preparedStatement 在执行增删改查语句的时候,不需要编译SQL语句了
      • 案例:品牌的CRUD(增删改查)
        • package com.itheima;import com.itheima.pojo.Brand;import org.junit.Test;import java.sql.*;import java.util.ArrayList;import java.util.List;/** * 使用子接口实现增删改操作 */public class Demo6Brand { /** * 查询所有状态为1的品牌 */ @Test public void testFind() throws SQLException { //1.获取连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.创建预编译的语句对象 PreparedStatement preparedStatement = connection.prepareStatement("select * from tb_brand where status=?"); //3.如果有占位符需要替换占位符 preparedStatement.setInt(1,1); //4.执行SQL语句,得到结果集 ResultSet resultSet = preparedStatement.executeQuery(); //5.将结果集封装成List对象 List brandList = new ArrayList(); while(resultSet.next()) { //每条记录封装成一个对象 Brand brand = new Brand(); brand.setId(resultSet.getInt("id")); brand.setBrandName(resultSet.getString("brand_name")); brand.setCompanyName(resultSet.getString("company_name")); brand.setOrdered(resultSet.getInt("ordered")); brand.setDescription(resultSet.getString("description")); brand.setStatus(resultSet.getInt("status")); //将每个对象添加到集合中 brandList.add(brand); } //6.释放资源,关闭连接 resultSet.close(); preparedStatement.close(); connection.close(); //输出 brandList.forEach(System.out::println); } /** * 添加记录 */ @Test public void testAdd() throws SQLException { //1.获取连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.创建预编译的语句对象 PreparedStatement preparedStatement = connection.prepareStatement("insert into tb_brand values(null,?,?,?,?,?)"); //3.如果有占位符需要替换占位符 preparedStatement.setString(1, "人鬼情喂鸟"); preparedStatement.setString(2, "三味书屋"); preparedStatement.setInt(3, 100); preparedStatement.setString(4, "香港的味道"); preparedStatement.setInt(5, 0); //4.执行SQL语句,得到影响的行数 int row = preparedStatement.executeUpdate(); //5.释放资源,关闭连接 preparedStatement.close(); connection.close(); //输出 System.out.println("添加了" + row + "行"); } /** * 修改记录 */ @Test public void testUpdate() throws SQLException { //1.获取连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.创建预编译的语句对象 PreparedStatement preparedStatement = connection.prepareStatement("update tb_brand set brand_name=?,company_name=? where id=?"); //3.如果有占位符需要替换占位符 preparedStatement.setString(1, "菠萝手机"); preparedStatement.setString(2, "菠萝公司"); preparedStatement.setInt(3, 5); //4.执行SQL语句,得到影响的行数 int row = preparedStatement.executeUpdate(); //5.释放资源,关闭连接 preparedStatement.close(); connection.close(); //输出 System.out.println("修改了" + row + "行"); } /** * 删除记录 */ @Test public void testDelete() throws SQLException { //1.获取连接对象 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "root"); //2.创建预编译的语句对象 PreparedStatement preparedStatement = connection.prepareStatement("delete from tb_brand where id=?"); //3.如果有占位符需要替换占位符 preparedStatement.setInt(1, 5); //4.执行SQL语句,得到影响的行数 int row = preparedStatement.executeUpdate(); //5.释放资源,关闭连接 preparedStatement.close(); connection.close(); //输出 System.out.println("删除了" + row + "行"); }}
    • 案例:对事务操作
      • Connection连接对象方法
        • 手动提交事务
          • setAutoCommit(false)
        • 提交事务
          • commit()
        • 回滚事务
          • rollback()
      • 代码
        • package com.itheima;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;/** * 事务处理:转账案例 */public class Demo3Transaction { public static void main(String[] args) { Connection connection = null; Statement statement = null; try { //1.获取连接对象 connection = DriverManager.getConnection("jdbc:mysql:///day17", "root", "root"); //设置为手动提交事务 connection.setAutoCommit(false); //2.创建语句对象 statement = connection.createStatement(); //3.更新张三和李四的账户金额,实现转账 statement.executeUpdate("update account set balance=balance-500 where name='张三'"); //模拟出现异常的情况 int m = 1 / 0; statement.executeUpdate("update account set balance=balance+500 where name='李四'"); //所有的DML代码都执行完毕后提交事务 connection.commit(); System.out.println("转账成功"); } catch (Exception throwables) { //捕获所有的异常 //回滚事务 try { connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } System.out.println("转账失败"); } finally { try { //4.释放资源 statement.close(); connection.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } } }}
    • 连接池(接口是DataSource)
      • 原理
        • 1. 在服务器启动的时候,就预先创建一定数量的连接对象
        • 2. 不再由自己创建连接对象,而是从连接池中获取创建好的连接
        • 3. 连接对象使用完毕,不再关闭连接,而是放回到连接池中
      • 好处:连接池会保存一些连接,这些连接可以重复使用,降低数据资源的消耗
      • Druid连接池参数(Druid是具体的实现类)
        • 用户名
        • 密码
        • 连接字符串
        • 驱动
        • 初始连接数
        • 最大连接数
        • 最长等时间
        • 代码
          • # 连接字符串url=jdbc:mysql://localhost:3306/day17# 用户名username=root# 密码password=root# 驱动类driverClassName=com.mysql.jdbc.Driver# 初始连接数initialSize=5# 最大连接数maxActive=10# 最长等待时间maxWait=2000
      • 步骤
        • 1. 加载mysql驱动和连接池jar包(druid)
        • 2. 通过Properties类读取druid.properties属性值 (类路径下文件)
        • 3.通过DruidDataSourceFactory静态方法:createDataSource(属性文件),创建数据源对象
        • 4.从数据源中获取连接对象
      • 代码
        • package _03_Druid的使用;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.InputStream;import java.sql.Connection;import java.util.Properties;/** * 使用连接池获取连接对象 */public class DemoDataSource { public static void main(String[] args) throws Exception { //1.获取属性文件 Properties properties = new Properties(); //加载带properties对象中 /* 注:从类路径(理解为src目录)下加载输入流对象,通过类对象的方法获取 1) 类对象.getResourceAsStream(),在当前类所在的包下去获取 2)类加载器.getResourceAsStream(),始终从类的根目录下读取文件 将文件读取,并且转为InputStream对象 */ //第一种方法 //InputStream inputStream = DemoDataSource.class.getResourceAsStream("/druid.properties"); //第二种方法 InputStream inputStream = DemoDataSource.class.getClassLoader().getResourceAsStream("druid.properties"); //输入流读取到的文件载入属性集合 properties.load(inputStream); System.out.println(properties); //通过数据工厂创建数据源,需要提供创建数据源的属性 DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); //从数据源中获取连接对象 for (int i = 1; i <= 11; i++) { Connection connection = dataSource.getConnection(); System.out.println("第"+i+"个连接:"+connection); //释放一个连接 if(i==2){ //不是真的关闭,而是将连接放回连接池中 connection.close(); } } }}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值