JavaWeb_jdbc笔记

回顾

Jdbc 的使用步骤

  1. 导入 jar 包
  2. 注册驱动 Class.forName(“com.mysql.jdbc.Driver”)
  3. 创建连接对象 Connection conn = DriverManager.getConnection(“连接字符串”,“用户名”,“密码”)
    • jdbc:mysql://ip地址:3306/数据库名
  4. PreparedStatement stmt = conn.prepareStatement(“sql”)
  5. 执行sql
    • executeUpdate() 执行增删改,返回值代表影响行数
    • executeQuery() 执行查询,返回 ResultSet 代表结果
  6. 释放资源
    • rs.close
    • stmt.close
    • conn.close

PreparedStatement 如何使用,它可以解决什么样的问题

  • PreparedStatement stmt = conn.prepareStatement(“select * from 表 where id=?”)
  • PreparedStatement stmt = conn.prepareStatement(“insert into 表 values(?,?,?)”)
  • ? 占位符只能代替值,不能代替关键字、表名、列名
  • stmt.setXXX(?的索引, 值); // 注意索引从1开始

ResultSet 如何使用

  • ResultSet rs = …
  • while(rs.next() )
  • rs.getXXX(“列名”)

Jdbc 工具类会用

  • Jdbc.getConnection() 获取数据库连接
  • Jdbc.close(rs, stmt, conn) 关闭资源

今日内容

1. jdbc 事务(会用)

  • conn.setAutoCommit(false) 不让自动提交,相当于事务由程序员自己控制
  • conn.commit()
  • conn.rollback()

结论

  • 将来事务的控制要放在 service 来执行
  • 控制事务要保证 connection 对象是同一个
  • dao 不要关 conn,在 service 统一关

建表

CREATE TABLE account(
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(20),
    money INT
);

insert into account values(1, '张三', 1000);
INSERT INTO account VALUES(2, '李四', 1000);

select * from account;

dao

public interface AccountDao {

    // dao 做更新操作,参数1 是账号,参数2 更新的金额
    public void update(int id, int amount, Connection conn);
}
package com.itheima.dao;

import com.itheima.util.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;

public class AccountDaoImpl implements AccountDao{
    @Override
    public void update(int id, int amount, Connection conn) {
//        Connection conn = null;
        PreparedStatement stmt = null;
        try {
//            conn = JdbcUtils.getConnection(); // conn1 conn2
            stmt = conn.prepareStatement("update account set money = money+? where id = ?");
            stmt.setInt(1, amount);
            stmt.setInt(2, id);
            stmt.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // dao 不应该关闭 conn
            JdbcUtils.close(stmt, null);
        }
    }
}

service 及测试

package com.itheima.service;

import com.itheima.dao.AccountDao;
import com.itheima.dao.AccountDaoImpl;
import com.itheima.util.JdbcUtils;

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

public class AccountService {

    private AccountDao dao = new AccountDaoImpl();
    /**
     *
     * @param source 源
     * @param target 目标
     * @param amount 金额
     */
    public void transfer(int source, int target, int amount) {

        Connection conn = JdbcUtils.getConnection();
        try {
            conn.setAutoCommit(false);
            // 转账
            dao.update(source, -1*amount, conn); // 源账号减钱
            int i = 1/0;
            dao.update(target, amount, conn); // 目标账户加钱

            conn.commit();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                conn.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        } finally {
            // service 层负责关闭连接
            JdbcUtils.close(null, conn);
        }
    }

    public static void main(String[] args) {
        AccountService service = new AccountService();
        service.transfer(1, 2, 500);
    }
}

2. Student Dao 与三层整合(* 重点,代码要求自己写)

代码和视频见飞秋共享

选择1:页面+servlet => service => dao 自顶至低

选择2:dao => service => 页面+servlet 从下到上

步骤:

  1. 编写 dao 的接口和实现
  2. 编写 service 的接口和实现
  3. 编写 servlet
  4. 编写 jsp 页面

3. 连接池(会用)

  • 数据库连接属于有限的资源,应当重用,而不是每次都创建新的
  • 著名的连接池实现
    • C3P0 外国的第三方连接池
    • Druid (德鲁伊) ali 出品,第三方连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection conn = dataSource.getConnection(); // 从连接池中获取一个已存在的连接

conn.close(); // 并不是真正关闭连接,而是将 conn 归还到连接池,(实际上重写了 close 方法)

Connection conn = DriverManager.getConnection(); // 每次都是创建新的连接
conn.close(); // 真正关闭了连接

配置文件 c3p0-config.xml

<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  	<!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://192.168.59.129:3306/db14</property>
    <property name="user">root</property>
    <property name="password">itheima</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">10</property>
    <property name="checkoutTimeout">3000</property>
  </default-config>
</c3p0-config>

druid

// 1. 获取配置文件输入流,注意配置文件必须在 src 下
InputStream is = 工具类.class.getClassLoader().getResourceAsStream("配置文件路径");

// 2. 创建 Properties 对象
Properties prop = new Properties();
prop.load(is);

// 3. 创建连接池
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);

// 4. 获取连接
Connection con = dataSource.getConnection();

// 5. 归还连接
con.close();
自定义连接池
  • 思想 - close 不能真正关闭连接,而是归还到连接池
  • 为了实现 close 功能的增强,MyConnection 替换了(包装了) 真正的 Connection
    • 调用 close 方法时调用是MyConnection 里增强后的方法
    • 调用其它方法是,间接调用了真正的 Connection 的方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值