JDBC应用最全笔记(附带案例)

Java的JDBC最全基础笔记(SQL注入) 1、JDBC:Java DataBase Connectivity,可以理解为是以前的Socket桥梁,或流读写数据库(1)确切的说,JDBC是Java平台提供的一套统一的执行规范/标准(2)那么我们知道通常定义规范,一般都要定义一些接口,所以JDBC这一套规范中定义了很多的接口和类及方法(3)那么接口是不能干活的,需要子类去完成,那么子类需要谁去完成?(4)Java对应多种数据库,那么就需要数据库去实现这个接口,Mysql数据库要去实现,Oracle的数据库也要去实现; 阅读详情

JDBC

一、概述

在Java中,数据库存取技术可分为如下⼏类:

1、JDBC直接访问数据库

2、 JDO技术(Java Data Object)

3、第三⽅O/R⼯具,如Hibernate, Mybatis 等

JDBC是java访问数据库的基⽯,JDO, Hibernate等只是更好的封装了JDBC。

二、理解

JDBC(Java Database Connectivity)是⼀个独⽴于特定数据库管理系统(DBMS)、通⽤的SQL数据库存取和操作的公共接⼝(⼀组API),定义了⽤来访问数据库的标准Java类库,使⽤这个类库可以以⼀种标准的⽅法、⽅便地访问数据库资源

JDBC为访问不同的数据库提供了⼀种统⼀的途径,为开发者屏蔽了⼀些细节问题。

JDBC的⽬标是使Java程序员使⽤JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样就使得程序员⽆需对特定的数据库系统的特点有过多的了解,从⽽⼤⼤简化和加快了开发过程。

如果没有JDBC,那么Java程序访问数据库时是这样的:

在这里插入图片描述

有JDBC,那么Java程序访问数据库时是这样的:

在这里插入图片描述

三、JDBC API

JDBC API是⼀系列的接⼝,它统⼀和规范了应⽤程序与数据库的连接、执⾏SQL语句,并到得到返回结果等各类操作。声明在java.sql与javax.sql包中。

1、DriverManager类 管理不同的驱动

2、Connection 接⼝ 应⽤和数据库的连接

3、Statement 接⼝ ⽤于执⾏sql语句

4、 ResultSet 接⼝ 保存查询的结果

四、JDBC的使用

1、下载驱动:

驱动程序由数据库提供商提供下载。 MySQL的驱动下载地址:http://dev.mysql.com/downloads/

2、创建项⽬导⼊jar包

3、 使⽤:

① 注册驱动(加载驱动)

② 获取连接对象

③ 创建命令对象

④ 编写sql命令

⑤ 执⾏sql命令 返回结果

⑥ 处理结果

⑦ 释放资源

 private static void queryAll() throws ClassNotFoundException, SQLException {
        //  1、加载驱动
        // DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        Class.forName("com.mysql.jdbc.Driver");
        //  2、获取连接  参数1:连接路径    参数2:用户名  参数3:密码
        //  https://downloads.mysql.com/archives/c-j/
        Connection connection = DriverManager
                .getConnection("jdbc:mysql://localhost:3306/java0210", "root", "123456");

        System.out.println(connection);
        System.out.println(connection==null?"连接失败":"连接成功");

        //3、 编写sql语句
        String sql = "select * from user";

        //4、创建命令对象
        Statement statement = connection.createStatement();

        //5、执行sql语句 返回结果
        ResultSet rs = statement.executeQuery(sql);


        //6、处理结果    rs.next()如果为true 集合中还有内容 如果为false 数据获取完毕
        while(rs.next()){
            String name = rs.getString("name");
            int age = rs.getInt("age");
            System.out.println("姓名:"+name+"\t姓名:"+age);
           // System.out.println(rs.getString("name")+" 年龄:"+rs.getInt("age"));
        }

        //7、释放资源  遵循 先开后关原则
        rs.close();
        statement.close();
        connection.close();
    }

五、连接池

5.1、为什么使用连接池

1、数据库连接是⼀种关键的有限的昂贵的资源,传统数据库连接每发出⼀个请求都要创建⼀个连接对象,使⽤完直接关闭不能重复利⽤;

2、关闭资源需要⼿动完成,⼀旦忘记会造成内存溢出;

3、请求过于频繁的时候,创建连接极其消耗内存;

4、⽽且⼀旦⾼并发访问数据库,有可能会造成系统崩溃。

为了解决这些问题,我们可以使⽤连接池。

5.2、连接池原理

