草庐IT

03-JDBC

OnlyOnYourself-lzw 2023-03-28 原文

1、JDBC简介

1.1、客户端操作MySQL数据库的方式

  • 使用DOS命令行方式
  • 使用第三方客户端来访问MySQL:SQLyog、Navicat、....
  • 通过程序来访问MySQL数据库
    • 而通过Java来访问MySQL数据库,就是JDBC的概念

1.2、JDBC的概念

  • 什么是JDBC
    • Java Data Base Connectivity:Java数据库连接
  • JDBC作用
    • 通过JDBC可以让Java程序操作数据库
  • JDBC本质
    • 官方(SUN)公司定义的一套操作所有关系型数据库的规则,即接口(API)
    • 各个数据库厂商去实现这套接口,提供数据库驱动jar包
    • 我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
  • JDBC的好处
    • 只需要会调用JDBC接口中的方法即可,使用简单
    • 使用同一套Java代码,进行少量的修改就可以访问其他JDBC支持的数据库

2、JDBC API详解

2.1、JDBC四个核心对象

  • JDBC的使用步骤
    • 注册驱动
    • 获取数据库连接
    • 获取SQL语句对象
    • 执行SQL语句并返回结果
    • 处理结果
    • 释放资源
  • JDBC四个核心对象
  • JDBC交互图

2.2、JDBC注册驱动

  • Java程序需要通过数据库驱动才能连接到数据库,因此需要注册驱动

    • 在注册驱动之前需要先导入驱动的Jar包
  • JDBC注册驱动

    • java.sql.DriverManager类用于注册驱动。提供如下方法注册驱动

      • static void registerDriver(Driver driver)	// 向DriverManager 注册给定驱动程序
        
  • 示例代码

    • public class Demo01 {
        public static void main(String[] args) throws Exception {
          	// 注册驱动
          	DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        }
      }
      
      
  • 提示

    • MySQL 5 之后的驱动包,可以省略注册驱动的步骤
    • 自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类

2.3、获取Connection连接

  • Connection 介绍

    • 表示Java程序与数据库之间的连接,只有拿到Connection才能操作数据库

    • DriverManager类中的静态方法 描述
      static Connection getConnection(String url, String user, String password) 连接到给定数据库URL,并返回连接
    • 参数说明

      • String url:连接数据库的URL,用于说明数据库的位置
      • String user:数据库的账号
      • String password:数据库的密码
    • 连接数据库的URL地址格式

      • 协议名:子协议://服务器名或IP地址:端口号/数据库名
    • MySQL写法

      • jdbc:mysql://localhost:3306/day03
    • 如果是本地服务器,端口号是默认的3306,则可以简写

      • jdbc:mysql:///day03

2.4、获取Statement对象

  • 在java.sql.Connection接口中有如下方法获取到Statement对象

    • Statement createStatement()	// 创建一个Statement对象来将SQL语句发送到数据库
      
  • 代码案例

    • // 1.注册驱动
      
      // 2.获取连接
      Connection conn = DriverManager.getConnection("jdbc:mysql:///day03", "root", "123");
      
      // 3.获取Statement
      Statement stmt = conn.createStatement();
      

3、JDBC实现对单表数据增加、删除、修改

  • 我们要对数据库进行增、删、改、查,需要使用Statement对象来执行SQL语句

  • Statement的API介绍

    • ResultSet executeQuery(String sql)
      // 用于执行查询语句; 返回查询到的结果集
      
      int executeUpdate(String sql)
      // 用于执行除查询外的SQL; 返回影响的行数
      
      

4、JDBC获取数据(Result类)

4.1、ResultSet的原理

  • ResultSet用于保存执行查询SQL语句的结果。我们不能一次性去除所有的数据,需要一行一行的去除

  • ResultSet内部有一个指针,记录获取到哪行数据

    • 获取查询结果

    • boolean   next():
        /*
        (1) 将光标从当前位置向前移动一行 
        (2)判断当前行是否为有效行
      返回值:
        true:有效行,当前行有数据
        false:无效行,当前行没有数据
      */
      
      
    • 应用案例

      • while (rs.next()) {
                rs.getXxx(字段名); // 取出数据
        }
        

