# JDBC

# 创建连接

# 直接的方式

  //链接url(不同的数据库版本连接方式不相同)
  String url ="";
  //用户名
  String user ="";
  //密码
  String password ="";

  try(
    Connection c = DriverManager.getConnection(url,user,password);
    Statement s = c.createStatement();
  ){
     //使用sql语句
  }catch(SQLException e){
    e.printStackTrace();
  }

# 封装成类的方式

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.DriverManager;

//连接数据库类
public class DBUtil {
    static String ip = "127.0.0.1";
    static int port = 3306;
    static String database = "数据库名称";
    static String encoding = "UTC";
    static String loginName = "用户名";
    static String password = "密码";

    public static Connection getConnection() throws SQLException{
        String url = String.format(
                "jdbc:mysql://%s:%d/%s?useSSL=FALSE&serverTimezone=%s",ip,port,database,encoding);  //这是一种 方便修改 这是8.0.12的连接方式
        //String url = ""; //这种用起来不方便修改
        return DriverManager.getConnection(url,loginName,password);
    }

}

# 预编译的方式使用 sql 语句

  /*

  + 使用预编译的方式 要提前准备号sql语句
  + 使用try-with-resource的方式 省去手动关闭连接
  + 以插入为例

  */
  String sql = "insert into 表名(字段1,字段2,字段3) values(?,?,?)";
  try(
    //这里连接使用封装成类的方式
    Connection c = BDUtil.getConnection();
     PreparedStatement ps = c.prepareStatement(sql);
  ){
    /*

    - 设置要插入的值 注意 这里的参数从1开始 不是从0开始
    - setXXXX(位置,值);  XXXX为你要插入的值对应的类型

    */
    //举个例子
      ps.setString(1, "字符串");
      ps.setFloat(2, 313.0f);
      ps.setInt(3, 50);
      //开始插入
      ps.execute();
  }catch(SQLException e){
    e.printStackTrace();
  }

# 执行 sql 语句(execute 与 executeUpdate 的区别)

# 相同点

都可以进行 增 删 改

  //这里演示的是不使用预编译的方式执行sql语句
  Statement s = c.createStatement();
  //创建sql语句
  String sqlInsert = "insert into Hero values (null,'盖伦',616,100)";
  String sqlDelete = "delete from Hero where id = 100";
  String sqlUpdate = "update Hero set hp = 300 where id = 100";
  // 相同点:都可以执行增加,删除,修改
  s.execute(sqlInsert);
  s.execute(sqlDelete);
  s.execute(sqlUpdate);
  s.executeUpdate(sqlInsert);
  s.executeUpdate(sqlDelete);
  s.executeUpdate(sqlUpdate);

# 不同点

  1. execute()可以执行查询语句
    然后通过 getResultSet()把结果集取出来
    executeUpdate()不能执行查询语句.

  2. execute()返回 boolean 类型,true 表示执行的是查询语句,false 表示执行的是 insert, delete, update 等等
    executeUpdate()返回的是 int,表示有多少条数据受到了影响

  //可以使用executeQuery()语句来查询
  Statement s = c.createStatement()
  String sql = "select * from hero";
  // 执行查询语句,并把结果集返回给ResultSet
  ResultSet rs = s.executeQuery(sql);

# jdbc 的特殊操作

  • 获取自动 ID
  //Statement.RETURN_GENERATED_KEYS参数是为了用于获取自增长id
  PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
  ResultSet rs = ps.getGeneratedKeys(); //获取结果集
  if(rs.next()){
    int id = rs.getInt(1);
  }
  • 获取表的元数据
  /*

  + 查看数据库层面的元数据
  + 数据库服务器版本
  + 驱动版本
  + 都有哪些数据库等等

  */
  DatabaseMetaData dbmd = c.getMetaData();
  // 获取数据库服务器产品名称
  dbmd.getDatabaseProductName()
  // 获取数据库服务器产品版本号
  dbmd.getDatabaseProductVersion()
  // 获取数据库服务器用作类别和表名之间的分隔符 如test.user
  dbmd.getCatalogSeparator()
  // 获取驱动版本
  dbmd.getDriverVersion()
  // 获取数据库名称
  ResultSet rs = dbmd.getCatalogs();
  while (rs.next()) {
    System.out.println("数据库名称:\t"+rs.getString(1));
  }

# 关于 jdbc 事务的介绍

  1. 前提: 表的类型必须是 INNODB 类型的

  2. 为什么要使用事务: 当使用数据库进行多个操作时 如果某个操作失败 而其他操作成功 可能会引起数据库的数据错误,尤其是某个操作之间的联系非常紧密时,这是非常严重的.所以这时候就要使用 事务

  3. 什么是事务: 在进行多个操作时,如果这些操作都处于一个事务中,那么这些操作要么都成功,要么都失败.

  4. 怎么使用事务:

    连接数据库成功后,关闭自动提交,改为手动提交.代码如下:

try (
      Connection c = BDUtil.getConnection();
      Statement s = c.createStatement();
    ) {
      // 有事务的前提下
      // 在事务中的多个操作,要么都成功,要么都失败
      //关闭自动提交
      c.setAutoCommit(false);
      //修改数据 比如血量加1
      String sql1 = "update 表名 set hp = hp +1 where id = 22";
      s.execute(sql1);
      // 在减1
      // 不小心写错写成了 updata(而非update)
      String sql2 = "updata hero set hp = hp -1 where id = 22";
      s.execute(sql2);
      // 手动提交
      c.commit();
      //因为sql2语句错误,提交失败;所以sql1语句也没有成功提交,这就是使用事务的好处
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
}

# ORM 与 DAO

# ORM

  1. 持久化

持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML 数据文件中等等。

  1. 持久层:

持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联

  1. ORM

即 Object-Relationl Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的 SQL 语句打交道,只要像平时操作对象一样操作它就可以了。

# DAO

DAO 模式

DAO (DataAccessobjects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。通俗来讲,就是将数据库操作都封装起来。

模式

在面向对象设计过程中,有一些"套路”用于解决特定问题称为模式

优点

  1. 隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用 DAO 方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了藕合性,提高了可复用性。
  2. 隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加 DAO 接口的新实现类即可,原有 MySQ 实现不用修改。这符合 "开-闭" 原则。该原则降低了代码的藕合性,提高了代码扩展性和系统的可移植性。

组成

  1. DAO 接口: 把对数据库的所有操作定义成抽象方法,可以提供多种实现
  2. DAO 实现类: 针对不同数据库给出 DAO 接口定义方法的具体实现
  3. 实体类:用于存放与传输对象数据
  4. 数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改
最后更新: 2022/9/12 16:01:28