03JDBC[数据库教程]

database

JDBC

JDBC是Java访问数据库的标准规范,具体操作具体由数据库厂商实现,相当于一个数据库驱动。我们只需要会JDBC接口中的方法即可,数据库驱动(jar包)由数据库厂商提供。

导入驱动jar包:

  1. 创建libs文件夹
  2. 复制jar包到libs
  3. 右键libs->add as library

JDBC快速实现:

public class Test {

public static void main(String[] args) throws Exception {

// 1. 注册驱动

Class.forName("com.mysql.jdbc.Driver");

// 2. 获取数据库连接对象

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "root", "root");

// 3. 定义sql语句

String sql = "update stu set score=80 where id=1";

// 4. 获取sql执行对象

Statement stmt = conn.createStatement();

// 5. 执行sql

int count = stmt.executeUpdate(sql);

// 6. 处理结果

System.out.println(count);

// 7. 释放资源

stmt.close();

conn.close();

}

}

JDBC的核心API:

  1. DriverManager 驱动管理对象,返回数据库连接对象

    • URL参数如果是本地 可以省略 jdbc:mysql:///stu
    • 处理乱码:jdbc:mysql///stu?characterEncoding=utf8

  2. Connection 数据库连接对象,用于创建一条SQL语句对象

    • Statement stmt = conn.createStatment();
    • PreparedStatment pstmt = conn.prepareStatement(sql);
    • setAutoCommit(boolean); 开始事务
    • commit(); 提交事务
    • rollback(); 回滚事务

  3. Statement 执行静态sql对象

    • boolean execute(sql); 执行任意sql
    • int executeUpdate(sql); 增删改、创建、修改、删除
    • ResultSet executeQuery(sql); 查找

  4. PreparedStatment 执行动态sql对象

  5. ResultSet:执行结果

    ResultSet rs = stmt.executeQuery(sql);

    while (rs.next()) {

    int id = rs.getInt(1); // 根据列号

    String name = rs.getString("name"); // 根据列名

    System.out.println(id + ": " + name);

    }

JdbcUtils

如果一个功能经常要用到(代码重复),就把这个功能做成工具类。

解决:

  1. 工具类中定义许多静态方法,通过传递参数解决;
  2. 如果不想传参,则把参数放在配置文件jdbc.properties中传递;
  3. 配置文件只需要读取一次即可,所以把读取配置文件代码放在静态代码块中。

最终如下:

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

url=jdbc:mysql://localhost:3306/db1

user=root

password=root

driver=com.mysql.jdbc.Driver

  1. 创建工具类 JDBCUtils.java

import java.io.FileReader;

import java.io.IOException;

import java.net.URL;

import java.sql.*;

import java.util.Properties;

public class JDBCUtils {

private static String url;

private static String user;

private static String password;

private static String driver;

static {

try {

// 获取绝对路径

ClassLoader classLoader = JDBCUtils.class.getClassLoader();

URL res = classLoader.getResource("jdbc.properties");

String path = res.getPath();

// 加载配置文件

Properties pro = new Properties();

pro.load(new FileReader(path));

url = pro.getProperty("url");

user = pro.getProperty("user");

password = pro.getProperty("password");

driver = pro.getProperty("driver");

// 注册驱动

Class.forName(driver);

} catch (IOException | ClassNotFoundException e) {

e.printStackTrace();

}

}

public static Connection getConnection() throws SQLException {

return DriverManager.getConnection(url, user, password);

}

public static void close(Statement stmt, Connection conn) {

if (stmt != null) {

try {

stmt.close();

} catch (SQLException throwables) {

throwables.printStackTrace();

}

}

if (conn != null) {

try {

conn.close();

} catch (SQLException throwables) {

throwables.printStackTrace();

}

}

}

public static void close(Statement stmt, Connection conn, ResultSet rs) {

if (rs != null) {

try {

rs.close();

} catch (SQLException throwables) {

throwables.printStackTrace();

}

}

close(stmt, conn);

}

}

  1. 数据库连接(测试工具类)

import java.sql.*;

public class JdbcDemo {

public static void main(String[] args) {

Connection conn = null;

Statement stmt = null;

ResultSet rs = null;

try {

conn = JDBCUtils.getConnection();

stmt = conn.createStatement();

String sql = "select * from stu";

rs = stmt.executeQuery(sql);

while (rs.next()) {

int id = rs.getInt("id");

String name = rs.getString("name");

System.out.println(id + ": " + name);

}

} catch (SQLException throwables) {

throwables.printStackTrace();

} finally {

JDBCUtils.close(stmt, conn, rs);

}

}

}

PreparedStatment

SQL注入问题:在用户密码和数据库匹配时,如果SQL语句是:

select * from user where name=‘Tom‘ and password=‘root‘ or 1=1;

则返回所有查询结果。

所以 使用PreparedStatment匹配SQL语句中的占位符?,可以防止SQL注入问题。

// 定义sql

String sql = "select * from user where name=? and password=?";

// 获取执行sql的对象

PreparedStatement pstmt = conn.getpreparedStatement(sql);

// 赋值

pstmt.setString(1, "Tom");

pstmt.setString(2, "123");

// 执行

ResultSet rs = pstmt.executeQuery();

JDBC控制事务