4.2、ResultSet获取数据的API

  • ResultSet获取数据的API是有规律的get后面加数据类型。我们统称getXXX()

  • 方法名 说明
    boolean getBoolean(String columnLabel) 获取boolean值
    byte getByte(String columnLabel) 获取byte值
    double getDouble(String columnLabel) 获取double值
    int getInt(String columnLabel) 获取int值
    long getLong(String columnLabel) 获取long值
    String getString(String columnLabel) 获取String值

4.3、ResultSet的getXXX方法与MySQL中数据类型的对应

  • 注意
    • 这只是一个建议,不按这个表的对应关系也可以,只要数据类型可以自动转换。如:int类型,使用String去取,也是可以的。但如果是String类型,使用int去取就不行

5、JDBC事务处理

  • JDBC操作银行转账的事务

    • Connection接口中与事务有关的方法
  • 使用步骤

    • 1.注册驱动
    • 2.获取连接
    • 3.开启事务
    • 4.获取Statement对象
    • 5.执行SQL语句
    • 6.提交或者回滚事务
    • 7.关闭资源
  • demo

    • package _02MySQL.Day03_JDBC.demo05_事务处理_重点;
      
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.SQLException;
      import java.sql.Statement;
      
      /**
       * JDBC事务处理
       *
       * 数据准备:
       *      CREATE TABLE tb_account (
       * 	        id INT PRIMARY KEY AUTO_INCREMENT,
       * 	        NAME VARCHAR(10),
       * 	        balance DOUBLE
       *      );
       *
       *-- 添加数据
       * INSERT INTO tb_account (NAME, balance) VALUES ('张三', 1000), ('李四', 1000);
       */
      public class Demo05 {
          public static void main(String[] args) throws SQLException{
              // 1. 注册驱动
              Connection connection = null;
              try {
                  // 2. 获取数据库连接
                  connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "123");
      
                  // 3. 开启事务
                  connection.setAutoCommit(false);    // 关闭自动提交
      
                  // 4. 获取Statement对象
                  Statement statement = connection.createStatement();
      
                  // 5. 执行SQL
                  String sql1 = "update tb_account set balance = balance - 500 where name = '张三'";
                  String sql2 = "update tb_account set balance = balance + 500 where name = '李四'";
      
                  statement.executeUpdate(sql1);
                  statement.executeUpdate(sql2);
      
                  // 模拟失败
                  // ...
      
                  // 6. 提交事务
                  System.out.println("提交事务!");
                  connection.commit();
              } catch (Exception e) {
                  // 6. 有异常,事务回滚
                  if (connection != null) {
                      connection.rollback();
                  }
              }finally {
                  // 7. 关闭资源
                  if (connection != null) {
                      connection.close();
                  }
              }
          }
      }
      
      

6、JDBC实现用户登录

  • 模拟用户输出账号和密码登录网站

  • 案例分析

    • 1.使用数据库中保存用户的账号和密码
    • 2.让用户输入账号和密码
    • 3.使用SQL根据用户的账号和密码去数据库查询数据
    • 4.如果查询到数据,说明登录成功
    • 5.如果查询不到数据,说明登录失败
  • Demo

    • package com.itheima.demo06_JDBC实现用户登录;
      
      import java.sql.*;
      import java.util.Scanner;
      
      /**
       * JDBC实现用户登录案例
       */
      public class Demo06 {
      
          public static void main(String[] args) throws SQLException {
              Scanner scanner = new Scanner(System.in);
              String userName = null;
              String password = null;
      
              // 1. 接收用户名
              while (true) {
                  System.out.println("请输入用户名:");
                  String line = scanner.nextLine();
                  if ("".equals(line)) {
                      continue;
                  }
                  userName = line;
                  break;
              }
      
              // 2.接收用户密码
              while (true) {
                  System.out.println("请输入密码:");
                  String line = scanner.nextLine();
                  if ("".equals(line)) {
                      continue;
                  }
                  password = line;
                  break;
              }
      
              // 3.根据用户名和密码,查询用户
              String sql = "SELECT * FROM USER WHERE NAME = '" + userName + "' AND PASSWORD = '" + password + "';";
              String jdbcUrl = "jdbc:mysql://localhost:3306/day03";
              Connection conn = DriverManager.getConnection(jdbcUrl, "root", "root");
              Statement stmt = conn.createStatement();
              ResultSet rs = stmt.executeQuery(sql);
      
              // 4.根据查询结果,判断是否登录成功
              // 4.1 如果查询到数据,显示登录成功
              if (rs.next()) {
                  System.out.println("登录成功!欢迎您," + userName);
              } else {
                  // 4.2 如果查询不到数据,显示登录失败
                  System.out.println("登录失败!用户名或密码错误...");
              }
      
          }
      }
      

