- JDBC
- JDBC介绍
- 概念:Java DataBase Connectivity
- 作用:使用Java来访问数据库,实现对数据库的操作
- 本质上是一组接口,程序员针对接口进行编程。好处是:同一组代码可以访问不同的数据库。
- 接口的实现类由数据库厂商实现,这个实现类其实就是数据库的驱动,需要jar包
- 思维图解
-
- JDBC API配置
- 创建工程
- 创建模块
- 1. 创建lib目录,将mysql驱动复制到lib目录下
- 2. 编写Java代码获取连接对象,验证是否成功
- DriverManager.getConnection(连接字符串,用户名,密码)
- 如果使用JDBC添加汉字出现乱码,需要在连接字符串上,额外指定一个参数characterEncoding=utf8,参数与访问地址前面使用?分隔
- DriverManager.getConnection(连接字符串,用户名,密码)
- 创建工程
- 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类型
- 相应的方法
- 相应的方法
- next()
- 代码
- //查询操作@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. 实体类中属性类型,基本类型建议使用包装类
- ORM
- 步骤
- SQL注入
- 输入的字符串与系统的SQL语句拼接成另一个SQL语句,功能上发生变化,会有安全隐患。
- 解决方法:使用Statement的子接口,即PreparedStatement
- 实现增删改DML操作
- 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(); } } }}
- Connection连接对象方法
- 连接池(接口是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(); } } }}
- 原理
- JDBC介绍
08-16
1243
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交