使用Connection对象管理事务:

  • setAutoCommit(boolean);` 开始事务:设置为false,相当于开启事务
  • commit(); 提交事务
  • rollback(); 回滚事务

案例:

Connection conn =  null;

PrepareStatment ps = null;

try{

conn = JdbcUtils.getConnection();

conn.setAutoCommit(false); // 开启事务

ps = conn.prepareStatment("update stu set score=? where name=?");

ps.setInt(1, 90);

ps.setString(2, "张三");

ps.executeUpdate();

conn.commit(); // 提交事务

} catch () {

conn.rollback(); // 回滚事务

} finally {

JdbcUtils.close(ps, conn);

}

JDBC连接池

之前都是每次连接数据库,执行完sql立马释放资源,降低了执行效率,因此提出数据库连接池。

  1. 接口:javax.sql.DataSourrce,由数据库厂商实现数据库连接池

    • 获取连接:Connection conn = ds.getConnection()
    • 归还连接:conn.close() ,归还给连接池

  2. 常见数据连接池实现:

    • C3P0:
    • Druid:阿里巴巴提供

C3P0连接池技术:

  1. 导入jar包

    • 导入c3p0-0.9.5.2.jar
    • 导入c3p0的依赖包mchange-commons-java-0.2.12.jar

  2. 定义配置文件

    • 直接将配置文件c3p0-config.xml放在src目录下。
    • 定义一下数据库等

  3. 创建数据库连接池对象DataSource ds = new ComboPooledDataSource();
  4. 获取连接:Connection conn = ds.getConnection();

Druid连接池:

连接池使用:

  1. 导入jar包druid-1.0.9.jar

  2. 导入并定义配置文件

    • 任意位置导入druid.properties

  3. 获取连接池对象:通过工厂类获取

  4. 获取连接对象

    // 加载配置文件

    InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");

    Properties pro = new Properties();

    pro.load(is);

    // 获取连接池对象

    DataSource ds = DruidDataSourceFactory.createDataSource(pro);

    // 获取连接对象

    Connection conn = ds.getConnection();

工具类:

  1. 定义一个类JDBCUtils
  2. 提供静态代码块加载配置文件,初始化连接池对象
  3. 提供方法:

    • 获取连接池的方法
    • 获取连接方法
    • 释放资源

例子,工具类代码:

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;

import java.io.IOException;

import java.sql.*;

import java.util.Properties;

public class JDBCUtils {

private static DataSource ds;

static {

Properties pro = new Properties();

try {

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(Statement stmt, Connection conn) {

if (stmt != null) {

try {

stmt.close();

} catch (SQLException throwables) {

throwables.printStackTrace();

}

}

if (conn != null) {

try {

conn.close();

} catch (SQLException throwables) {

throwables.printStackTrace();

}

}

}

public static void close(ResultSet rs, Statement stmt, Connection conn) {

if (rs != null) {

try {

rs.close();

} catch (SQLException throwables) {

throwables.printStackTrace();

}

}

close(stmt, conn);

}

public static DataSource getDataSource() {

return ds;

}

}

工具类测试代码

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.SQLException;

public class DruidDemo2 {

public static void main(String[] args) {

Connection conn = null;

PreparedStatement pstmt = null;

try {

conn = JDBCUtils.getConnection();

String sql = "insert into stu values(?, ?, ?, ?)";

pstmt = conn.prepareStatement(sql);

pstmt.setInt(1, 5);

pstmt.setString(2, "测试");

pstmt.setInt(3, 100);

pstmt.setInt(4, 100);

int count = pstmt.executeUpdate();

System.out.println(count);

} catch (SQLException throwables) {

throwables.printStackTrace();

} finally {

JDBCUtils.close(pstmt, conn);

}

}

}

JDBC Template

JDBC工具类已经很好用了,但是创建连接对象、创建执行对象、执行sql语句等还是很复杂。

Spring框架对JDBC进行简单封装,提供了JDBC Template对象,简化了JDBC开发,只需要关注执行sql和结果。

  1. 导入JdbcTemplate的jar包(5个)

  2. 创建JdbcTemplate对象(依赖于数据源DataSource)

    • JdbcTemplate template= new JdbcTemplate(ds);

  3. 调用JdbcTemplate的方法完成增删改查

    • update(): 增删改

    • queryForMap(): 查询一条记录

      String sql = "select * from emp where id=?";

      Map<String, Object> map = temp.queryForMap(sql, 1);

    • queryForList(): 封装为List对象

      String sql = "select * from emp";

      List<Map<String, Object>> list = temp.queryForList(sql);

      for (Map<String, Object> map : list) {

      System.out.println(map);

      }

    • query(): 封装为JavaBean对象

      String sql = "select * from emp";

      List<Emp> list = temp.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));

      for (Emp emp : list) {

      System.out.println(emp);

      }

    • queryForObject(): 封装为基本类型对象,用于聚合函数

      String sql = "select count(*) from emp";

      Long total = temp.queryForObject(sql, Long.class);

      System.out.println(total);

一个简单的例子:(连接池等都是template完成,不需要自己写)

JdbcTemplate template= new JdbcTemplate(JDBCUtils.getDataSource());

String sql = "update stu set age=18 where id=?";

int count = template.update(sql, 5);

System.out.println(count);

03JDBC

原文:https://www.cnblogs.com/mingriyingying/p/13439277.html

以上是 03JDBC[数据库教程] 的全部内容, 来源链接: utcz.com/z/535094.html

回到顶部