7、SQL注入攻击

7.1、SQL注入问题

  • 在我们前面JDBC实现登录案例中,当我们输入以下密码的时候,可以发现账号和密码都不对竟然登录成功了!

    • 请输入用户名:
      hehe
      请输入密码:
      a'or'1'='1
      
  • 字符串拼接,把输入的字符串全都将其视为sql语句,导致statement对象查询直接为真,条件不起作用!

  • 问题分析

    • "SELECT * FROM user WHERE name='" + name + "' AND password='" + password + "';";
      
      // 将用户输入的账号密码拼接后
      "SELECT * FROM user WHERE name='hehe' AND password='a'or'1'='1';"
      
  • SQL注入攻击的原理

    • 按照正常道理来说,在密码处输入的所有内容,都应该认为是密码的组成
    • 但是现在Statement对象在执行sql语句时,将密码的一部分内容当作查询条件来执行了。

7.2、解决SQL注入

  • PreparedStatement预编译执行者对象

    • 预编译:SQL语句子在执行前就已经编译好了,执行速度更快
    • 安全性更高:没有字符串拼接的SQL语句,所以避免SQL注入的问题
    • 代码的可读性更好,是因为没有字符串拼接
  • PreparedStatement使用

    • SQL语句中的参数使用?作为参为辐
    • 给?占位符赋值
  • 设置参数

    • setXxx(参数1,参数2):Xxx代表数据类型
    • 参数1:第几个?(编号从1开始)
    • 参数2:?的实际参数
  • 执行SQL语句

    • int executeUpdate()
      • 执行insert、update、delete语句
    • ResultSet executeQuery()
      • 执行select语句
  • demo

    • String sql = "SELECT * FROM USER WHERE NAME=? AND PASSWORD=?;";
      
      PreparedStatement pstmt = conn.prepareStatement(sql);
      pstmt.setString(1, “zhangsan”);
      pstmt.setString(2, “6666”);
      

7.3、使用PreparedStatement改写登录案例

  • package _02MySQL.Day03_JDBC.demo08_PreparedStatement改写登录案例;
    
    import java.sql.*;
    import java.util.Scanner;
    
    /**
     * PreparedStatement改写登录案例
     */
    public class Demo08 {
    
        public static void main(String[] args) throws SQLException {
            // 1. 注册驱动
            // 2. 获取连接
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "123");
    
            // 3. 获取PreparedStatement对象
            String sql = "select * from day03.user where phoneNumber = ? and password = ?";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            // 准备参数
            Scanner scanner = new Scanner(System.in);
            String phoneNumber = null;
            String password = null;
            do {
                System.out.print("请输入账号:");
                phoneNumber = scanner.nextLine();
            } while ("".equals(phoneNumber));
    
            do {
                System.out.print("请输入密码: ");
                password = scanner.nextLine();
            } while ("".equals(password));
    
            // 4. 执行SQL语句
            preparedStatement.setString(1, phoneNumber);
            preparedStatement.setString(2, password);
            ResultSet resultSet = preparedStatement.executeQuery();
    
            // 5. 处理结果
            if (resultSet.next()) {
                System.out.println("欢迎您,尊敬的" + phoneNumber + "用户");
            }else {
                System.out.println("账号或密码错误!");
            }
            // 6. 释放资源
            connection.close();
        }
    }
    
    

8、JDBC连接池

