蓝旭后端第七次培训课 JDBC

2023-11-05 05:50

本文主要是介绍蓝旭后端第七次培训课 JDBC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、什么是JDBC

二、Hello JDBC

1.为项目导入mysql-jdbc依赖的jar包

2.初始化驱动

3.建立与数据库的连接

4.创建statement

5.执行SQL语句

6.关闭连接

小插曲:Java7语法糖-------try-with-resources

三、查询

四、预编译Statement

五、execute方法,executeUpdate方法与executeQuery方法

六、特殊操作

七、事务

八、ORM

九、DAO


一、什么是JDBC

JDBC的全称是Java数据库连接(Java Database Connect),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系数据库,并使用SQL语句来完成对数据库中数据的查询、更新和删除等操作。

二、Hello JDBC

1.为项目导入mysql-jdbc依赖的jar包

访问MySQL数据库需要用到第三方的类,这些第三方的类,都被压缩在一个叫做Jar的文件里。为了代码能够使用第三方的类,需要为项目导入mysql的专用Jar包。       

我们使用的是mysql-connector-java-8.0.11-bin.jar的驱动,当然也可以使用mysql-connector-java-5.1.46-bin.jar的驱动,但是在加载驱动的时候以及填写链接的时候会有些不同,后续会介绍

  • 通常都会把项目用到的jar包统一放在项目的lib目录下

类似于这样:

注意:lib文件夹要放到web-inf文件下,不然可能导致导入失败

当然不要忘记在项目结构中把这个lib添加为项目依赖,这样才算是导入了jar包

2.初始化驱动

通过Class.forName(驱动类的类路径)来进行初始化驱动

