内容

  • JDBC `JDBC`简介
  • JDBC `JDBC`快速入门
  • JDBC API `JDBC API` 详解
  • 数据库连接池
  • JDBC `JDBC`案例

1. JDBC入门

1.1 概述

  • 概念

    JDBC:Java DataBase ConnectivityJava数据库连接

    JDBC就是使用Java语言操作关系型数据库的一套API

    Sun公司和数据库厂商共同制定的一套连接并操作数据库的统一规范(接口),由数据库厂商负责实现(驱动Jar包);我们使用的时候只需要导入数据库厂商已经实现好的jar包即可。

  • 好处

    因为各个数据库厂商都实现了同一套JDBC接口规范。

    1. 我们可以使用同一套Java代码操作不同的关系型数据库
    2. 访问数据库的Java代码不改变的前提下,替换不同的驱动Jar包可以轻松更换数据库
  • 我们要怎么做

    整体思路:基于JDBC定义的规则编码,不用考虑不同数据库之间的差异

    1. 导数对应据库驱动包。
    2. 基于JDBC定义的规则轻松编程。

1.2 quick start

  • 实现步骤

    1. 导入Jar
    2. 注册驱动
    3. 获取连接
    4. 获取执行者对象
    5. 执行SQL语句,并且接收结果
    6. 处理结果
    7. 释放资源
  • 演示代码

    package com.cy.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.Statement; /**
    * JDBC快速入门
    */
    public class JDBCDemo { public static void main(String[] args) throws Exception {
    //1. 注册驱动 建议写上去
    Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接
    //url jdbc:mysql:///maven == jdbc:mysql://127.0.0.1:3306/maven
    //jdbc:mysql://ip:数据库端口号/数据库名称?添加自定义参数
    String url = "jdbc:mysql://127.0.0.1:3306/maven";
    String username = "root";
    String password = "root";
    //Connection 数据库的连接对象
    Connection conn = DriverManager.getConnection(url, username, password);
    //3. 定义sql
    String sql = "update account set money = ? where id = ?";
    //4. 获取执行sql的对象 Statement
    //Statement stmt = conn.createStatement();
    PreparedStatement pps = conn.prepareStatement(sql); pps.setDouble(1,3000);
    pps.setInt(2,1); //5. 执行sql
    //int count = stmt.executeUpdate(sql);//受影响的行数 执行增删改
    int count = pps.executeUpdate(); //6. 处理结果 受影响的行数
    System.out.println(count);
    //7. 释放资源
    pps.close();
    conn.close();
    }
    }

2. jdbc常用API

2.1 DriverManager

功能1:注册驱动

  • 不需要手动调用DriverManagerAPI注册,而是保证com.mysql.jdbc.Driver被加载进内存即可。

查看com.mysql.jdbc.Driver类的源码