数据库连接池负责分配、管理和释放数据库连接,它的核⼼思想就是连接复⽤,通过建⽴⼀个数据库连接池,这个池中有若⼲个连接对象,当⽤户想要连接数据库,就要先从连接池中获取连接对象,然后操作数据库。⼀旦连接池中的连接对象被⽤完了,判断连接对象的个数是否已达上限,如果没有可以再创建新的连接对象,如果已达上限,⽤户必须处于等待状态,等待其他⽤户释放连接对象,直到连接池中有被释放的连接对象了,这时候等待的⽤户才能获取连接对象,从⽽操作数据库。这样就可以使连接池中的连接得到⾼效、安全的复⽤,避免了数据库连接频繁创建、关闭的开销。这项技术明显提⾼对数据库操作的性能。

5.3、连接池的好处

1、程序启动时提前创建好连接,不⽤⽤户请求时创建,给服务器减轻压⼒;

2、连接关闭的时候不会直接销毁connection,这样能够重复利⽤;

3、如果超过设定的连接数量但是还没有达到最⼤值,那么可以再创建;

4、如果空闲了,会默认销毁(释放)⼀些连接,让系统性能达到最优;

5.4、常见的开源连接池

1、 【DBCP】是Apache提供的数据库连接池,速度相对c3p0较快,但因⾃身存在BUG,Hibernate3已不再提供⽀持

2、【C3P0】是⼀个开源组织提供的⼀个数据库连接池,速度相对较慢,稳定性还可以

3、【Druid】是阿⾥提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于⼀身的数据库连接池,但是速度不知道是否有BoneCP快

5.5、连接池的使用

5.5.1、c3p0连接池

1、下载导包 c3p0-0.9.5.2.jar mchange-commons-java-0.2.11.jar

代码配置⽅式

① 创建c3p0连接池对象

 //1、创建连接池对象
        ComboPooledDataSource cpds = new ComboPooledDataSource();

② 配置信息 (必配、选配) 【创建 c3p0.properties 放在src⽬录下】

#必配信息
c3p0.driverClass = com.mysql.jdbc.Driver
c3p0.jdbcUrl = jdbc:mysql://localhost:3306/java0210
c3p0.user = root
c3p0.password = 123456

#选配
c3p0.InitialPoolSize = 10   #初始连接数
c3p0.MaxPoolSize = 200		#最大连接数
c3p0.MinPoolSize = 15		#最小连接数
c3p0.MaxIdleTime = 30		#最大空闲时间

③ 从池⼦中获取连接

 //从池子中获取连接
        Connection connection = cpds.getConnection();

④ sql 操作

		//1、编写sql
        String sql = "select * from user where age = 23";
        //2、创建命令对象
        Statement statement = connection.createStatement();
        //3、执行命令 返回结果
        ResultSet resultSet = statement.executeQuery(sql);
        //4、处理结果
        if (resultSet.next()){
            String name = resultSet.getString("name");
            int age = resultSet.getInt("age");
            System.out.println("姓名:"+name+"\t姓名:"+age);
        }
        //5、把连接对象放回连接池
        connection.close();
5.5.2、Druid连接池

1、下载导包 druid-1.1.10.jar 在lib目录下

2、 编写druid.properties 放在src⽬录下

#必配
driver.ClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/java0210
username = root
password = 123456
#选配
initialSize = 15		#初始连接数
maxActive = 100			#最大连接数
minIdle = 5				#最小连接数
maxWait = 30000			#最大空闲时间

3、读取配置文件

// 一、读取配置文件
        Properties properties = new Properties();

        // 根据当前线程对象的上下文类加载器 以流的方式 读取src目录下的文件
        InputStream asStream = Thread.currentThread()
                .getContextClassLoader().getResourceAsStream("druid.properties");

        properties.load(asStream);

4、创建druid连接池对象

// 二、创建druid连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

5、从连接池中获取连接

 //从池子中获取连接
        Connection connection = dataSource.getConnection();

6、sql 操作

		//1、编写sql
        String sql = "select * from user where age = 23";
        //2、创建命令对象
        Statement statement = connection.createStatement();
        //3、执行命令 返回结果
        ResultSet resultSet = statement.executeQuery(sql);
        //4、处理结果
        if (resultSet.next()){
            String name = resultSet.getString("name");
            int age = resultSet.getInt("age");
            System.out.println("姓名:"+name+"\t姓名:"+age);
        }
        //5、把连接对象放回连接池
        connection.close();
5.6、封装JDBCTools

ThreadLocal类

【理解】JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了⼀种新的思路。使⽤这个⼯具类可以很简洁地编写出优美的多线程程序。

【原理】

ThreadLocal⽤于保存某个线程共享变量,原因是在Java中,每⼀个线程中都有⼀个ThreadLocalMap<ThreadLocal, Object>,其key就是⼀个ThreadLocal,⽽Object即为该线程的共享变量。⽽这个map是通过ThreadLocal的set和get⽅法操作的。对于同⼀个static ThreadLocal,不同线程只能从中get,set,remove⾃⼰的变量,⽽不会影响其他线程的变量。

【使⽤】

1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。

2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。

3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。