Class.forName:返回与给定的字符串名称相关联接口的Class对象。

    public static void main(String[] args) {try {// 初始化驱动Class.forName("com.mysql.cj.jdbc.Driver");System.out.println("初始化驱动加载成功");}catch (ClassNotFoundException e) {e.printStackTrace();}}

或者使用DriverManager.register(驱动类的对象)进行初始化驱动

DriverManager:管理一组 JDBC 驱动程序的基本服务。

作用:用于管理和注册驱动,建立与数据库的连接

    public static void main(String[] args) {try {// 初始化驱动DriverManager.registerDriver(new Driver());System.out.println("初始化驱动加载成功");}catch (SQLException e) {e.printStackTrace();}}

注意:在 mysql-connector-java-8.0.11-bin.jar中,驱动类的类路径为com.mysql.cj.jdbc.Driver,而在 mysql-connector-java-5.0.8-bin.jar中,驱动类的类路径为com.mysql.jdbc.Driver

3.建立与数据库的连接

  • 协议连接格式

协议名:子协议://IP地址或服务器名:端口号/数据库名?参数=参数值

例如:jdbc:mysql://localhost:3306/jdbc?characterEncoding=utf8&serverTimezone=GMT&useSSL=false

参数characterEncoding可以防止乱码出现,通常设置为utf8

参数serverTimezone用来设置时区,可以为GMT,也可以是中国标准时间Asia/Shanghai

参数useSSL用来设置是否使用ssl连接,目前学习jdbc不建议建立SSL连接,所以可设置为false。

  • 什么是Connection?

Connection是一个接口,用于操作数据库。具体实现有各大厂商来做。

public static void main(String[] args) {try {Class.forName("com.mysql.cj.jdbc.Driver");// 建立与数据库的Connection连接// 这里需要提供:// 数据库所处于的ip:127.0.0.1 或者说localhost (本机)// 数据库的端口号: 3306 (mysql专用端口号)// 数据库名称: jdbc(根据你自己的数据名称来设置)// 编码方式: UTF-8// 时区: GMT (8版本的驱动要添加,5版本可以不写)// 是否使用ssl连接: false (8版本的驱动要添加,5版本可以不写)// 账号: root(根据你自己的用户名填写)// 密码: root(根据你自己的密码填写)String url = "jdbc:mysql://localhost:3306/jdbc?characterEncoding=utf8&serverTimezone=GMT&useSSL=false";// String url = "jdbc:mysql://localhost:3306/jdbc?characterEncoding=utf8"; 这个是5版本的驱动使用的连接String username = "root";String password = "root";Connection connection = DriverManager.getConnection(url, username, password);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}

 

4.创建statement

  • statement的作用是什么?

statement用于执行SQL语句的

  • 使用statement进行增删改查

首先是JDBCUtils类,封装了注册驱动,获取连接,关闭连接等方法,方便调用。

package com.jdbc.util;import java.sql.*;public class JDBCUtils {private final String url = "jdbc:mysql://localhost:3306/jdbc?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";private final String username = "root";private final String password = "root";private volatile static JDBCUtils jdbcUtils = null;/*初始化驱动*/static {try {Class.forName("com.mysql.cj.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}private Connection getMysqlConnection(JDBCUtils jdbcUtils){Connection connection = null;try {connection = DriverManager.getConnection(jdbcUtils.url,jdbcUtils.username,jdbcUtils.password);} catch (SQLException e) {e.printStackTrace();}return connection;}/*** 获取MySQL数据连接对象(略读,不要求掌握)* @return Connection连接对象*/public static Connection getMysqlConnection(){return getInstance().getMysqlConnection(getInstance());}/*** 获取实例对象(略读,不要求掌握)* @return JDBCUtils对象*/private static JDBCUtils getInstance() {if (null == jdbcUtils){synchronized (JDBCUtils.class){if (null == jdbcUtils){jdbcUtils = new JDBCUtils();}}}return jdbcUtils;}/*** 关闭连接* @param connection*/public static void close(Connection connection){if (connection != null) {try {connection.close();System.out.println("连接已关闭");} catch (SQLException e) {System.out.println("连接关闭失败");e.printStackTrace();}}}/*** 关闭连接* @param connection* @param statement* @param resultSet*/public static void close(Connection connection, Statement statement, ResultSet resultSet){if (resultSet != null) {try {resultSet.close();System.out.println("resultSet关闭成功");} catch (SQLException e) {System.out.println("resultSet关闭失败");e.printStackTrace();}}if (statement != null) {try {statement.close();System.out.println("statement关闭成功");} catch (SQLException e) {System.out.println("statement关闭失败");e.printStackTrace();}}if (connection != null) {try {connection.close();System.out.println("连接已关闭");} catch (SQLException e) {System.out.println("连接关闭失败");e.printStackTrace();}}}
}

其次是测试类

package com.jdbc.test;import com.jdbc.util.JDBCUtils;import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;public class TestStatement {public static void main(String[] args) {// 获取连接Connection mysqlConnection = JDBCUtils.getMysqlConnection();// 创建statement对象Statement statement = null;String sql = null;boolean execute = false;try {statement = mysqlConnection.createStatement();System.out.println("statement创建成功");} catch (SQLException e) {System.out.println("statement创建失败");e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection,statement,null);}}
}

5.执行SQL语句

package com.jdbc.test;import com.jdbc.util.JDBCUtils;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class TestStatement {public static void main(String[] args) {// 获取连接Connection mysqlConnection = JDBCUtils.getMysqlConnection();// 创建statement对象Statement statement = null;String sql = null;boolean execute = false;try {statement = mysqlConnection.createStatement();System.out.println("statement创建成功");// 查sql = "select * from tb_user where `username` = 'Jack'";execute = statement.execute(sql);// 通过getResultSet方法可以获取返回结果集ResultSet resultSet = statement.getResultSet();while (resultSet.next()){System.out.println(resultSet.getInt(1));}System.out.println("select语句的execute = " + execute);// 增sql = "insert into tb_user(`username`,`password`,`gender`) values('Tom','123456',1)";execute = statement.execute(sql);System.out.println("insert语句的execute = " + execute);// 改sql = "update tb_user set `password` = '12345678' where `username` = 'Tom'";execute = statement.execute(sql);System.out.println("update语句的execute = " + execute);// 删sql = "delete from tb_user where `username` = 'Tom'";execute = statement.execute(sql);System.out.println("delete语句的execute = " + execute);// 方法statement.execute(sql)的返回值,如果执行的是select语句,且有返回集,则为true,其他情况下均为false。该返回值并不表示SQL语句是否执行成功} catch (SQLException e) {System.out.println("sql执行异常");e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection,statement,null);}}
}

6.关闭连接

/*以下是来自JDBCUtils中的关闭方法*//*** 关闭连接* @param connection*/public static void close(Connection connection){if (connection != null) {try {connection.close();System.out.println("连接已关闭");} catch (SQLException e) {System.out.println("连接关闭失败");e.printStackTrace();}}}/*** 关闭连接* @param connection* @param statement* @param resultSet*/public static void close(Connection connection, Statement statement, ResultSet resultSet){if (resultSet != null) {try {resultSet.close();System.out.println("resultSet关闭成功");} catch (SQLException e) {System.out.println("resultSet关闭失败");e.printStackTrace();}}if (statement != null) {try {statement.close();System.out.println("statement关闭成功");} catch (SQLException e) {System.out.println("statement关闭失败");e.printStackTrace();}}if (connection != null) {try {connection.close();System.out.println("连接已关闭");} catch (SQLException e) {System.out.println("连接关闭失败");e.printStackTrace();}}}
}

关闭顺序为:先开启的后关闭,即关闭顺序为:resultSet>statement>connection

总结:

    jdbc的整个执行过程为:1.加载驱动 2.获取连接 3.创建语句 4.执行SQL 5.关闭连接

小插曲:Java7语法糖-------try-with-resources

语法糖(Syntactic sugar),也译为糖衣语法,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。

在 Java 7 以及后续版本中,支持 try-with-resources,任何实现 java.lang.AutoCloseable 接口的类,包括 java.io.Closeable 的实现类,都可以通过 try-with-resources 来关闭。

原来关闭资源的代码:

InputStream inputStream = null;
try {inputStream = new FileInputStream("/my/file");// ...
} catch (Exception e) {e.printStackTrace();
} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}
}

使用语法糖后的代码:

try (InputStream inputStream = new FileInputStream("/my/file")) {// ...
} catch (Exception e) {e.printStackTrace();
}

 两个代码虽然长得不一样,但是对于Java虚拟机jvm来说起到的效果是相同的。验证:两段代码的字节码文件分别反编译,你会发现结果是一样的。

通过 JDBC 查询数据库时,会依次创建 ConnectionStatementResultSet,并且这三个资源都需要关闭,那么可以这样写:

try (Connection connection = DriverManager.getConnection(url, user, password);Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery("SELECT ...")) {// ...
} catch (Exception e) {// ...
}

多个 resources 的关闭顺序

如果在 try 中定义了多个 resources,那么它们关闭的顺序和创建的顺序是相反的。上面的例子中,依次创建了 ConnectionStatmentResultSet 对象,最终关闭时会依次关闭 ResultSetStatmentConnection,所以不用担心 Connection 会先 close。

 

三、查询

  • 查询使用的方法为:executeQuery(sql语句),返回值为ResultSet类型的对象
  • ResultSet几个必会方法:
  1. resultSet.next() 返回值为布尔类型,表示是否有下一个元素,true表示有,false表示没有

  2. resultSet.getInt(数据库字段名或者字段的位置) 返回值为int类型,表示获取查询结果集中,当前元组指定字段的数据,并且转换为int类型

同理,resultSet.getString(数据库字段名或者字段的位置) resultSet.getDouble(数据库字段名或者字段的位置) 等都是获取指定字段的数据,并且进行对应数据类型的转换

这里字段的位置是从1开始计算的

package com.jdbc.test;import com.jdbc.util.JDBCUtils;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class TestQuery {public static void main(String[] args) {Connection mysqlConnection = JDBCUtils.getMysqlConnection();Statement statement = null;ResultSet resultSet = null;try {statement = mysqlConnection.createStatement();String sql = "select * from tb_user where `username` = 'Susan'";resultSet = statement.executeQuery(sql);while (resultSet.next()){int id = resultSet.getInt("id");String username = resultSet.getString(2);String password = resultSet.getString("password");int gender = resultSet.getInt(4);System.out.println("id = " + id);System.out.println("username = " + username);System.out.println("password = " + password);System.out.println("gender = " + gender);}} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection,statement,resultSet);}}
}

四、预编译Statement

  • 什么是PreparedStatement?

和 Statement一样,PreparedStatement也是用来执行sql语句的

  • PreparedStatement和Statement有什么区别?

  1. 需要根据sql语句创建PreparedStatement,而statement不需要

  2. PreparedStatement可以通过设置参数,指定相应的值,而不是Statement那样使用字符串拼接(注意,这里参数的位置是从1开始计算的

  3. PreparedStatement有预编译机制,而Statement没有

  • 既然有Statement,为什么还要有PreparedStatement呢,或者说PreparedStatement的优点是什么呢?
  1. PreparedStatement的参数设置相比于Statement来说更加容易维护,可读性更高,不容易犯错

  2. PreparedStatement的预编译机制,性能比Statement更快

  3. PreparedStatement可以防止SQL注入式攻击

package com.jdbc.test;import com.jdbc.entity.User;
import com.jdbc.util.JDBCUtils;import java.sql.*;public class TestPrepareStatement {/*** preparedStatement的参数设置* @param user*/public void userRegister1(User user){Connection mysqlConnection = JDBCUtils.getMysqlConnection();String sqlOne = "insert into tb_user(`username`,`password`,`gender`) values("+user.getUsername()+","+user.getPassword()+","+user.getGender()+")";String sqlTwo = "insert into tb_user(`username`,`password`,`gender`) values(?,?,?)";try (Statement statement = mysqlConnection.createStatement();PreparedStatement prepareStatement = mysqlConnection.prepareStatement(sqlTwo);){statement.execute(sqlOne);// 参数设置是从1开始的,不是从0开始的prepareStatement.setString(1,user.getUsername());prepareStatement.setString(2,user.getPassword());prepareStatement.setInt(3,user.getGender());prepareStatement.execute();} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection);}}/*** preparedStatement的预编译机制* @param user*/public void userRegister2(User user){Connection mysqlConnection = JDBCUtils.getMysqlConnection();String sqlOne = "insert into tb_user(`username`,`password`,`gender`) values("+"\""+user.getUsername()+"\""+","+user.getPassword()+","+user.getGender()+")";String sqlTwo = "insert into tb_user(`username`,`password`,`gender`) values(?,?,?)";try (Statement statement = mysqlConnection.createStatement();PreparedStatement prepareStatement = mysqlConnection.prepareStatement(sqlTwo);){// 插入十个用户,statement需要执行10次sql语句,需要10都把SQL语句传输到数据库端,数据库每次都要对SQL语句进行编译的执行for (int i = 0; i < 10; i++) {statement.execute(sqlOne);}// 插入十个用户,PreparedStatement 执行10次,只需要1次把SQL语句传输到数据库端// 数据库对带?的SQL进行预编译// 每次执行,只需要传输参数到数据库端// 1. 网络传输量比Statement更小// 2. 数据库不需要再进行编译,响应更快for (int i = 0; i < 10; i++) {prepareStatement.setString(1,user.getUsername());prepareStatement.setString(2,user.getPassword());prepareStatement.setInt(3,user.getGender());prepareStatement.execute();}} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection);}}/*** 防止SQL注入* @param user*/public void userRegister3(User user){Connection mysqlConnection = JDBCUtils.getMysqlConnection();String sqlOne = "select * from tb_user where `username` = "+user.getUsername();String sqlTwo = "select * from tb_user where `username` = ?";ResultSet resultSet = null;try (
//                Statement statement = mysqlConnection.createStatement();PreparedStatement prepareStatement = mysqlConnection.prepareStatement(sqlTwo);){
//            ResultSet resultSet = statement.executeQuery(sqlOne);// PreparedStatement会对SQL进行了预编译,在第一次执行SQL前数据库会进行分析、编译和优化,同时执行计划同样会被缓存起来,它允许数据库做参数化查询。// 在使用参数化查询的情况下,数据库不会将参数的内容视为SQL执行的一部分,而是作为一个字段的属性值来处理,这样就算参数中包含破环性语句(or ‘1=1’)也不会被执行。// preparedStatement执行的SQL语句:select * from tb_user where `username` = "'Jack' or 1=1"prepareStatement.setString(1,user.getUsername());resultSet = prepareStatement.executeQuery();while (resultSet.next()){user.setId(resultSet.getInt("id"));user.setUsername(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));user.setGender(resultSet.getInt("gender"));System.out.println(user);}} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection,null,resultSet);}}public static void main(String[] args) {User user = new User();user.setUsername("Jack");user.setPassword("123");user.setGender(1);TestPrepareStatement testPrepareStatement = new TestPrepareStatement();// 优点1演示
//        testPrepareStatement.userRegister1(user);// 优点2演示
//        testPrepareStatement.userRegister2(user);// 优点3演示// statement会把数据库中所有的信息查出来,而preparedStatement返回集为空
//        user.setUsername("'Jack' or 1=1");
//        testPrepareStatement.userRegister3(user);}
}

 

五、execute方法,executeUpdate方法与executeQuery方法

  • execute方法可以执行任何SQL语句,返回类型为布尔类型,若有结果集则为true,否则为false
  • executeUpdate方法只可以执行DML数据操纵语言和DDL数据定义语言,返回受影响的行数
  • executeQuery方法只可以执行DQL数据查询语言,返回值为ResultSet返回结果集

因此建议大家在使用DML数据操纵语言的时候,使用executeUpdate方法,可以根据返回值判断该语句的执行情况

六、特殊操作

  • 获取自增ID

一般情况下,MySQL数据库每张表都有一个自增ID,作为这张表的主键。向数据库插入一条数据后,MySQL会自动计算并且为ID字段赋值,接下来的操作就是介绍如何获取这个自增的ID

package com.jdbc.test;import com.jdbc.entity.User;
import com.jdbc.util.JDBCUtils;import java.sql.*;public class TestSpecialOperation {public void userRegister(User user){Connection mysqlConnection = JDBCUtils.getMysqlConnection();PreparedStatement prepareStatement = null;ResultSet generatedKeys = null;String sql = "insert into tb_user(`username`,`password`,`gender`) values(?,?,?)";try {// 要记得加一个参数Statement.RETURN_GENERATED_KEYS,才可以返回自增主键prepareStatement = mysqlConnection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);prepareStatement.setString(1,user.getUsername());prepareStatement.setString(2,user.getPassword());prepareStatement.setInt(3,user.getGender());prepareStatement.execute();// 获取自增长idgeneratedKeys = prepareStatement.getGeneratedKeys();if (generatedKeys.next()){System.out.println("generatedKeys = " + generatedKeys.getInt(1));}} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection,prepareStatement,generatedKeys);}}public static void main(String[] args) {User user = new User();user.setUsername("Jack");user.setPassword("123");user.setGender(1);TestSpecialOperation testSpecialOperation =new TestSpecialOperation();testSpecialOperation.userRegister(user);}
}

七、事务

  • 什么是事务?

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

原子性: 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性: 在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

隔离性: 数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

持久性: 事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

  • 为什么要使用事务?

假设这样一种场景,银行汇款。A向B汇款100元(假设A账户余额大于100元),那么要实现这样的功能,需要进行的操作有:

1.A账户余额减去100元

2.B账户余额增加100元

但是,如果步骤1执行成功,但是步骤2执行出现问题,这个时候就会出现A账户减少100但是B没有收到。这个问题是很严重的,直接导致损害到了用户的利益。

因此,为了防止出现这样的情况,我就要用到事务。

上述情况,如果使用了事务,在事务中出现错误(指的是抛出运行时异常)的时候,整个执行操作都会被自动回滚(或者也可以自己调用rollback方法进行回滚)。这样的话,就保证了用户的利益。

接下来介绍一下,在jdbc中如何操作事务

package com.jdbc.test;import com.jdbc.entity.User;
import com.jdbc.util.JDBCUtils;import java.sql.*;public class TestTransaction {public void userRegister(User user){Connection mysqlConnection = JDBCUtils.getMysqlConnection();PreparedStatement prepareStatement = null;ResultSet generatedKeys = null;String sql1 = "insert into tb_user(`username`,`password`,`gender`) values(?,?,?)";String sql2 = "update tb_user set `password` = ? where `id` = ?";try {// 设置取消自动提交mysqlConnection.setAutoCommit(false);prepareStatement = mysqlConnection.prepareStatement(sql1, Statement.RETURN_GENERATED_KEYS);prepareStatement.setString(1,user.getUsername());prepareStatement.setString(2,user.getPassword());prepareStatement.setInt(3,user.getGender());int num = prepareStatement.executeUpdate();if (num == 1){generatedKeys = prepareStatement.getGeneratedKeys();if (generatedKeys.next()){int id = generatedKeys.getInt(1);prepareStatement = mysqlConnection.prepareStatement(sql2);prepareStatement.setString(1,"1234");prepareStatement.setInt(2,id+1);int i = prepareStatement.executeUpdate();if (i == 1){System.out.println("更新成功");}else {
//                        // 抛出运行时异常,自动回滚
//                        throw new RuntimeException("更新失败");// 手动调用rollback方法回滚mysqlConnection.rollback();System.out.println("事务回滚");}}}else {// 抛出运行时异常,自动回滚throw new RuntimeException("用户注册失败");
//                // 手动调用rollback方法回滚
//                mysqlConnection.rollback();
//                System.out.println("事务回滚");}// 手动提交mysqlConnection.commit();//mysqlConnection.setAutoCommit(false)和mysqlConnection.commit(),之间的所有操作都会被归到一个事务中} catch (SQLException e) {e.printStackTrace();}finally {JDBCUtils.close(mysqlConnection,prepareStatement,generatedKeys);}}public static void main(String[] args) {User user = new User();user.setUsername("Jack");user.setPassword("123");user.setGender(1);TestTransaction testTransaction = new TestTransaction();testTransaction.userRegister(user);}
}

八、ORM

  • 什么是ORM

ORM(Object-relational mapping),中文翻译为对象关系映射,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

简单说,一个对象,对应数据库里的一条记录

  • 表与类的关系

一张表的表结构和一个实体类的属性一一对应

一张表的一个元组对应一个实体类的实例对象

九、DAO

DAO(Data Access Object)是一个数据访问接口,数据访问:顾名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。

简单来说,就是把和数据库打交道的逻辑,都放到DAO层,进行功能的聚合。不向外暴露与数据库交互的逻辑处理,也就是实现功能解耦。

 

这篇关于蓝旭后端第七次培训课 JDBC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/347837

相关文章

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

内卷时代无人机培训机构如何做大做强

在当今社会,随着科技的飞速发展,“内卷”一词频繁被提及,反映了各行业竞争日益激烈的现象。对于无人机培训行业而言,如何在这样的时代背景下脱颖而出,实现做大做强的目标,成为每个培训机构必须深思的问题。以下是从八个关键方面提出的策略,旨在帮助无人机培训机构在内卷时代中稳步前行。 1. 精准定位市场需求 深入研究市场:通过市场调研,了解无人机行业的最新趋势、政策导向及未来发展方向。 明确目标

Hibernate框架中,使用JDBC语法

/*** 调用存储过程* * @param PRONAME* @return*/public CallableStatement citePro(final String PRONAME){Session session = getCurrentSession();CallableStatement pro = session.doReturningWork(new ReturningWork<C

网络安全运维培训一般多少钱

在当今数字化时代,网络安全已成为企业和个人关注的焦点。而网络安全运维作为保障网络安全的重要环节,其专业人才的需求也日益增长。许多人都对网络安全运维培训感兴趣,那么,网络安全运维培训一般多少钱呢?   一、影响网络安全运维培训价格的因素   1. 培训内容的深度和广度   不同的网络安全运维培训课程涵盖的内容有所不同。一些基础的培训课程可能主要涉及网络安全基础知识、常见安全工具的使用等,价

培训第九周(部署k8s基础环境)

一、前期系统环境准备 1、关闭防火墙与selinux  [root@k8s-master ~]# systemctl stop firewalld[root@k8s-master ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.servi

jdbc连接数据库使用sid和service_name的区别 ?

问题描述: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor The Connection descriptor used by the client was: 10.12.162.84:1521:xxxx  oracle数据的tnsnames.ora中配置的是:SERVICE

超全泛微E10-eBuilder功能培训视频教程(精华)含源码 火!!!

引言  在当今数字化转型的浪潮中,掌握强大而高效的工具将是职业发展的关键。泛微E10的低代码平台e-Builder不仅是一个功能强大的数字化运营管理平台,还为希望在工作中提升效率和技术技能的从业者提供了丰富的学习资源。在这篇文章中,我们将详细介绍泛微E10-eBuilder功能培训视频教程的内容,帮助你了解这款平台如何帮助你在数字化转型和职业提升中领先一步。 一、课程目录介绍 本次培训视频

Java项目中,配置打印 JDBC 日志的几种方法

在 IDEA 项目中,如果你想打印 JDBC 日志,可以通过配置日志框架(如 Logback 或 Log4j)来实现。Spring Boot 使用的默认日志框架是 Logback,你可以通过在 application.yml 文件中配置日志级别来打印 JDBC 日志。 方法 1: 使用 application.yml 配置 JDBC 日志 logging:level:# 显示 SQL 语句co

知名AIGC人工智能专家培训讲师唐兴通谈AI大模型数字化转型数字新媒体营销与数字化销售

在过去的二十年里,中国企业在数字营销领域经历了一场惊心动魄的变革。从最初的懵懂无知到如今的游刃有余,这一路走来,既有模仿学习的艰辛,也有创新突破的喜悦。然而,站在人工智能时代的门槛上,我们不禁要问:下一个十年,中国企业将如何在数字营销的浪潮中乘风破浪? 一、从跟风到精通:中国数字营销的进化史 回顾过去,中国企业在数字营销领域的发展可谓是一部"跟风学习"的编年史。从最初的搜索引擎营销(SEM),

基于shard-jdbc中间件,实现数据分库分表

一、水平分割 1、水平分库 1)、概念: 以字段为依据,按照一定策略,将一个库中的数据拆分到多个库中。 2)、结果 每个库的结构都一样;数据都不一样; 所有库的并集是全量数据; 2、水平分表 1)、概念 以字段为依据,按照一定策略,将一个表中的数据拆分到多个表中。 2)、结果 每个表的结构都一样;数据都不一样; 所有表的并集是全量数据; 二、Shard-jdbc 中间件 1、架构图 2、特点