8.1、常规数据库连接的问题

  • JDBC访问数据库的步骤
    • 创建数据库连接
    • 运行SQL语句
    • 关闭连接
  • 上述动作每次数据库访问都会执行这样的重复动作
  • 而每次创建数据库连接的问题
    • 获取数据库连接需要消耗比较多的资源,而每次操作都要重新获取新的连接对象,执行一次操作就把连接关闭,而数据库创建连接通常需要消耗相对较多的资源。这样数据库连接对象的使用率低

8.2、数据库连接池简介

  • 现实生活中每日三餐。我们并不会吃一餐饭就将碗丢掉,而是吃完饭后将碗放到碗柜中,下一餐接着使用。目的是重复利用碗。数据库连接也可以重复使用,可以减少数据库连接的创建次数。提高数据库连接对象的使用率
  • 连接池的概念
    • 连接池就是一个容器,连接池中保存了一些数据库连接,这些连接是可以重复使用的
  • 连接池的原理
    • 1.启动连接池,连接池就会初始化一些连接
    • 2.当用户需要使用数据库连接,直接从连接池中取出
    • 3.当用户使用完连接,会将连接重新放回连接池中
  • 连接池的好处
    • 连接池中保存一些连接,这些连接可以重复使用,降低数据资源的消耗

8.3、常用连接池的介绍

  • javax.sql.DataSource表示数据库连接池,也是JDK中提供的一个接口,没有具体的实现,它的实现由连接池的厂商去实现。我们只需要学习这个工具如何使用

    • public interface DataSource{
        	Connection getConnection();
        ...
      }
      
  • 常用的连接池实现组件有以下这些

    • 阿里巴巴-德鲁伊Druid连接池
      • Druid是阿里巴巴开源平台上的一个项目
    • C3P0是一个开源的连接池,目前使用它的开源项目有Hibernate,Spring等
    • DBCP(DataBase Connection Pool)数据库连接池,是Tomcat使用的连接池组件

8.3、Druid连接池简介

  • Druid是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过了其他数据连接池,同时加入了日志监控,可以很好的监控数据库连接池和SQL的执行情况。

    • Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产大环境部署的严苛考验
  • Druid常用的配置参数

    • 方法名 说明
      initialSize 刚启动连接池时,连接池中包含连接的数量
      maxActive 连接池中最多可以放多少个连接
      maxWait 获取连接时最大等待时间,单位毫秒
  • com.alibaba.druid.pool.DruidDataSourceFactory类创建连接池的方法

    • public static DataSource createDataSource(Properties properties) // 创建一个连接池,连接池的参数使用properties中的数据
      
  • 我们可以看到Druid连接池在创建的时候需要一个Properties对象来设置参数,所以我们使用properties文件来保存对应的参数。Druid连接池的配置文件名称随便,放到src目录下面方便加载

    • druid.properties文件内容

    • driverClassName=com.mysql.jdbc.Driver
      url=jdbc:mysql://127.0.0.1:3306/day17
      username=root
      password=root
      initialSize=5
      maxActive=10
      maxWait=3000
      

8.4、Druid连接池使用步骤

  • 1.导入druid-1.0.0.jar的jar包
  • 2.赋值druid.properties文件到src下,并设置对应参数
  • 3.加载properties文件的内容到Properties对象中
  • 4.创建Druid连接池,使用配置文件中的参数
  • 5.从Druid连接池中取出连接
  • 6.执行SQL语句
  • 7.关闭资源