public class JDBCPoolTools2 {
    static DataSource dataSource;
    // 实例化ThreadLocal类
    private static ThreadLocal<Connection> t = new ThreadLocal<>();
    static {
        try{
            // 一、读取配置文件
            Properties properties = new Properties();

            // 根据当前线程对象的上下文类加载器 以流的方式 读取src目录下的文件
            InputStream asStream = Thread.currentThread()
                    .getContextClassLoader().getResourceAsStream("druid.properties");
            properties.load(asStream);
            //2、创建连接池
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 定义一个获取连接的静态方法
    public static Connection getConnection(){
        try {
            //1、从连ThreadLocal中获取连接
            Connection connection = t.get();
            if (connection==null){
                //2、如果连接为空,从连接池中获取一个连接对象
                t.set(dataSource.getConnection());
                //3、把这个连接对象绑定到ThreadLocal类
                connection = t.get();
            }
            return connection;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //封装释放连接对象的方法
    public static void release(){
        // 1、将连接对象 和 ThreadLocal类 解绑
        Connection connection = t.get();
        t.remove();
        // 2、释放资源
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

测试类

public static void main(String[] args) {
        //    建立连接  从JDBCPoolTools2中调用 getConnection()方法
        Connection connection = JDBCPoolTools2.getConnection();
        try {
        //     sql操作
            String sql = "select * from admin_user";
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()){
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                System.out.println("账号:"+username+"\t密码:"+password);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
        //     必须必须【解绑】和【释放资源】,从JDBCPoolTools2中调用 release()方法
            if (connection!=null){
                Up_DruidPool_03.release();
            }
        }
    }

六、juint

6.1、概述

JUnit是⼀个Java语⾔的单元测试框架。测试分为:⿊盒测试和⽩盒测试。

⿊盒测试⼜称功能测试,主要检测每个功能是否都能正常使⽤。在测试中,把程序看作⼀个不能打开的⿊盒⼦,在完全不考虑程序内部结构和内部特性的情况下,进⾏测试,主要针对软件界⾯和软件功能进⾏测试。 ⽩盒测试⼜称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试,主要检测程序内部逻辑是否正常。在测试中测试者必须检查程序的内部结构,从检查程序的逻辑着⼿,得出测试数据。按照程序内部的结构进⾏测试。这⼀⽅法是把测试对象看作⼀个打开的盒⼦,测试⼈员清楚盒⼦内部的东⻄以及⾥⾯是如何运作的单元测试Junit就属于⽩盒测试.

6.2、使用

1、把junit4.x的测试jar,添加到该项⽬中来;

2、定义⼀个测试类 测试类的名字: XxxTest,如EmployeeDAOTest

3、 在EmployeeDAOTest中编写测试⽅法:如

@BeforeClass
    public static void beforeClass(){
        
}

@Before
public void bef(){
        
}

@Test
public void testXxx() throws Exception {

 }

@After
public void aft(){
       
}

@AfterClass
public static void afterClass(){

}

注意:⽅法是public修饰的,⽆返回的,该⽅法上必须贴有@Test标签,XXX表示测试的功能名字

4、选择某⼀个测试⽅法,⿏标右键选择 [run as junit],或则选中测试类,表示测试该类中所有的测试⽅法.

6.3、常见注解

1、@Test:要执⾏的测试⽅法

2、@Before:每次执⾏测试⽅法之前都会执⾏

3、@After: 每次执⾏测试⽅法之后都会执⾏

4、 @BeforeClass:在所有的Before⽅法之前执⾏,只在最初执⾏⼀次. 只能修饰静态⽅法

5、@AfterClass:在所有的After⽅法之后执⾏,只在最后执⾏⼀次. 只能修饰静态⽅法

七、SQL注入

7.1、理解

SQL 注⼊是利⽤某些系统没有对⽤户输⼊的数据进⾏充分的检查,⽽在⽤户输⼊数据中注⼊⾮法的 SQL 语句段或命令,从⽽利⽤系统的 SQL 引擎完成恶意⾏为的做法。对于 Java ⽽⾔,要防范 SQL 注⼊,只要⽤

PreparedStatement 取代 Statement 就可以了。

7.2、解决

SQL注入问题:sql语句中拼接了一些特殊字符 导致sql语句发生变化的现象

  • 引发原因:特殊字符导致
    
  • 解决:将特殊字符转义为普通字符  将传递的字符作为一个整体 Statement命令对象 换成PreparedStatement
    
  • PreparedStatement 原理:预编译命令对象
    
  • 1、sql语句时 使用?作为占位符 如果里面有特殊符号 自动转义

  • 2、先编译sql语句 执行时再传递参数

    PreparedStatement 好处:

  •         1. 不用拼接字符串 避免了拼接字符串产生的问题
    
  •         2. 自检特殊字符
    
  •         3. 可以复用sql语句
    

【案例】

模拟用户登录的功能

  •      1. 输入账户和密码
    
  •      2. 查询数据库中是否有该用户
    
  •          有 登录成功
    
  •          没有 登录失败
    
public class JDBCTest2 {
    String username;
    String pwd;
    Connection connection;
    @Before
    public void bef(){
        Scanner input = new Scanner(System.in);
        System.out.println("请输入用户名:");
        username = input.nextLine();
        System.out.println("请输入密码:");
        pwd = input.nextLine();

        connection = JDBCTools.getConnection();
    }
    @Test  // 使用Statement
    public void testLogin1(){

        // 根据用户名和密码查询用户
        try {

            // select * from user where name='大洋洋' and password='123321';
            String sql = "select * from user where name='"+username+"' and password='"+pwd+"'";

            Statement statement = connection.createStatement();

            ResultSet resultSet = statement.executeQuery(sql);

            System.out.println(resultSet.next()?"登录成功!":"登录失败!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }

    @Test  // 使用PreparedStatement
    public void testLogin2(){
        try {
            // 1. 编写sql语句
            String sql = "select * from user where name=? and password=?";

            // 2. 创建命令对象 预编译sql语句
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            // 3. 传递sql中的参数
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, pwd);

            // 4. 执行sql命令
            ResultSet resultSet = preparedStatement.executeQuery();

            // 5. 处理结果
            System.out.println(resultSet.next()?"登录成功!":"登录失败!");

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }
    @After
    public void aft(){
        JDBCTools.release();
    }
}

八、事务实现

1、 ⼿动开启事务 setAutoCommit(false)

2、 成功 提交 commit()

3、失败 回滚 rollback()

public class JDBCTxTest {
    Connection connection;
    @Before
    public void bef(){
        connection = JDBCTools.getConnection();
    }

    @Test  // 使用事务
    public void textUseTx(){
        try {
            // 1. 设置事务提交为手动  2. 开启一个新的事务
            connection.setAutoCommit(false);

            String sql = "update user set money=? where uid=?";

            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setDouble(1, 900);
            preparedStatement.setInt(2, 1);

            preparedStatement.executeUpdate();

            // 模拟异常
            int i = 10/0;

            preparedStatement.setDouble(1, 1100);
            preparedStatement.setInt(2, 2);

            preparedStatement.executeUpdate();

            connection.commit();
            System.out.println("转账成功!");
        } catch (SQLException throwables) {
            try {
                connection.rollback();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            throwables.printStackTrace();
        }
    }

    @After
    public void aft(){
        JDBCTools.release();
    }
}

九、批处理

9.1、概述

JDBC操作数据库的时候,需要⼀次性插⼊⼤量的数据的时候,如果每次只执⾏⼀条SQL语句,效率可能会⽐较低。这时可以使⽤batch操作,每次批量执⾏SQL语句,调⾼效率。

9.2、实现

1、 添加批处理 addBacth();

2、执⾏批处理 executeBacth();

3、清除批处理 clearBatch();

public class JDBCBatchTest {
    Connection connection;
    @Before
    public void bef(){
        connection = JDBCTools.getConnection();
    }

    @Test  // 使用批处理
    public void textUseBatch(){
        try {
            String sql = "insert into user(name, password, money) values(?,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            long start = System.currentTimeMillis();

            for(int i=1; i<=10000; i++){
                preparedStatement.setString(1,"root"+i);
                preparedStatement.setString(2, i+"");
                preparedStatement.setDouble(3, i);
                // 保存到批处理中
                preparedStatement.addBatch();

                if(i%100==0){
                    // 执行批处理
                    preparedStatement.executeBatch();

                    // 清除批处理  便于下一次使用
                    preparedStatement.clearBatch();
                }
            }

            long end = System.currentTimeMillis();
            System.out.println("插入10000条花费的时间:"+(end-start)); // 6080
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    @After
    public void aft(){
        JDBCTools.release();
    }
}

十、DBUtils

10.1、简介

commons-dbutils 是 Apache 组织提供的⼀个开源 JDBC⼯具类库,它是对JDBC的简单封装,学习成本极低,并且使⽤dbutils能极⼤简化jdbc编码的⼯作量,同时也不会影响程序的性能。

10.2、作用

DbUtils :提供如关闭连接、装载JDBC驱动程序等常规⼯作的⼯具类,⾥⾯的所有⽅法都是静态的。

该包封装了SQL的执⾏,是线程安全的。

1、可以实现增、删、改、查、批处理、

2、考虑了事务处理需要共⽤Connection。

3、该类最主要的就是简单化了SQL查询,它与ResultSetHandler组合在⼀起使⽤可以完成⼤部分的数据库操作,能够⼤⼤减少编码量。

10.2、常用方法

1、操作:update()

public int update(Connection conn, String sql, Object… params) throws SQLException:

⽤来执⾏⼀个更新(插⼊、更新或删除)操作。

2、 查询:query()

public Object query(Connection conn, String sql, ResultSetHandler rsh,Object…

params) throws SQLException:执⾏⼀个查询操作,在这个查询中,对象数组中的每个元素值被⽤来作为查询语句的置换参数。该⽅法会⾃⾏处理 PreparedStatement 和 ResultSet 的创建和关闭。

【注】:该接⼝⽤于处理 java.sql.ResultSet,将数据按要求转换为另⼀种形式。ResultSetHandler 接⼝提供了⼀个单独的⽅法:Object handle (java.sql.ResultSet rs)该⽅法的返回值将作为QueryRunner类的query()⽅法的返回值

【⽅法】:

ArrayHandler:把结果集中的第⼀⾏数据转成对象数组。

ArrayListHandler:把结果集中的每⼀⾏数据都转成⼀个数组,再存放到List中。

BeanHandler:将结果集中的第⼀⾏数据封装到⼀个对应的JavaBean实例中。

BeanListHandler:将结果集中的每⼀⾏数据都封装到⼀个对应的JavaBean实例中,存放到List⾥。

ColumnListHandler:将结果集中某⼀列的数据存放到List中。

KeyedHandler(name):将结果集中的每⼀⾏数据都封装到⼀个Map⾥,再把这些map再存到⼀个map⾥,其

key为指定的key。

MapHandler:将结果集中的第⼀⾏数据封装到⼀个Map⾥,key是列名,value就是对应的值。

MapListHandler:将结果集中的每⼀⾏数据都封装到⼀个Map⾥,然后再存放到List

10.4、使用

1、下载导包 commons-dbutils-1.7.jar

2、创建核⼼对象

QueryRunner qr = new QueryRunner();

3、执⾏命令

// 执⾏增删改
int update = qr.update(connection,sql,params); 
// 查询单条数据
T t = qr.query(connection,sql,new BeanHandler,params);
// 查询多条数据
List t = qr.query(connection,sql,new BeanListHandler,params);
// 查询特殊数据类型,如返回值为数量等等
Object t = qr.query(connection,sql,new ScalerHandler,params);

十一、Dao封装

11.1、介绍

Data Access Object访问数据信息的类和接⼝,包括了对数据的CRUD(Create、Retrival、Update、Delete),⽽不包含任何业务相关的信息

11.2、作用

为了实现功能的模块化,更有利于代码的维护和升级。

11.3、封装

封装通用的类:可以对任何表都能实现 增删改查的功能

  •     1. 增 删 改的方法
    
  •     2. 查询的方法[单查、多查、查询个数]
    
public class BasicDao<T> {
    QueryRunner qr;
    {
        qr = new QueryRunner();
    }
    // 1. 增删改方法
    public int update(String sql, Object...params){
        try {
            return qr.update(JDBCTools.getConnection(), sql, params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 2. 查询单个
    public T querySingle(String sql, Class<T> clazz, Object...params){
        try {
            return qr.query(JDBCTools.getConnection(), sql, new BeanHandler<>(clazz), params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 3. 查询多个
    public List<T> queryMore(String sql, Class<T> clazz, Object...params){
        try {
            return qr.query(JDBCTools.getConnection(), sql, new BeanListHandler<>(clazz), params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 4. 查询个数
    public Object scale(String sql, Object...params){
        try {
            return qr.query(JDBCTools.getConnection(), sql, new ScalarHandler<>(), params);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}

十二、项目三层架构

12.1、理解

【三层架构】 通常意义上的三层架构就是将整个业务应⽤划分为:界⾯层、业务逻辑层、数据访问层。区分层次的⽬的即为了 “⾼内聚低耦合” 的思想。在软件体系架构设计中,分层式结构是最常⻅,也是最重要的⼀种结构。微软推荐的分层式结构⼀般分为三层,从下⾄上分别为:数据访问层、业务逻辑层(⼜或称为领域层)、表示层。

表示层(JSP)

表现层也称为界⾯层,位于最外层(最上层),离⽤户最近。⽤于显示数据和接收⽤户输⼊的数据,为⽤户提供⼀种交互式操作的界⾯。

业务层(service)

  • 业务层在体系架构中的位置很关键,它处于数据访问层与表示层中间,起到了数据交换中承上启下的作⽤。

  • 由于层是⼀种弱耦合结构,层与层之间的依赖是向下的,底层对于上层⽽⾔是“⽆知”的,改变上层的设计对于其调⽤的底层⽽⾔没有任何影响。如果在分层设计时,遵循了⾯向接⼝设计的思想,那么这种向下的依赖也应该是⼀种弱依赖关系。

持久层(DAO)

持久层,有时候也称为是数据访问层,其功能主要是负责数据库的访问,可以访问数据库系统

12.2、特点

1、上⼀层可以调⽤下⼀层 但是 下⼀层不能调⽤上⼀层

2、不可以隔层调⽤

     return qr.query(JDBCTools.getConnection(), sql, new ScalarHandler<>(), params);
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

}


## 十二、项目三层架构

### 12.1、理解

> 【**三层架构**】 通常意义上的三层架构就是将整个业务应⽤划分为:界⾯层、业务逻辑层、数据访问层。区分层次的⽬的即为了 “⾼内聚低耦合” 的思想。在软件体系架构设计中,分层式结构是最常⻅,也是最重要的⼀种结构。微软推荐的分层式结构⼀般分为三层,从下⾄上分别为:数据访问层、业务逻辑层(⼜或称为领域层)、表示层。
>
>  **表示层(JSP)**
>
>  表现层也称为界⾯层,位于最外层(最上层),离⽤户最近。⽤于显示数据和接收⽤户输⼊的数据,为⽤户提供⼀种交互式操作的界⾯。
>
>  **业务层(service)**
>
> * 业务层在体系架构中的位置很关键,它处于数据访问层与表示层中间,起到了数据交换中承上启下的作⽤。
>
> * 由于层是⼀种弱耦合结构,层与层之间的依赖是向下的,底层对于上层⽽⾔是“⽆知”的,改变上层的设计对于其调⽤的底层⽽⾔没有任何影响。如果在分层设计时,遵循了⾯向接⼝设计的思想,那么这种向下的依赖也应该是⼀种弱依赖关系。
>
>  **持久层(DAO)**
>
>  持久层,有时候也称为是数据访问层,其功能主要是负责数据库的访问,可以访问数据库系统

### 12.2、特点

> 1、上⼀层可以调⽤下⼀层 但是 下⼀层不能调⽤上⼀层
>
> 2、不可以隔层调⽤

![在这里插入图片描述](https://img-blog.csdnimg.cn/4b4814e9b2d54fbb9cab16991b7b31ff.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUElLYXBpa2FhYWE=,size_20,color_FFFFFF,t_70,g_se,x_16)

JavaWeb——JDBC(附案例) 目录1. 定义2. JDBC体系结构3. JDBC的使用 1. 定义 Java DataBase Connectivity是一个独立于特定数据库的管理系统,通用的SQL数据库存取和操作的公共接口。 定义了一组标准,为访问不同数据库提供了同一途径。 2. JDBC体系结构 JDBC接口包括两个层面: 面向应用的API,供程序员调用 面向数据库的API,供厂商开发数据库的驱动程序 API: JDBC API 提供者:Java官方 内容:供开发者调用的接口 java.sql和javax.sql 类:Dri 阅读详情

相关推荐

java的JDBC简单案例

java的JDBC简单案例 Driver接口 Driver是每个驱动程序类必须实现的接口,专门提供给数据厂商使用 在编写JDBC程序时,必须要把所使用的数据库驱动程序和类库 (指MySQL的驱动JAR包)加载到项目的classpath中。 jar包下载地 解压后添加到项目中 根据代码提示加载Driver的包 Class.forName("com.mysql.jdbc.Driver"); Connection接口 Connection接口用于创建数据库的连接,只有获得该连接对象后才可以访问

飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘飘 2982

JDBC实现java数据库连接(附完整例子+超详细注解)

注重版权,转载请注明原作者和原文链接 作者:码农BookSea 原文链接:https://editor.youkuaiyun.com/md?articleId=105959128 本人刚写博客不久,是个新人,望大家能给予一些鼓励。 您的一个赞或者是评论区的一句话都将是对我最大的激励。 简单一句话先来了解下JDBC: JDBC(Java Data Base Connectivity,java数据库连接...

BookSea的博客 1万+

CentOS 7下kkFileView 4.4.0离线部署全攻略(含LibreOffice 7.5配置避坑指南)

本文详细介绍了在CentOS 7环境下离线部署kkFileView 4.4.0的全流程,包括LibreOffice 7.5的配置避坑指南、中文字体解决方案以及企业级运维实践。通过本指南,用户可以在内网环境中快速搭建稳定可靠的文档在线预览服务,提升办公效率。

weixin_28481133的博客 288

JDBC详细全解(示例超多)

JDBC ( Java DataBaseConnectivity java数据库连接)是一种用于执行SQL语句的Java API,本文详细讲解JDBC知识。

qq_54353206的博客 2万+

视网膜血管分割数据集(DRIVE数据集,STARE数据集,REFUGE数据集,CHASE_DB1数据集,DiaRetDB1数据集)

在医学图像处理领域,视网膜图像分析对于眼部疾病的早期诊断与治疗具有举足轻重的意义。随着人工智能技术的蓬勃发展,尤其是深度学习算法在图像分割任务中的广泛应用,高质量的视网膜图像数据集成为推动该领域研究进展的关键要素。这些数据集不仅是训练和优化算法模型的基石,更是衡量算法性能优劣的重要依据。本文聚焦于视网膜图像分割领域,详细介绍 DRIVE、STARE、REFUGE、CHASE_DB1 以及 DiaRetDB1 这几个具有代表性的数据集。

weixin_43518285的博客 2270

基于Transformers库的BERT模型:一个文本情感分类的实例解析

简介 本文来讲述BERT应用的一个例子,采用预训练好的BERT模型来进行演示。BERT的库来源于Transformers,这是一个由PyTorch编写的库,其集成了多个NLP领域SOTA的模型,比如bert、gpt-2、transformer xl等,并且可以自由选择已经预训练好的模型参数,我们可以基于这些参数进行进一步的训练调试。 Part 1: 利用BERT基于特征的方式进行建模 1、任务与数...

蓝天白云梦的csdn博客 2万+

11.JDBC实例

JDBC实例1、建表语句:2、建立工程3、JDBC操作的对象(1)、Connection:数据库链接对象(2)、Statement:sql语句执行对象(3)、ResultSet:返回结果集对象(4)、PreparedStatement:预处理sql执行对象,是Statement的子接口预处理的优点:4、DAO开发模式:转注入数据访问层(1)、数据库链接工具类:Dbutils——负责链接数据库和关闭资源(2)、创建和数据库表对应的javabean对象(3)、创建接口,提供访问数据的方法(4)、创建接口的实现类

weixin_46048220的博客 1529

ANSYS APDL齿轮建模实战:从渐开线方程到完整3D模型的保姆级教程

本文详细介绍了使用ANSYS APDL进行齿轮建模的全过程,从渐开线方程的数学基础到完整3D模型的创建。通过参数化命令流实现高精度齿轮建模,特别适合机械设计和仿真分析需求。教程包含关键参数计算、APDL环境配置、单齿齿廓建模以及全齿轮阵列复制等实用技巧,帮助工程师快速掌握ANSYS APDL在齿轮建模中的应用。

lg888的博客 445

数据库概论之 JDBC 编程的常见案例

对于 JDBC 编程的基本案例

m0_53117341的博客 825

避开命令行!在VMware vCenter 8.0图形化界面里搞定SSL证书续期全流程

本文详细介绍了在VMware vCenter 8.0图形化界面中完成SSL证书续期的全流程,包括计算机SSL证书、VMCA根证书和STS证书的管理。通过可视化操作,管理员无需使用命令行即可高效处理证书问题,确保vSphere环境的稳定运行。文章还提供了证书监控与预警配置的实用技巧,帮助用户提前规避证书过期风险。

weixin_27051161的博客 280

nvlddmkm事件ID14报错排查全指南:从找不到描述到显卡驱动崩溃

系统日志中的“无法找到描述”往往让人一头雾水,但这类提示其实隐藏着驱动故障的关键线索。Windows事件查看器通过事件源和ID记录系统异常,其中显卡驱动相关的内核模式驱动组件一旦超时失败,就会触发TDR机制,产生13、14、153等不同事件ID。理解这些ID的含义,比纠结“找不到描述”本身更重要。对于频繁出现的驱动崩溃问题,可以从日志频率和发生场景判断方向,再通过安全模式下彻底清理驱动、关闭冲突软件、检查供电和温度等步骤逐层定位。无论是游戏满载黑屏,还是睡眠唤醒后闪退,掌握NVIDIA驱动日志的解读逻辑,都

weixin_30545945的博客 401

JDBC案例

【代码】JDBC案例。

meini32的博客 699

从零到一:手把手教你用STM32和WiFi打造智能温室大棚的物联网核心

本文详细介绍了如何利用STM32单片机和WiFi技术从零构建智能温室大棚的物联网核心系统。内容涵盖硬件选型、传感器集成、低功耗WiFi通信、自动控制逻辑及OLED显示,提供实际部署中的优化技巧和故障排查方案,帮助开发者打造稳定可靠的农业自动化解决方案。

c7d8e的博客 178

JDBC的使用及案例

1. JDBC基本操作 1.1. JDBC概述 JDBC(Java Data Base Connectivity)Java连接数据库 是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问 它由一组用Java语言编写的类和接口组成 有了JDBC,程序员只需用JDBC API写一个程序,就可以访问所有数据库 SUN公司时规范制定者,制定了JDBC规范 DriverManager类:管理不同的JDBC驱动 Connection接口 Statement接口和PreparedStatemen

小小前端转型中 2540

面向口齿不清者的语音识别新突破:用大模型拯救“听不懂”的声音

面向构音障碍患者的语音识别新突破:大语言模型显著提升识别准确率 国际语音研究团队在Interspeech 2025发表最新成果,通过将大语言模型(LLM)融入语音识别系统,显著改善了对构音障碍(dysarthria)患者语音的识别效果。研究表明: 传统语音识别(如CTC模型)对构音障碍语音的词错误率(WER)高达50-54%,Whisper模型降至38-40%。 引入LLM解码器后,BART模型将WER降至30-32%,而Whisper-Vicuna组合更将WER降低至21-26%。 关键优势:LLM能有效

帅小柏的博客 270

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

最全的jdbc笔记

JDBC概述 数据的持久化 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。 JDBC的理解 JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API) 简单理解为:JDBC,是SUN提供的一套 API,使用这套API可以实现对具体数据库的操作(获取连接、关闭连接、DML、DDL、DCL) JDBC的好处 面向应用的API:Java API,抽象接口,供应用程序开发人员使用(

weixin_43146162的博客 258

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

day01JDBC课堂笔记

该笔记是黑马JDBC课程笔记,仅为了方便学习上传,请勿商用。 文章目录1. 今日内容2. JDBC:1. 概念:2. 快速入门:3. 详解各个对象:1. DriverManager:驱动管理对象2. Connection:数据库连接对象3. Statement:执行sql的对象4. ResultSet:结果集对象,封装查询结果5. PreparedStatement:执行sql的对象3.抽取JDB...

H.千面的博客 638

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

尚硅谷JDBC学习笔记

尚硅谷JDBC学习笔记 文章目录尚硅谷JDBC学习笔记写在前面1. 通过Driver接口获取数据库连接2. 通过DriverManager获取数据库连接3. 通过Statement执行更新操作4. 通过ResultSet执行查询操作5. PreparedStatement6. 利用反射及JDBC元数据编写通用的查询7. DAO设计模式8. JDBC的元数据9. JDBC获取插入记录的主键值10. ...

李英俊小朋友 2689

JDBC学习笔记02【ResultSet类详解、JDBC登录案例练习、PreparedStatement类详解】

ResultSet类详解、JDBC登录案例练习、PreparedStatement类详解

upward 1239

JDBC笔记详解

文章目录一、前言二、JDBC本质理解1.什么是JDBC?2.JDBC的本质是什么?三、使用代码模拟JDBC本质四、JDBC编程六步骤1.注册驱动2.获取连接3.获取数据库操作对象4.执行sql语句5.处理查询结果集(第六章讲解)6.释放资源代码展示五、从配置文件中读取连接数据库信息六、处理查询结果集七、用户登录案例八、SQL注入现象及解决1.SQL注入现象2.导致SQL注入的根本原因3.解决SQL注入九、Statement和PreparedStatement对比十、JDBC事务自动提交机制十一、账户转账演示

保持学习 581

JDBC超详细笔记

本文主要分享了有关JDBC的内容包括:JDBC的概述(思想和环境的搭建)、JDBC的核心6步、ResultSet结果集、SQL注入问题、Statement接口、PreparedStatement接口(案例)、登录案例、封装工具类、ORM、DAO、日期类型的封装、JDBC事务、连接池(Druid德鲁伊连接池)以及若干案例;

Willing卡卡的博客 2259

JDBC笔记

JDBC(java Database Connectivity)是一个独立于特定数据库管理系统,通用的SQL数据库存取和操作的公共接口(一组API)定义了用来访问数据库的标准java类库使用这个类库可以以一种标准的方法,方便的访问数据库资源。JDBC的目标是使java程序员使用JDBC可以连接任何提供了JDBC驱动程序的数据库系统,这样可以是程序员无需对特定的数据库系统的特点有过多的了解加快开发过程。(Java 数据库连接)使用Java代码操作数据库JDBC其实就是一套操作数据库的规范(接口)

ke67855523的博客 1126

JDBC学习笔记

JDBC学习

2301_80073794的博客 973

JDBC入门介绍(包含简单案例)

JDBC:Java DataBase Connectivity,就是使用Java语言操作关系型数据库的一套API(规范)。本质:sun公司官方定义的一套操作所有关系数据库的规范,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码时驱动jar包中的实现类。

2301_77631508的博客 1382

JavaWeb笔记:JDBC总结

JavaWeb笔记:JDBC总结 目录 JavaWeb笔记:JDBC总结 一、JDBC概述 二、开发一个JDBC程序(重要) 三、JDBC常用的类和接口详解 1、java.sql.Drivermanager类 : 创建连接 2、java.sql.Connection接口:一个连接 3、java.sql.Statement接口: 操作sql语句,并返回相应结果的对象(小货车) 4、...

岁月求索 1071
上一篇: MySQL高级应用(触发器、索引、锁机制、存储引擎等等)
下一篇: (Tomcat服务器的安装与搭建)Web服务器的理解与应用
皮卡丘不断更
博客等级 码龄5年 111粉丝 141原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮卡丘不断更

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值