package com.mysql.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException; public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
} static {
try {
// 在静态代码块中完成了注册驱动的代码
// 我们只要保证Driver被加载进内存,下面的注册驱动的步骤就会自动完成。
/*
Class.forName("com.mysql.jdbc.Driver");
Driver.class //Driver的字节码对象
new Driver(); // 多一个driver对象
*/
/*
在MySQL5以上的版本,注册驱动不需要我们自己做了。
在mysql-connector-java-5.1.47.jar中META-INF下面services下面的
java.sql.Driver文件中,填写了com.mysql.jdbc.Driver全类名
该类的便会自动被加载进内存
*/
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}

功能2:获取连接对象

static Connection getConnection(url, username, password)

//3.获取连接
// 相当于之前使用mysql工具连接数据库
// 完整格式:jdbc:mysql://ip:数据库端口号/数据库名称?添加自定义参数
// jdbc:mysql://就是协议 相当于 http://
// url连本机 jdbc:mysql://localhost:3306/db2 简化写法jdbc:mysql:///db2
// 可选自定义参数:useSSL=false 不是用SSL加密并取消提示 Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");

2.2 Connection

就像打电话,一个Connection对象,就是一通电话。

所以连接又称会话,Session

功能1:获取执行者对象

该对象会执行SQL语句

  • 获取普通执行者对象:Statement createStatement();

  • 获取预编译执行者对象:PreparedStatement prepareStatement(String sql);

功能2:控制事务

Connection中定义了三个方法,用来控制事务。对应MySQL中的三种操作。

  • 开启:setAutoCommit(boolean autoCommit); 参数为false,则开启事务。

  • 提交:commit();

  • 回滚:rollback();

功能3:释放资源

  • close();

演示代码

package com.cy.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement; /**
* JDBC API 详解:Connection
*/
public class JDBCDemo3_Connection { public static void main(String[] args) throws Exception {
//1. 注册驱动 建议写上去
Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接,配置连接四要素
//jdbc:mysql://ip:数据库端口号/数据库名称?添加自定义参数
String url = "jdbc:mysql://127.0.0.1:3306/web22_day03_jdbc";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, username, password);
//3. 定义sql
String sql1 = "update account set money = money - 500 where id = 1";
String sql2 = "update account set money = money + 500 where id = 2";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
try {
// 开启事务
conn.setAutoCommit(false);
//5. 执行sql
int count1 = stmt.executeUpdate(sql1);//受影响的行数
//6. 处理结果
System.out.println(count1);
int i = 3/0;
//5. 执行sql
int count2 = stmt.executeUpdate(sql2);//受影响的行数
//6. 处理结果
System.out.println(count2); // 提交事务
conn.commit();
} catch (Exception throwables) {
// 回滚事务,手动开启事务之后,该操作可以省略。
// 没有没有提交,他也不会自动提交,就相当于回滚了。
// conn.rollback();
throwables.printStackTrace();
} //7. 释放资源
stmt.close();
conn.close();
}
}

2.3 Statement

执行者对象,执行SQL语句并返回SQL语句执行的结果/结果集。

  • 执行DML/DDL语句:修改(增删改)

    int executeUpdate(String sql);

    返回值int:返回影响的行数。

    参数sqlinsertupdatedelete语句。

    一般不会在Java代码中执行DDL语句,Java中主要完成对数据库中表记录的操作。

  • 执行DQL语句:查询

    ResultSet executeQuery(String sql);

    返回值ResultSet:封装查询的结果集。

    参数sqlselect语句。

  • 释放资源

    立即将执行者对象释放:void close();

  • 演示代码:演示增删改

    /**
    * statement执行dql,并获取结果集
    * JDBC API 详解:Statement
    */
    public class JDBCDemo4_Statement { /**
    * 执行DML语句
    * @throws Exception
    */
    @Test
    public void testDML() throws Exception {
    //1. 注册驱动
    //Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    String url = "jdbc:mysql:///maven?useSSL=false";
    String username = "root";
    String password = "root";
    Connection conn = DriverManager.getConnection(url, username, password);
    //3. 定义sql
    String sql = "update account set money = 4000 where id = 1";
    //4. 获取执行sql的对象 Statement
    Statement stmt = conn.createStatement();
    //5. 执行sql
    int count = stmt.executeUpdate(sql);//执行完DML语句,受影响的行数 //6. 处理结果
    if(count > 0){
    System.out.println("修改成功~");
    }else{
    System.out.println("修改失败~");
    }
    //7. 释放资源
    stmt.close();
    conn.close(); } /**
    * 执行DDL语句
    * @throws Exception
    */
    @Test
    public void testDDL() throws Exception {
    //1. 注册驱动
    //Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    String url = "jdbc:mysql:///db1?useSSL=false";
    String username = "root";
    String password = "1234";
    Connection conn = DriverManager.getConnection(url, username, password);
    //3. 定义sql
    String sql = "drop database db2";
    //4. 获取执行sql的对象 Statement
    Statement stmt = conn.createStatement();
    //5. 执行sql
    int count = stmt.executeUpdate(sql);//执行完DDL语句,可能是0
    //6. 处理结果
    //System.out.println(count);
    /* if(count > 0){
    System.out.println("修改成功~");
    }else{ System.out.println("修改失败~");
    }*/
    System.out.println(count); //7. 释放资源
    stmt.close();
    conn.close(); }
    }
  • 演示代码:查询及结果集处理

    public class JDBCDemo5_ResultSet {
    
        /**
    * 执行DQL
    *
    * @throws Exception
    */
    @Test
    public void testResultSet() throws Exception {
    //1. 注册驱动
    //Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    String url = "jdbc:mysql:///maven?useSSL=false";
    String username = "root";
    String password = "root";
    Connection conn = DriverManager.getConnection(url, username, password); //3. 定义sql
    String sql = "select * from account"; //4. 获取statement对象
    Statement stmt = conn.createStatement(); //5. 执行sql executeQuery
    ResultSet rs = stmt.executeQuery(sql); // 6.1 光标向下移动一行,并且判断当前行是否有数据
    while (rs.next()) { //移动到下一行
    //6.2 获取数据 getXxx() int id = rs.getInt("id");
    String name = rs.getString("name");
    double money = rs.getDouble("money"); System.out.println("id = " + id);
    System.out.println("name = " + name);
    System.out.println("money = " + money);
    } //7. 释放资源
    rs.close();
    stmt.close();
    conn.close();
    }
    }

2.4 查询并封装POJO对象案例

2.4.1 需求

查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中

2.4.2 核心步骤

  1. 使用上述操作完成查询,查询出结果集。
  2. 定义实体类Account
  3. 查询数据,封装到Account对象中
  4. Account对象存入ArrayList集合中

2.4.3 演示代码

package com.cy.pojo;

public class Account {

    private int id;
private String name;
private double money; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getMoney() {
return money;
} public void setMoney(double money) {
this.money = money;
} @Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
/**
* 实现需求:查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
*/
public class JDBCDemo5_ResultSet { /**
* 查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
* 1. 定义实体类Account
* 2. 查询数据,封装到Account对象中
* 3. 将Account对象存入ArrayList集合中
*
*
* @throws Exception
*/
@Test
public void testResultSet2() throws Exception {
//1. 注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
String url = "jdbc:mysql:///maven?useSSL=false";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, username, password); //3. 定义sql
String sql = "select * from account"; //4. 获取statement对象 不能用(Statement)
//Statement stmt = conn.createStatement();
PreparedStatement pps = conn.prepareStatement(sql);
//5. 执行sql
//ResultSet rs = stmt.executeQuery(sql);
ResultSet rs = pps.executeQuery();
// 创建集合
List<Account> list = new ArrayList<>(); // 6.1 光标向下移动一行,并且判断当前行是否有数据
while (rs.next()){
Account account = new Account();
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money1");
account.setId(id);
account.setName(name);
account.setMoney(money);
// 存入集合
list.add(account);
}
System.out.println(list); //7. 释放资源
rs.close();
pps.close();
conn.close();
}
}

2.5 PreparedStatement

2.5.1概述

预编译的执行者对象,执行SQL语句并返回SQL语句执行的结果集。

相对于Statement来说,PreparedStatement有额外两个作用:

  1. 通过转义字符避免SQL注入问题。
  2. 开启预编译后,通过预编译可以提高SQL语句的执行效率。

2.5.2 使用及API

  • 获取该对象

    // 这里的SQL语句,不需要指定参数,而是通过?作为占位符,后面再通过setString方法把参数设置进来
    PreparedStatement connection.prepareStatement(sql)
  • 设置参数

    // index 从1 开始
    pst.setString(int index, String paramter)
  • 执行DML语句:修改(增删改)

    int executeUpdate();

    返回值int:返回影响的行数。

    执行DQL语句:查询

    ResultSet executeQuery();

    返回值ResultSet:封装查询的结果集。

  • 释放资源

    立即将执行者对象释放:void close();

  • 演示代码

    /**
    *
    * @throws Exception
    */
    @Test
    public void testPreparedStatement() throws Exception {
    //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    String url = "jdbc:mysql:///db1?useSSL=false";
    String username = "root";
    String password = "1234";
    Connection conn = DriverManager.getConnection(url, username, password); // 接收用户输入 用户名和密码
    String name = "zhangsan";
    String pwd = "' or '1' = '1"; // 定义sql 预编译sql ? 占位符
    String sql = "select * from tb_user where username = ? and password = ?"; // 获取pstmt对象
    PreparedStatement pstmt = conn.prepareStatement(sql); // 设置?的值
    pstmt.setString(1,name);
    pstmt.setString(2,pwd); // 执行sql
    ResultSet rs = pstmt.executeQuery(); // 判断登录是否成功
    if(rs.next()){
    System.out.println("登录成功~");
    }else{
    System.out.println("登录失败~");
    } //7. 释放资源
    rs.close();
    pstmt.close();
    conn.close();
    }

2.5.3 原理

可以通过日志看到其运行原理及效果。

  • 准备工作1:开启预编译

    想要看小预编译执行者对象的执行效果,需要先在url中开启预编译,添加如下自定义参数即可

    useServerPrepStmts=true

    添加该参数后,完整的URL链接如下:

    jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
  • 准备工作2:打开日志,查看预编译等相关效果

    my.ini文件末尾,添加如下内容,并重启MySQL服务。

    log-output=FILE
    general-log=1
    general_log_file="D:\mysql.log"
    slow-query-log=1
    slow_query_log_file="D:\mysql_slow.log"
    long_query_time=2
  • 重启MySQL

    方式1:可以打开服务窗口,手动重启MySQL服务。

    方式2:在以管理员身份打开的命令行中,键入以下命令

    net stop mysql  # 关闭mysql服务
    net start mysql # 开启mysql服务
  • 结论

    通过修改查询相关代码,并查看日志,可以得出如下结论:

    1. URL中开启预编译后,相同模板的SQL语句在创建预编译执行者对象的时候,就已经发送到SQL,并完成了语法检查和编译。
    2. 预编译执行者对象,在往SQL模板中设置参数的时候,会对参数中的特殊符号添加转义字符\,避免SQL注入
    3. 使用相同模板的多条不同参数的SQL语句,只会在第一次创建预编译执行者对象的时候编译一次,从而提高执行效率。
  • 演示代码

    /**
    * PreparedStatement原理
    * @throws Exception
    */
    @Test
    public void testPreparedStatement2() throws Exception { //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    // useServerPrepStmts=true 参数开启预编译功能
    String url = "jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true";
    String username = "root";
    String password = "root";
    Connection conn = DriverManager.getConnection(url, username, password); // 接收用户输入 用户名和密码
    String name = "zhangsan";
    String pwd = "' or '1' = '1"; // 定义sql
    String sql = "select * from tb_user where username = ? and password = ?"; // 获取pstmt对象
    PreparedStatement pstmt = conn.prepareStatement(sql); Thread.sleep(10000);
    // 设置?的值
    pstmt.setString(1,name);
    pstmt.setString(2,pwd);
    ResultSet rs = null;
    // 执行sql
    rs = pstmt.executeQuery(); // 设置?的值
    pstmt.setString(1,"aaa");
    pstmt.setString(2,"bbb"); // 执行sql
    rs = pstmt.executeQuery(); // 判断登录是否成功
    if(rs.next()){
    System.out.println("登录成功~");
    }else{
    System.out.println("登录失败~");
    } //7. 释放资源
    rs.close();
    pstmt.close();
    conn.close();
    }

3. SQL注入及解决方案

3.1. 产生的原因

使用任意用户名并配合下面的密码,登录

' or '1' = '1

普通执行者对象拼接后的SQL 语句,变成了:

select * from tb_user where username = 'xxxx' and password = '' or '1' = '1'

普通的statement只是把用户输入的用户名和密码进行了简单的拼接,拼接到了SQL语句中。

这样,用户名或密码中特殊的单子或符号就被识别成了SQL语句中的关键字或者是特殊符号。

思路:仅把' or 1=1 -- 当做普通的字符串来处理,使用转义符号\,然后面的符号表示其本来的意思(现原形)。

PreparedStatement就是使用这个思路解决的。

PreparedStatement中的方法public void setString(int parameterIndex, String x) throws SQLException

// 提前准备好长度变量,不用每次调用length()方法,效率高
int stringLength = x.length(); for(int i = 0; i < stringLength; ++i) {
// 获取参数的每一个字符
char c = x.charAt(i); // 判断是否是特殊符号,如果是就在前面拼一个 \ 转义,让这个特殊符号表示自己原来的意思。
switch(c) {
case '\u0000':
buf.append('\\');
buf.append('0');
break;
case '\n':
buf.append('\\');
buf.append('n');
break;
case '\r':
buf.append('\\');
buf.append('r');
break;
case '\u001a':
buf.append('\\');
buf.append('Z');
break;
case '"':
if (this.usingAnsiMode) {
buf.append('\\');
} buf.append('"');
break;
case '\'':
buf.append('\\');
buf.append('\'');
break;
case '\\':
buf.append('\\');
buf.append('\\');
break;
case '¥':
case '₩':
if (this.charsetEncoder != null) {
CharBuffer cbuf = CharBuffer.allocate(1);
ByteBuffer bbuf = ByteBuffer.allocate(1);
cbuf.put(c);
cbuf.position(0);
this.charsetEncoder.encode(cbuf, bbuf, true);
if (bbuf.get(0) == 92) {
buf.append('\\');
}
} buf.append(c);
break;
default:
buf.append(c);
}
}

4. 连接池

4.1 概念

初始化并维护多个连接对象,当其他地方需要数据库连接时,从连接池获取;用完之后,归还到连接池。

以此实现连接的复用,提高效率。

数据源:DataSource,内部维护了一个连接池,还提供了操作连接池的一些功能。

一般情况下,会把数据源和连接池混为一谈,把数据源喊做连接池。

常见的数据源有:C3P0、Druid。我们学习Druid

4.2 池化思想(重要)

以空间换时间的做法。

游戏背包、新闻客户端。

  1. 提供更好的使用体验
  2. 对资源的消耗会更少。不会频繁的创建和销毁对象。

4.3 Druid使用

4.3.1 导包

// 导包并添加到添加了模块类库
druid-1.1.12.jar

4.3.2 配置文件

properties配置文件(名字任意),但是配置文件中key的值固定。常见参数如下:

# 连接四要素
# 数据库驱动全类名
driverClassName=com.mysql.jdbc.Driver
# URL
url=jdbc:mysql:///maven?useSSL=false&useServerPrepStmts=true
#用户名
username=root
#密码
password=root # 其他参数
# 初始化连接数
initialSize=5
# 最大连接数
maxActive=10
# 超时时间
maxWait=3000

完整参数介绍:

属性 说明 建议值
url 数据库的jdbc连接地址。一般为连接oracle/mysql。示例如下:
mysql : jdbc:mysql://ip:port/dbname?option1&option2&…
oracle : jdbc:oracle:thin:@ip:port:oracle_sid
username 登录数据库的用户名
password 登录数据库的用户密码
initialSize 启动程序时,在连接池中初始化多少个连接 10-50已足够
maxActive 连接池中最多支持多少个活动会话
maxWait 程序向连接池中请求连接时,超过maxWait的值后,认为本次请求失败,即连接池 100
没有可用连接,单位毫秒,设置-1时表示无限等待
minEvictableIdleTimeMillis 池中某个连接的空闲时长达到 N 毫秒后, 连接池在下次检查空闲连接时,将 见说明部分
回收该连接,要小于防火墙超时设置
net.netfilter.nf_conntrack_tcp_timeout_established的设置
timeBetweenEvictionRunsMillis 检查空闲连接的频率,单位毫秒, 非正整数时表示不进行检查
keepAlive 程序没有close连接且空闲时长超过 minEvictableIdleTimeMillis,则会执 true
行validationQuery指定的SQL,以保证该程序连接不会池kill掉,其范围不超
过minIdle指定的连接个数。
minIdle 回收空闲连接时,将保证至少有minIdle个连接. 与initialSize相同
removeAbandoned 要求程序从池中get到连接后, N 秒后必须close,否则druid 会强制回收该 false,当发现程序有未
连接,不管该连接中是活动还是空闲, 以防止进程不会进行close而霸占连接。 正常close连接时设置为true
removeAbandonedTimeout 设置druid 强制回收连接的时限,当程序从池中get到连接开始算起,超过此 应大于业务运行最长时间
值后,druid将强制回收该连接,单位秒。
logAbandoned 当druid强制回收连接后,是否将stack trace 记录到日志中 true
testWhileIdle 当程序请求连接,池在分配连接时,是否先检查该连接是否有效。(高效) true
validationQuery 检查池中的连接是否仍可用的 SQL 语句,drui会连接到数据库执行该SQL, 如果
正常返回,则表示连接可用,否则表示连接不可用
testOnBorrow 程序 申请 连接时,进行连接有效性检查(低效,影响性能) false
testOnReturn 程序 返还 连接时,进行连接有效性检查(低效,影响性能) false
poolPreparedStatements 缓存通过以下两个方法发起的SQL: true
public PreparedStatement prepareStatement(String sql)
public PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency)
maxPoolPrepareStatement
PerConnectionSize
每个连接最多缓存多少个SQL 20
filters 这里配置的是插件,常用的插件有: stat,wall,slf4j
监控统计: filter:stat
日志监控: filter:log4j 或者 slf4j
防御SQL注入: filter:wall
connectProperties 连接属性。比如设置一些连接池统计方面的配置。
druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
比如设置一些数据库连接属性:

4.3.3 代码

public class DruidDemo {

