概念

Java DataBase Connectivity java数据库连接

定义了操作所有关系型数据库的规则(接口),不同的数据库厂商编写类实现这些接口,这些类就叫数据库驱动,使得用户只需要使用统一的接口操作不同的数据库

快速入门

public void test(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
//1.导入驱动jar包,如mysql-connector-java-5.1.37-bin.jar
// 新建目录,复制jar包,将存放jar包的目录右键选择add as library
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库连接对象 Connection
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbName","root","1234");
//url也可以为"jdbc:mysql://localhost:3306/dbName?user=root&password=1234"
//4.定义sql语句
String sql = "select * from account";
//5.获取执行sql语句的对象Statement,实际开发用PreparedStatement
stmt = conn.createStatement();
//6.执行sql,接收返回结果
rs = stmt.executeQuery(sql);
//7.处理结果
while(rs.next()){
int id = rs.getInt(1);
String name = rs.getString("name");
System.out.println(id + " " + name);
}
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}finally {
//释放资源
if(rs != null){
try{
rs.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}

组件分析

  1. DriverManager:驱动管理对象

    • 注册驱动,5.0版本后可以省略注册让其自动注册

      Class.forName("com.mysql.jdbc.Driver"); 实际通过静态代码块调用了 static void registerDriver(Driver driver);以注册驱动(告诉程序该使用哪个哪一个数据库驱动)

    • 获取数据库连接

      static Connection getConnection(String url, String user, String password);

      url:指定连接的路径,如果连接的是本机mysql并且端口是3306,url可以写成"jdbc:mysql///dbName"

  2. Connection:数据库连接对象

    • 获取执行sql的对象

      Statement createStatement();

      PreparedStatement prepareStatement(String sql);

    • 管理事务

      开启事务:setAutoCommit(boolean autoCommit); 设置参数为false即开启

      提交事务:commit();

      回滚事务:rollback();

  3. Statement:执行静态sql (参数给定不可更改) 并返回结果集的对象

    • 执行sql

      • boolean execute(String sql); 执行任意sql语句(不常用)

      • int executeUpdate(String sql); 执行DML(insert, update, delete)和DDL(create, alter, drop)语句,DDL不返回值且不常用

        返回值:受影响的行数,可以通过返回值判断执行是否成功,大于0则成功

      • ResultSet executeQuery(String sql); 执行DQL(select)语句

  4. ResultSet:结果集对象

    • next():游标向下移动一行,游标初始在第一行上面一行

    • getXxx():获取数据,Xxx代表数据类型,如getInt(); getString();

      参数:int:代表列的编号,从1开始

      ​ String:代表列的名称

    • 在try之前声明ResultSet rs = null;

  5. PreparedStatement(常用):执行静态sql (参数给定不可更改) 并返回结果集的对象

    • SQL注入问题: 在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,有安全隐患

      1. 登录时,只要密码为 a' or 'a' = 'a
      2. sql: select * from user where username = 'whatever' and password = 'a' or 'a' = 'a';
      3. 条件为true,会查询所有user
    • 解决sql注入问题:使用PrepareStatement对象

    • 预编译的sql:使用问号作为点位符

    • 使用步骤

      String sql = "select * from user where username = ? and password = ?";
      pstmt = conn.prepareStatement(sql);
      pstmt.setString(1, username); //参数位置从1开始
      pstmt.setString(2, password);
      rs = pstmt.executeQuery();
    • 一般采用PreparedStatement,可以防止SQL注入,而且效率更高

自定义JDBC工具类:JDBCUtils

jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///dbName
user=root
password=1234
public class JDBCUtils{
private static String driver;
private static String url;
private static String user;
private static String password;
//使用静态代码块读取文件,使得类加载时就读取文件且只读取这一次
static{
try{
//创建Properties集合类
Properties pro = new Properties();
//获取src路径下文件的方式,ClassLoader 类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = ClassLoade.getResource("jdbc.properties");
String path = res.getPath();
//加载文件
pro.load(new FileReader(path));
//读取数据
driver = pro.getProperty("driver");
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
class.forName(driver);
} catch(IOException e){
e.printStackTrace();
} catch(ClassNotFoundException e){
e.printStackTrace();
}
}
public static Connection getConnection(){
return DriverManager.getConnection(url, user, password);
}
public static void close(Statement stmt, Connection conn){
if(rs != null){
try{
rs.close();
}catch (SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
public static void close(Statement stmt, Connection conn, Result rs){
close(stmt, conn);
if(rs != null){
try{
rs.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}

使用工具类

public class login(String username, String password){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
conn = JDBCUtils.getConnection();
String sql = "select * from user where username = ? and password = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
rs = pstmt.executeQuery();
return rs.next(); //如果有结果,则返回true
}catch(SQLException e){
e.printStackTrace();
}finally{
JDBCUtils.close(rs, pstmt, conn);
}
}

JDBC控制事务

  • 用Connection对象来管理事务

  • 开启事务:setAutoCommit(boolean autoCommit); 设置参数为false即开启

    • 执行sql之前开启事务

    提交事务:commit();

    • 当所有sql都执行完提交事务

    回滚事务:rollback();

    • 在catch中回滚事务

连接池

  • 数据库连接池

    • 概念:数据库连接池是一个存放数据库连接的容器,当系统初始化好后,窗口被创建,容器中会申请 一些连接对象,当用户来访问数据库时,从容器在中获取连接对象,用户访问完之后 ,会将连接对象归还容器。
    • 好处:节约资源,用户访问更高效
    • 实现:数据库厂商实现javax.sql.DataSource接口,接口下有getConnection()方法,连接池把close()方法增强,关闭连接变成归还连接
  • c3p0

    1. 导入jar包(两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar

    2. 定义配置文件 c3p0.properties 或 c3p0-config.xml 放在src目录下,也可以用dataSource.setXxx(...)在代码中配置

      # c3p0.properties
      c3p0.driverClass=com.mysql.jdbc.Driver
      c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc
      c3p0.user=root
      c3p0.password=java
      ...
      <!-- c3p0-config.xml -->
      <?xml version="1.0" encoding="UTF-8"?>
      <c3p0-config>
      <!-- 默认配置,如果没有指定则使用这个配置 -->
      <default-config>
      <property name="user">root</property>
      <property name="password">1234</property>
      <property name="jdbcUrl">jdbc:mysql://localhost:3306/dbName</property>
      <property name="driverClass">com.mysql.jdbc.Driver</property>
      <property name="checkoutTimeout">30000</property>
      <property name="idleConnectionTestPeriod">30</property>
      <property name="initialPoolSize">3</property>
      <property name="maxIdleTime">30</property>
      <property name="maxPoolSize">100</property>
      <property name="minPoolSize">2</property>
      <property name="maxStatements">200</property>
      </default-config>
      <!-- 命名的配置,配置多个config,可以通过相同的配置文件去配置不同的数据源,新建数据源时传入name即可 -->
      <named-config name="test">
      <property name="user">root</property>
      <property name="password">1234</property>
      <property name="jdbcUrl">jdbc:mysql://localhost:3306/dbName</property>
      <property name="driverClass">com.mysql.jdbc.Driver</property>
      <!-- 如果池中数据连接不够时一次增长多少个 -->
      <property name="acquireIncrement">5</property>
      <!-- 初始化数据库连接池时连接的数量 -->
      <property name="initialPoolSize">20</property>
      <!-- 数据库连接池中的最大的数据库连接数 -->
      <property name="maxPoolSize">25</property>
      <!-- 数据库连接池中的最小的数据库连接数 -->
      <property name="minPoolSize">5</property>
      </named-config>
      </c3p0-config>
    3. 创建核心对象,数据库连接池对象 DataSource ds = new ComboPooledDataSource();

    4. 获取连接:getConnection();

  • druid

    1. 导入jar包 druid-1.0.9.jar

    2. 定义配置文件,properties类型,放在任意目录下

    3. 加载配置文件

      Properties pro = new Properties();
      InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
      pro.load(is);
    4. 获取数据库连接池对象,通过工厂类来获取 DruidDataSourceFactory

      DataSource ds = DruidDataSourceFactory.createDataSource(pro);
    5. 获取连接:getConnection();

    • 自定义工具类

      public class JDBCUtils{
      private static DataSource ds;
      static{
      try{
      Properties pro = new Properties();
      pro.load(JDBCUtils.class.getClassLoader(). getResourceAsStream("druid.properties"););
      ds = DruidDataSourceFactory.createDataSource(pro);
      }catch(IOException e){
      e.printStackTrace();
      }catch(Exception e){
      e.printStackTrace();
      }
      }
      public static Connection getConnection() throws SQLException{
      return ds.getConnection();
      }
      public static void close(...){...}
      public static DataSource getDataSource(){return ds;}
      }

Spring JDBCTemplate

  • Spring框架对JDBC的简单封装,提供了一个JdbcTemplate对象简化JDBC的开发

  • 使用步骤

    1. 导入jar包

      commons-logging、spring-beans、spring-core、spring-jdbc、spring-tx

    2. 创建对象,依赖于数据源DataSource

      JdbcTemplate template = new JdbcTemplate(dataSource);
    3. 调用JdbcTemplate的方法来完成CRUD操作

      • update():执行DML语句

      • queryForMap():DQL,并将结果集封装为map集合,key为字段名,value为字段值,只能封装一条记录,如果查出多条会报错

      • queryForList():DQL,并将结果集封装到list集合,将每条记录封装为map,再将map存入list中

      • query():DQL,并将结果集封闭到JavaBean的list中

        //自定义RowMapper方式(不常用)
        List<User> list = template.query(sql, new RowMapper<User>{
        @Override
        public User mapRow(ResultSet rs, int i) throws SQLException{
        User user = new User();
        user.setId(rs.getInt("id"));
        user.setName(rs.getString("name"));
        return user;
        }
        });
        //使用spring提供的RowMapper方式,JavaBean中基本类型用封装类可以避免null错误
        List<User> list = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
      • queryForObject():DQL,并将结果封装到对象,一般为基本类型的封装对象,用于聚合函数的查询

  • Demo

    public void test(){
    JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
    String sql = "update account set balance = 5000 where id = ?";
    int count = template.update(sql, 1); //sql后按顺序传参数
    System.out.println(count);
    }

JDBC 复习的更多相关文章

  1. JDBC复习

    -----------------------------------------JDBC复习----------------------------------------- 1.JDBC (Jav ...

  2. JDBC复习2

    前面复习了一些基础知识以及如何抽取一些常用的代码,接下来就结合junit4做一个增删改查的小demo 重点是这么几个步骤:1.创建连接 2.编写sql语句 3.编写sql语句的载体 4.如果是Prep ...

  3. JDBC复习1

    1.什么是JDBC JDBC是java数据库连接技术的简称(Java DataBase Connectivity) jdbc是接口,jdbc驱动才是接口的实现,负责连接各种不同的数据库.jdbc的AP ...

  4. JDBC 复习4 批量执行SQL

    1使用jdbc进行批量执行SQL在实际的项目开发中,有时候需要向数据库发送一批SQL语句执行,这时应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率. package dbe ...

  5. JDBC 复习3 存取Oracle大数据 clob blob

    1 目录结构记得导包咯 mysql oracle 2 代码,DBUtil工具类见前面的随笔博文 package dbex.mysql; import java.io.BufferedReader; i ...

  6. JDBC 复习2 存取mysql 大数据

    大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据 mysql的大数据分为2种 blob 和 text ,没有cl ...

  7. JDBC 复习1 DBUtil

    package dbex; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; impo ...

  8. JDBC 复习5 mysql 的自增长主键 auto_increment

    MySQL 自增长主键 (1)如果把一个NULL插入到一个AUTO_INCREMENT数据列里去,MySQL将自动生成下一个序列编号.编号从1开始,并1为基数递增. (2)把0插入AUTO_INCRE ...

  9. JDBC(三)数据库连接池(DBCP、C3P0)

    前言 这段时间状态有一点浮躁,希望自己静下心来.还有特别多的东西还没有学懂.需要学习的东西非常的多,加油! 一.JDBC复习 Java Data Base Connectivity,java数据库连接 ...

随机推荐

  1. STL杂记

    STL介绍: 我所理解的stl: 容器: 是一种数据结构,如list,vector,和deques ,以模板类的方法提供.为了访问容器中的数据,可以使用由容器类输出的迭代器: 算法:  是用来操作容器 ...

  2. dapi 基于Django的轻量级测试平台四 任务设置

    QQ群: GitHub:https://github.com/yjlch1016/dapi 一.间隔时间: 二.定时时间: 三.任务设置: 四.任务结果:

  3. django crm2

    1.模糊查询 由于Q的可以传递字符串属性,可以进行拼接__contains 进行搜索 2.未报名筛选,未报名的存储在models的 enroll_status_choices中,存储的是 enroll ...

  4. 201871010110-李华《面向对象程序设计(java)》第6-7周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  5. 20180706模拟赛T2——染色

    文件名: seq 题目类型: 传统题 时间限制: 1秒 内存限制: 128MB 编译优化: 无 题目描述 小A正在帮助小M刷她家的墙壁 小M家的墙可以分为\(n\)块,每段需要被刷成黑色或者白色.你可 ...

  6. Qt常用类——QWidget

    QWidget类是所有用户界面对象的基类. Widget是用户界面的基本单元:它从窗口系统接收鼠标,键盘和其他事件,并在屏幕上绘制自己. 每个Widget都是矩形的,它们按照Z-order进行排序.

  7. Apache的代理服务器的配置 (正向代理 ,反向代理,轮询调度)

    一. 代理服务器的了解1.代理服务器 代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息. Squid是一个缓存Internet 数据的软件,其接收用户的下载申请,并自 ...

  8. python 之类的继承

    #类的继承 class As1(): def As2(self): print("he11...") class As2(As1): def As2(self): print(&q ...

  9. [技术博客]微信小程序审核的注意事项及企业版小程序的申请流程

    关于小程序审核及企业版小程序申请的一些问题 微信小程序是一个非常方便的平台.由于微信小程序可以通过微信直接进入,不需要下载,且可使用微信账号直接登录,因此具有巨大的流量优势.但是,也正是因为微信流量巨 ...

  10. asbDio (asbDio.dll)

    using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices ...