CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。
我们每天将都会精选CSDN站内技术文章供大家学习,帮助大家系统化学习IT技术。
一、目录JDBC是什么?JDBC英文名为:Java Data Base Connectivity(Java数据库连接),官方解释它是Java编程语言和广泛的数据库之间独立于数据库的连接标准的Java API,根本上说JDBC是一种规范,它提供的接口,一套完整的,允许便捷式访问底层数据库。可以用JAVA来写不同类型的可执行文件:JAVA应用程序、JAVA Applets、Java Servlet、JSP等,不同的可执行文件都能通过JDBC访问数据库,又兼备存储的优势。简单说它就是JAVA与数据库的连接的桥梁或者插件,用JAVA代码就能操作数据库的增删改查、存储过程、事务等。
JDBC有什么用?我们用JAVA就能连接到数据库;创建SQL或者MYSQL语句;执行SQL或MYSQL的查询数据库;查看和修改结果记录。
我们思考一下?数据库是由不同生产产商决定的,例如Mysql、Oracle、SQL Server,而如果JAVA JDK不可能说提供对不同数据库的实现吧?还有,JAVA具备天生跨平台的优势,它就提供了JDBC的接口API,具体的实现由不同的生产产商决定。这样,数据库生产产商都根据JAVA API去实现各自的应用驱动,这问题就迎刃而解了。
JDBC的工作原理是什么?我将在下一篇文章叙述JDBC运用的设计模式,以及部分JDK源码。
工作原理图(转自百度百科)
提供的接口包括:JAVA API:提供对JDBC的管理链接;JAVA Driver API:支持JDBC管理到驱动器连接。
DriverManager:这个类管理数据库驱动程序的列表,查看加载的驱动是否符合JAVA Driver API的规范。
Connection:与数据库中的所有的通信是通过唯一的连接对象。
Statement:把创建的SQL对象,转而存储到数据库当中。
ResultSet:它是一个迭代器,用于检索查询数据。
三、快速入门 操作流程图数字类型
时间日期类型
字符串类型
1、Connection
public class JDBCUtil { //Driver类全名 public static String DRIVER="com.mysql.jdbc.Driver"; //jdbc协议:子协议://ip:端口号/数据库名 public static String URL="jdbc:mysql://localhost:3306/test"; //数据库用户名 public static String USERNAME="root"; //数据库密码 public static String PASSWORD="root"; private static Connection connection=null; /** * 获取JDBC连接 * @return */ public static Connection getConnection(){ try { //加载驱动程序:它通过反射创建一个driver对象。 Class.forName(DRIVER); //获得数据连接对象。 // 在返回connection对象之前,DriverManager它内部会先校验驱动对象driver信息对不对,我们只要知道内部过程即可。 connection= DriverManager.getConnection(URL,USERNAME,PASSWORD); return connection; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 通过读取文件连接 * @param fileName * @return * @throws SQLException */ public Connection getConnectionByLoadSettingFile(String fileName) throws SQLException { /* 文件里面的内容:跟上面的常量一模一样 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8 jdbc.username=root jdbc.password=root */ Properties props=new Properties(); try { //我的properties文件是放在src根目录下的 InputStream in=DBUtil.class.getResourceAsStream("/"+fileName); if(null==in) System.out.println("找不到文件:"+fileName); props.load(in); } catch (Exception e) { e.printStackTrace(); } String driver=props.getProperty("jdbc.driver"); if(null!=driver) System.setProperty("jdbc.drivers",driver); String url=props.getProperty("jdbc.url"); String username=props.getProperty("jdbc.username"); String password=props.getProperty("jdbc.password"); connection=DriverManager.getConnection(url,username,password); return connection; } }
2、Statement
public class MyClient { public static void main(String [] args) throws SQLException { Connection connection=null; Statement statement=null; connection=JDBCUtil.getConnection(); statement=connection.createStatement(); //需要在自己的数据库当中建立一张user表 String sql="insert into user(loginName,userName,password,sex)values('tom123','tom','123456',1)"; statement.executeUpdate(sql); } }
3、PareparedStatement
public class MyClient { public static void main(String [] args) throws SQLException { Connection connection=null; PreparedStatement pStatement=null; connection=JDBCUtil.getConnection(); String sql="insert into user(loginName,userName,password,sex)values(?,?,?,?)"; //预编译 pStatement=connection.prepareStatement(sql); //前面的索引对应上面的问号,传递参数。 pStatement.setString(1,"tom123"); pStatement.setString(2,"tom"); pStatement.setString(3,"123456"); pStatement.setInt(4,1); pStatement.executeUpdate(); } }
4、ResultSet
public class MyClient { public static void main(String [] args) throws SQLException { Connection connection=null; Statement statement=null; ResultSet resultSet; connection=JDBCUtil.getConnection(); String sql="select * from user"; statement=connection.createStatement(); //resultSet就是一个迭代器,里面的方法跟迭代器几乎一致。 resultSet=statement.executeQuery(sql); while (resultSet.next()){ String loginName=resultSet.getString("loginName"); String userName=resultSet.getString("userName"); String password=resultSet.getString("password"); int sex=resultSet.getInt("sex"); System.out.println(loginName+"-"+userName+"-"+password+"-"+sex); } } }
//了解数据集可滚动更新:查看ResultSet接口的几个参数 /** 结果集不能滚动(默认值)*/ int TYPE_FORWARD_ONLY = 1003; /** 结果集可以滚动,但对数据库变化不敏感*/ int TYPE_SCROLL_INSENSITIVE = 1004; /**结果集可以滚动,且对数据库变化敏感*/ int TYPE_SCROLL_SENSITIVE = 1005; /**结果集不能用于更新数据库(默认值)*/ int CONCUR_READ_ONLY = 1007; /**结果集可以用于更新数据库*/ int CONCUR_UPDATABLE = 1008;
注意:可滚动简单说就是设置结果集可更新resultSet目前的游标值。可更新就是可以更新结果集里面的增删改查。可更新简单说,就是获取数据集ResultSet以后改动更加灵活。
public class Client { public static void main(String [] args){ Connection connection=null; PreparedStatement pStatement=null; Statement statement=null; ResultSet resultSet=null; try { connection=DBUtil.getInstance().getConnection(); //第一个参数设置是否可以滚动,第二个参数设置是否可更新 statement=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from user"; ResultSet rs=statement.executeQuery(sql); /**可滚动的几个方法 rs.previous(); rs.next(); rs.getRow(); rs.absolute(0); **/ //往数据集里面插入数据同时更新到数据:从表的最后开始插入。 rs.moveToInsertRow();//把游标移动到插入行,默认在最后一行。 rs.updateString("loginName","小白脸"); rs.updateString("userName","大猩猩"); rs.updateString("password","123"); rs.updateInt("sex",100); rs.insertRow(); rs.moveToCurrentRow();//把游标移动最后一个位置 //删除第十行数据 rs.absolute(10); rs.deleteRow(); while(rs.next()){ System.out.println(rs.getString(2)); //把数据集里的数据中的性别全部更新为0 rs.updateInt("sex",0); rs.updateRow(); } } catch (SQLException e) { e.printStackTrace(); } } }
事务是什么?我们将一组语句构成一个事务。当所有语句都是顺利执行以后,事务可以被提交。否则,如果其中某个语句遇到错误,那么事务将被回滚,就好像任何语句都没有被执行一样。
实际用例。假设我们需要将钱从一个银行账号转移到另外一个账号。此时,一个非常重要的问题就是我们必须同时将钱从一个账号取出并且存入另一个账号。如果在将钱存入其他账号之前系统发生崩溃,那么我们必须撤销取款操作。
事务有什么特性或者说有什么作用?
- 原子性:最小的单元,如果一个是失败了,则一切的操作将全部失败。
- 一致性:如果事务出现错误,则回到最原始的状态
- 隔离性:多个事务之间无法访问,只有当事务完成后才可以看到结果
- 持久性:当一个系统崩溃时,一个事务依然可以提交,当事务完成后,操作结果保存在磁盘中,不会被回滚
保存点与事务的接口源码
public interface Connection extends Wrapper, AutoCloseable { /** 设置提交方式:自动还是手动*/ void setAutoCommit(boolean autoCommit) throws SQLException; boolean getAutoCommit() throws SQLException; /**提交事务*/ void commit() throws SQLException; /**事务回滚*/ void rollback() throws SQLException; /**设置保存点*/ Savepoint setSavepoint() throws SQLException; Savepoint setSavepoint(String name) throws SQLException; /**回滚到保存点*/ void rollback(Savepoint savepoint) throws SQLException; /**释放保存点资源*/ void releaseSavepoint(Savepoint savepoint) throws SQLException; } public interface Statement extends Wrapper, AutoCloseable { /**加入到批量处理队列*/ void addBatch( String sql ) throws SQLException; void clearBatch() throws SQLException; /**执行批量处理队列*/ int[] executeBatch() throws SQLException; }
什么是保存点?使用保存点可以更细粒度地控制回滚操作,而不用每次都退回到初始点。
什么又是批量更新?批量更新包括批量增删改,当我们一次性要插入很多条数据的时候,假设我们每次提交一次又获取数据库连接一次,然后又关闭数据库连接,而且数据库连接是一个耗时操作,这样会大大降低性能,后续文章我会对这部分内容进行详细叙述。而批量更新呢,则先把数据放入一个队列里,并没有真正存入数据库中,当调用commit()方法的时候,队列的数据的操作一次性收集和提交。
public class Client { public static void main(String [] args) throws SQLException { long time=System.currentTimeMillis(); Connection connection=null; PreparedStatement pStatement=null; boolean autoCommit=false; Savepoint savepoint=null; try { connection=JDBCUtil.getConnection(); autoCommit=connection.getAutoCommit(); connection.setAutoCommit(false); String sql="insert into user(loginName,userName,password,sex)values(?,?,?,?)"; pStatement=connection.prepareStatement(sql); //设置保存点 savepoint=connection.setSavepoint("savePoint"); for(int i=0;i关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?