    public static void main(String[] args) throws Exception {
//1.导入jar包
//2.定义配置文件 //3. 加载配置文件 map集合 key-value
Properties prop = new Properties();
prop.load(new FileInputStream("web_day03_jdbc-demo/src/druid.properties"));
//4. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop); //5. 获取数据库连接 Connection
Connection connection = dataSource.getConnection(); System.out.println(connection); // 这里可以调用connection的close方法
// Druid充了connection的close方法,实现逻辑变成了回收连接,而非关闭连接
connection.close(); // 获取当前代码的运行路径,可以运行下面一行代码
//System.out.println(System.getProperty("user.dir"));
}
}

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

  1. JavaWeb用Jdbc操作MySql数据库(一)

    一.添加开发包.在JavaWeb中用jdbc操作数据库,使用方法与java一样,但是在处理开发包的问题上有点差别.JavaWeb不能将mysql-connector-java-5.1.7-bin.ja ...

  2. 【JavaWeb】JDBC连接MySQL数据库

    正文之前 在之前写的JavaWeb项目中使用了JDBC,在此来回顾一下,并做个demo看看,先来看看JDBC的概念 Java数据库连接,(Java Database Connectivity,简称JD ...

  3. JavaWeb用Jdbc操作MySql数据库(二)

    一.仍然使用前面的环境和示例数据库. 二.建立发出注册请求的页面index3.jsp. <%@ page language="java" import="java. ...

  4. JavaWeb之JDBC

    一.介绍 C#定义了ADO.Net接口来实现对SQLServer.Oracel等数据库的访问,那Java定义了JDBC接口实现对数据库的访问,数据库提供商只要实现这些接口,Java语言就能访问数据库. ...

  5. JavaWeb 例子 JDBC+JSP登陆注册留言板

    注册页面: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEnc ...

  6. JavaWeb基础—JDBC(二)事务与批处理

    一.批处理 这里给出PrepareStatement的示例,优点是可以发送预编译的SQL,缺点是SQL语句无法更换,但参数可以更换 批处理:多条语句的处理 mysql默认是关闭的,要打开需要在url后 ...

  7. JavaWeb基础—JDBC入门

    一.什么是JDBC JDBC全称为:Java Data Base Connectivity(java数据库连接),它主要由接口组成 二.JDBC原理概述 JDBC原理:其实就是一组规范(就是对类的规范 ...

  8. Javaweb入门 JDBC第一天

    JDBC的定义和作用 DBC(Java DataBase Connectivity) Java数据库连接, 其实就是利用Java语言/程序连接并访问数据库的一门技术. 之前我们可以通过cmd或者nav ...

  9. javaweb学习——JDBC(五)

    管理结果集 JDBC使用ResultSet来封装查询到的结果集,然后移动记录指针来取出结果集的内容,除此之外,JDBC还允许通过ResultSet来更新记录,并提供了ResultSetMetaData ...

  10. javaweb 03: jsp

    JSP 我的第一个JSP程序: 在WEB-INF目录之外创建一个index.jsp文件,然后这个文件中没有任何内容. 将上面的项目部署之后,启动服务器,打开浏览器,访问以下地址: http://loc ...

随机推荐

  1. 通过命令验证docker容器相当一个轻量级的Linux运行环境,且每个容器内都有一个属于自己的文件系统,容器之间相互隔离

    一.docker的三个重要概念 1.镜像:打包项目带上环境,即镜像 Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资源.配置等文件外,还包含了一些为运行时准备的配置参数.镜像 ...

  2. python实现基于smtp发送邮件

    [前言] 在某些项目中,我们需要实现发送邮件的功能,比如: 爬虫结束后,发送邮件通知 定时发送邮件提醒待办事项 某项业务逻辑触发邮件通知 今天我们就分享如何基于smtp借助163邮箱来发送邮件 [实现 ...

  3. CSS展开收起

    有一个问题是,在上述例子中,把段落内容的"浮动元素"去掉后,段落最后从"行"字开始换行了,"收起"却不换行,也就是会存在有两个字内容看不见情 ...

  4. Docker容器的数据卷

    一.数据卷概念 1.数据卷是宿主机中的一个目录或文件 2.当容器目录和数据卷目录绑定后,对方的修改会立即同步 3.一个数据卷可以被多个容器同时挂载 4.一个容器也可以挂载多个数据卷 简单理解:有点类似 ...

  5. 一文彻底搞懂JavaScript中的prototype

    prototype初步认识 在学习JavaScript中,遇到了prototype,经过一番了解,知道它是可以进行动态扩展的 function Func(){}; var func1 = new Fu ...

  6. Springcloud及Git线上配置详解

    SpringCloud 这个阶段该如何学? 三层架构 + MVC 框架: Spring IOC AOP SpringBoot,新一代的JavaEE开发标准,自动装配 模块化~ all in one,代 ...

  7. zabbix 1.1

    1.zabbix监控平台 2.zabbix的三部分组件:      Zabbix server 是 Zabbix软件的核心组件,agent 向其报告可用性.系统完整性信息和统计信息.server也是存 ...

  8. 好客租房23-react组件的两种创建方式(抽离为独立js)

    2.3抽离为单独组件 组件作为一个单独的个体,一般把每个组件放在单独的js中文件中 1创建hello.js 2在hello.js中导入React 3创建组件(函数或者类) hello.js子组件 // ...

  9. CF1682E Unordered Swaps

    鸽着,我不知道为什么对? 题意: 思路: code: #include<bits/stdc++.h> using namespace std; const int N=5e5+5; int ...

  10. 第6章 字符串(下)——C++字符串

    6.5 C++ strings(C++字符串) C风格字符串常见错误:试图去访问数组范围以外的元素:没有使用函数strcpy( )来实现字符串之间的复制:没有使用函数strcmp( )来比较两个字符串 ...