《Tomcat与Java Web开发技术详解》阅读梳理 第八章 访问数据库

点击查看合集

JDBC

JDBC(java DataBase Connectivity)是java与数据库连接的纽带。JDBC封装了java与数据库通信的细节。程序员只需要通过JDBC API就可以与数据库服务器通信。
优点:
1.简化代码
2.使java代码不依赖具体数据库服务器。
JDBC API位于java.sql(大部分)和javax.sql(高级特性)包中。
在这里插入图片描述

JDBC的实现

JDBC的实现包括三个部分
1.JDBC驱动管理器:java.sql.DriverManger类,由Oracle公司实现,负责注册特定JDBC驱动器,以及根据特定驱动器建立与数据库的连接。
2.JDBC驱动器API:由Oracle公司制定,其中最主要的接口是java.sql.Driver接口。
3.JDBC驱动器,由数据库供应商,或者其他第三方工具提供商创建,也成为JDBC驱动程序。JDBC驱动器实现了JDBC驱动器API负责与与特定数据库连接。
在这里插入图片描述
JDBC API:java程序通过它来访问各种数据库。
JDBC驱动器 API:具体的JDBC驱动器需要实现它(java.sql.Driver)
因此实际上java程序与数据库服务器的连接是由JDBC驱动器完成的。

桥梁设计模式

DriverManager类运用桥梁设计模式,是java程序与各种JDBC驱动器连接的桥梁。
应用程序只和JDBC API打交道,JDBC API依赖DriverManager类来管理JDBC驱动器。
在这里插入图片描述

java.sql包中的接口和类

JDBC API主要在java.sql包中,主要有
1.Driver接口:驱动器
2.DriverManager类:驱动管理器
3.Connection接口:表示数据库连接
4.Statement接口:负责执行SQL语句
5.PreparedStatement接口:负责执行预准备的SQL语句
6.CallableStatement接口:负责执行SQL存储过程。
7.ResultSet接口:表示SQL查询语句返回的结果集。
在这里插入图片描述

DRiverManager类方法

在这里插入图片描述
在这里插入图片描述

Connection接口方法

在这里插入图片描述

Statement接口

在这里插入图片描述

PrepareStatement接口方法

PrepareStatement是statement的子接口,statement执行的sql语句参数都是固定的。而prepareStatement的参数可以动态修改。每次通过statement执行sql语句都要重新编译。而prepareStatement只需编译一次,然后可以多次执行。
例子
PreparedStatement

PreparedStatement preparedStatement = connection.prepareStatement("select id,username,? from user where id = ?");
        //第一个?是password
        preparedStatement.setString(1,"password");
        //第二个?是10
        preparedStatement.setInt(2,2);

Statement

 Statement statement = connection.createStatement();
        statement.execute("select * from user where id = 10");

ResultSet接口的方法

ResultSet接口表示select查询语句得到的结果集。
d
在这里插入图片描述

  while (resultSet.next()){
    
    
            //根据索引
            System.out.println(resultSet.getString(1));
            //根据字段名
            System.out.println(resultSet.getString("username"));
        }

访问数据库程序的步骤

1.加载JDBC驱动器

Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");

2.注册数据库驱动器

DriverManager.registerDriver((Driver) aClass.newInstance());

这一步实际上并不是必须的
因为在com.mysql.cj.jdbc.Driver内部有这么一段静态代码

static {
    
    
        try {
    
    
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
    
    
            throw new RuntimeException("Can't register driver!");
        }
    }

他实际上会在加载的时候就自己把自己注册了
3.与数据库建立连接

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

url的格式
jdbc:[数据库名]:[数据库服务器IP]:[端口号]/[数据库名]?[默认配置]

完整例子

//1.加载并注册驱动
        Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
        //DriverManager.registerDriver((Driver) aClass.newInstance());
        //2.与数据库建立连接
        String url = "jdbc:mysql://localhost:3306/db1";
        Connection connection = DriverManager.getConnection(url,"root","root");
        //3.用PreparedStatement
        PreparedStatement preparedStatement = connection.prepareStatement("select id,username,? from user where id = ?");
        //第一个?是password
        preparedStatement.setString(1,"password");
        //第二个?是10
        preparedStatement.setInt(2,2);
        preparedStatement.execute();
        //获取ResultSet对象
        ResultSet resultSet1 = preparedStatement.getResultSet();
        while (resultSet1.next()){
    
    
            //根据索引
            System.out.println(resultSet1.getInt(1));
            //根据字段名
            System.out.println(resultSet1.getString("username"));
            //根据索引
            System.out.println(resultSet1.getString(3));
        }

        //3.用statement
        Statement statement = connection.createStatement();
        statement.execute("select id,username,password from user where id = 9");
        //获取ResultSet对象
        ResultSet resultSet = statement.getResultSet();
        while (resultSet.next()){
    
    
            //根据索引
            System.out.println(resultSet.getInt(1));
            //根据字段名
            System.out.println(resultSet.getString("username"));
            //根据索引
            System.out.println(resultSet.getString(3));
        }

事务处理

所谓事务,就是多条SQL语句组合而成的。这些SQL语句要么都成功完成,要么都失败。也就是说即使有一个SQL语句执行出现错误,这个事务中的所有SQL都将失效
在Connection接口中提供了三个控制事务的方法
1.serAutoCommit(boolean autoCommit);设置是否自动提交事务。默认情况下为true。也就是说每条SQL语句执行成功后自动提交,失败则自动回滚。
2.commit();提交事务
3.rollback():回滚事务
例子

 //1.加载并注册驱动
        Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
        //DriverManager.registerDriver((Driver) aClass.newInstance());
        //2.与数据库建立连接
        String url = "jdbc:mysql://localhost:3306/db1";
        Connection connection = DriverManager.getConnection(url,"root","root");
        //禁止自动提交事务
        connection.setAutoCommit(false);
        Statement statement1 = connection.createStatement();
        try{
    
    
            statement1.executeUpdate("update user set password = 'heh213e1' where id = 2");
            statement1.executeUpdate("update user set password = heh213e1 where id = 2");
            connection.commit();
        }catch (SQLException e){
    
    
            //事务回滚
            connection.rollback();
        }

配置数据源

context.xml

<?xml version="1.0" encode="UTF-8" ?>
<Context>
    <!--    T9.0 将resource复制到tomcat/config/context的Context中-->
    <Resource
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/db1"
            username="root"
            password="root"
            maxActive="50"
            maxIdle="20"
            name="ds"
            auth="Container"
            maxWait="10000"
            type="javax.sql.DataSource"/>
</Context>


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">


  <resource-ref>
    <description>DB Connection</description>
    <res-ref-name>ds</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

</web-app>



@WebServlet("/test3")
public class Test3 extends HttpServlet {
    
    

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        Connection connection =null;
        try {
    
    
            InitialContext context = new InitialContext();
            DataSource ds = (DataSource) context.lookup("java:comp/env/ds");
            connection = ds.getConnection();
            Statement statement = connection.createStatement();
            statement.execute("select id,username.password from user ");
            ResultSet resultSet = statement.getResultSet();
            while(resultSet.next()){
    
    
                System.out.println(resultSet.getInt(1));
                System.out.println(resultSet.getString(2));
                System.out.println(resultSet.getString(3));
            }
        } catch (NamingException e) {
    
    
            e.printStackTrace();
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        } finally {
    
    
            try {
    
    
                connection.close();
            } catch (SQLException throwables) {
    
    
                throwables.printStackTrace();
            }
        }
    }
}

可滚动的结果级

//创建一个可以生成可以滚动的结果集的statemen
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_30033509/article/details/109748069