9、JDBC案例(在Java程序中实现对数据库的增删改查)

  • Demo类

    • package _02MySQL.Day03_JDBC.demo10_JDBC增删改查练习;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * JDBC增删改查练习---- 完成商品品牌数据的增删改查操作
       * 查询数据:查询所有数据
       * 添加数据:添加品牌
       * 修改数据:根据id修改
       * 删除数据:根据id删除
       */
      public class Demo10 {
          /*
              数据准备:
                  创建一个商品品牌的数据库表 tb_brand
                  创建一个Brand实体类
           */
          public static void main(String[] args) throws Exception {
              // 1. 增加数据
      //        addBrand();
      
              // 2. 删除数据
              deleteBrand();
      
              // 3. 修改数据
              editBrand();
      
              // 4. 查询数据
              seekBrand();
          }
      
          public static void addBrand() throws SQLException {
              // 获取连接
              Connection connection = DataSourceUtils.getConnection();
              // 获取preparedStatement对象
              String sql = "insert into day03.tb_brand (brand, description, headquarters) values" +
                      "(?, ?, ?)";
              PreparedStatement preparedStatement = connection.prepareStatement(sql);
              preparedStatement.setString(1, "格力空调");
              preparedStatement.setString(2, "美好生活格力造");
              preparedStatement.setString(3, "China");
              // 得到statement对象返回的影响行数
              int i = preparedStatement.executeUpdate();
              System.out.println(i);
              // 将连接返回给连接池
              connection.close();
          }
      
          // 根据id删除数据
          public static void deleteBrand() throws SQLException {
              // 获取连接
              Connection connection = DataSourceUtils.getConnection();
              // 编写删除数据的SQL, 并获取preparedStatement对象
              String sql = "delete from day03.tb_brand where id = ?";
              PreparedStatement preparedStatement = connection.prepareStatement(sql);
              preparedStatement.setInt(1, 5);
      
              // 执行SQL, 返回影响的行数
              int i = preparedStatement.executeUpdate();
              System.out.println(i);
      
              // 将连接返回给连接池
              connection.close();
          }
      
          // 根据id编辑数据
          public static void editBrand() throws SQLException {
              // 获取连接
              Connection connection = DataSourceUtils.getConnection();
              // 编写sql,并获取preparedStatement对象
              String sql = "update day03.tb_brand set brand = ?, description = ?, headquarters = ? where id = ?";
              PreparedStatement preparedStatement = connection.prepareStatement(sql);
              // 补全SQL
              preparedStatement.setString(1, "华强北");
              preparedStatement.setString(2, "天上地下我华强北说第二,谁敢说第一");
              preparedStatement.setString(3, "中国深圳");
              preparedStatement.setInt(4, 1);
      
              // 执行SQL语句, 返回影响的行数
              int i = preparedStatement.executeUpdate();
              System.out.println(i);
              // 关闭连接,将连接返回给连接池
              connection.close();
          }
      
          public static void seekBrand() throws SQLException {
              // 获取连接
              Connection connection = DataSourceUtils.getConnection();
      
              // 获取Statement对象
              String sql = "select * from day03.tb_brand";
              PreparedStatement preparedStatement = connection.prepareStatement(sql);
      
              // 得到数据集合
              ResultSet resultSet = preparedStatement.executeQuery();
      
              // 处理数据
              List<Brand> brandList = new ArrayList<>();  // 存储数据
              while (resultSet.next()) {
                  int id = resultSet.getInt("id");
                  String brand = resultSet.getString("brand");
                  String description = resultSet.getString("description");
                  String headquarters = resultSet.getString("headquarters");
                  brandList.add(new Brand(id, brand, description, headquarters));
              }
      
              brandList.forEach((brand) -> System.out.println("data = " + brand));
              // 将连接返回给连接池
              connection.close();
      
          }
      }
      
  • DataSourceUtils工具类(获取Datasource)

    • package _02MySQL.Day03_JDBC.demo10_JDBC增删改查练习;
      
      import com.alibaba.druid.pool.DruidDataSourceFactory;
      
      import javax.sql.DataSource;
      import java.io.InputStream;
      import java.sql.Connection;
      import java.sql.SQLException;
      import java.util.Properties;
      
      /**
       * 工具类
       *      -- 创建Druid连接池
       */
      public class DataSourceUtils {
          private static DataSource dataSource;
      
          static {    // 利用静态代码块加载创建连接池的操作
              try {
                  // 1. 载入配置文件
                  // 获取properties配置文件
                  InputStream inputStream = DataSourceUtils.class.getResourceAsStream("brand.properties");
                  Properties properties = new Properties();
                  properties.load(inputStream);
      
                  // 2. 创建连接
                  dataSource = DruidDataSourceFactory.createDataSource(properties);
              }catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          public static Connection getConnection() throws SQLException {
              return dataSource.getConnection();
          }
      }
      
  • Brand实体类

    • package _02MySQL.Day03_JDBC.demo10_JDBC增删改查练习;
      
      public class Brand {
          private int id;
          private String brand;
          private String description;
          private String headquarters;
      
          public Brand(int id, String brand, String description, String headquarters) {
              this.id = id;
              this.brand = brand;
              this.description = description;
              this.headquarters = headquarters;
          }
      
          public int getId() {
              return id;
          }
      
          public void setId(int id) {
              this.id = id;
          }
      
          public String getBrand() {
              return brand;
          }
      
          public void setBrand(String brand) {
              this.brand = brand;
          }
      
          public String getDescription() {
              return description;
          }
      
          public void setDescription(String description) {
              this.description = description;
          }
      
          public String getHeadquarters() {
              return headquarters;
          }
      
          public void setHeadquarters(String headquarters) {
              this.headquarters = headquarters;
          }
      
          @Override
          public String toString() {
              return "Brand{" +
                      "id=" + id +
                      ", brand='" + brand + '\'' +
                      ", description='" + description + '\'' +
                      ", headquarters='" + headquarters + '\'' +
                      '}';
          }
      }
      
  • brand.properties配置文件

    • driverClassName=com.mysql.cj.jdbc.Driver
      url=jdbc:mysql://127.0.0.1:3306/day03
      username=root
      password=123
      initialSize=5
      maxActive=10
      maxWait=3000
      

有关03-JDBC的更多相关文章

  1. 【JAVAEE】JAVA数据库连接(JDBC) - 2

    1.什么是JDBC?Java数据库连接,(JavaDatabaseConnectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是SunMicrosystems的商标。我们通常说的JDBC是面向关系型数据库的。简而言之,JDBC就是JDK提供的关于数据库操作的一套接口规范,不同数据库厂商来负责实现这个接口,完成指定的操作。用程序和数据建立连接,分为三步骤:1.连接数据库2.执行SQL语句3.把查询到的结果集转换成JAVA对象2.对于MySQL的JDBC编程的前期准备工作知识拓展:JAR文件(Java归

  2. ruby-on-rails - Rails 未定义方法 `strftime' 为 "2013-03-06":String - 2

    我遇到了错误“2013-03-06”的未定义方法`strftime':String当尝试使用strftime从字符串2013-03-06正常显示日期(2013年6月3日或类似日期)时。在我的index.html.erb中执行此操作的行看起来像这样我只是在学习Rails,所以我确信这只是一个愚蠢的初学者错误,我们将不胜感激。谢谢 最佳答案 当strftime是时间/日期类的方法时,您的截止日期看起来是一个字符串。你可以试试这个:Date.parse(task.duedate).strftime("%B%e,%Y")

  3. MySQL的JDBC 编程 - 2

    目录1.数据库编程:JDBC2.JDBC工作原理3.JDBC使用3.1驱动包的下载与导入3.2JDBC使用步骤(插入)4.JDBC修改删除查询1.将数据库驱动包,添加到项目依赖中创建目录,拷贝jar包,然后addaslibrary2.创建数据源DataSourse:数据源,描述了数据库服务器在哪里3.和数据库建立连接使用JDBC里的Connection将代码和数据库服务器进行连接一个程序中,通常有一个数据源对象,可以有多个Connection对象4.构造sql语句PreparedStatement:表示一个预处理过的SQL语句对象5.执行sql语句(1)executeUpdate对应插入到删除

  4. go - 如何解析 "2019-09-19 04:03:01.770080087 +0000 UTC"时间戳 - 2

    这个问题在这里已经有了答案:ParsingRFC-3339/ISO-8601date-timestringinGo(8个答案)关闭3年前。我将如何解析这个时间戳?“2019-09-1904:03:01.770080087+0000UTC”我尝试了以下方法:formatExample:=obj.CreatedOn//obj.CreatedOn="2019-09-1904:03:01.770080087+0000UTC"time,err:=time.Parse(formatExample,obj.CreatedOn)check(err)fmt.Println(time)但我得到的输出是:0

  5. oracle - Golang用的是JDBC还是ODBC或者什么连接类型 - 2

    goversiongo1.8.1windows/amd64我正在导入"github.com/mattn/go-oci8""database/sql"用于连接到我的oracle数据库。在这里,当我在连接字符串中提供数据库用户名、密码、端口和表名时funcopenAndConnectToDb(sbconfigConnectorConfig)*sql.DB{logger:=sbgoclient.Loglogger.Println("Openthedatabase")//oraprop:=LoadConfig("oraproperties.yml")fmt.Println("Loadconfi

  6. openEuler RISC-V 23.03 创新版本亮相:全面提升硬件兼容性和桌面体验 - 2

    近日,openEulerRISC-V23.03创新版本正式发布。openEulerRISC-VSIG作为openEuler系统在RISC-V架构上的维护组织,主要致力于openEuler在RISC-V软硬件方面的适配,一直跟随openEuler版本节奏提供openEuler的RISC-V镜像版本。本次更新带来更好的硬件支持,更多的软件适配,包括VisionFive2,SG2042等多款新开发板的默认支持、UKUI,GNOME等多个桌面环境的新增适配、容器及其工具的适配,另外,还默认新增JIT支持以及针对性优化。镜像下载链接https://mirror.iscas.ac.cn/openeuler

  7. xml - 将 JDBC url 从 Maven 传递到 hibernate.cfg.xml - 2

    我有一个hibernate.cfg.xml,其中配置了JDBCUrl:jdbc:mysql://${server.hostname}:3306/dsm?zeroDateTimeBehavior=convertToNull&jdbcCompliantTruncation=true&autoReconnect=true这些&是必需的(而不仅仅是&)以避免异常:对实体“jdbcCompliantTruncation”的引用必须以“;”结尾分隔符。为了能够通过Maven选择不同的目标数据库,我想将其更改为:${jdbc.url}其中${jdbc.url}是Maven中定义的属性

  8. xml - 十六进制值 0X03 是无效字符 - 2

    这是一个网页的来源Da brow#aG�rnicza我需要浏览此页面并复制显示的文本之后,我将此文本粘贴到asp.netmvc应用程序的输入文本框中,以便在数据库中创建一条新记录。布局页面的元字符集是“utf-8”如果我在调试中转到VisualStudio2013,当执行Controller的创建操作时,我可以看到以下字符串此地址已存储到nvarchar(255)类型的列中,从sql管理工具中我看到与之前相同的文本:如果我将数据库列中的地址复制并粘贴到Notepad++,我可以看到之后我必须调用svc服务才能发送地址数据,但我从另一端收到了这个异常ERRORT

  9. java - Spring 3 applicationContext-security-JDBC.xml 有 bean :bean not bean? - 2

    有人可以告诉我在我的ApplicationContext中我必须使用beans:bean而不是bean的什么以及如何修复它。 最佳答案 说明。基本上,您在这里处理的是XML命名空间。Spring配置允许您使用来自不同命名空间的配置元素作为一种扩展基本beans命名空间配置的方式,具有方便的特定于域的配置,如上述案例中的安全配置。如果您的配置文件集中在这些扩展命名空间之一——再次,让我们以安全性为例——如果您将默认命名空间声明为扩展命名空间而不是标准beans命名空间。就是这样xmlns="http://www.springframe

  10. java - 从 JDBC 结果集中获取 XML 的最佳方式 - 2

    我正在寻找从JDBC结果集中获取XML文档的最佳方法。XML的结构不是很重要,但它应该相当快。为了清楚起见,我想要结果集中的数据和足够的元数据来识别数据(本质上是字段名称)。我目前正在使用MySQL、DB2、SQLServer,但解决方案需要与数据库无关(对于SQLServer中的XML不是一个可行的选择)。 最佳答案 通过使用WebRowSet,一次可以将整个ResultSet转换成XML。WebRowSet生成的XML非常清晰和简单,我不确定速度,因为它还取决于驱动程序实现。这里有一篇关于WebRowSetusingOracle

随机推荐