0


JDBC基础篇总结

基础总结目录2

说明:本篇文章承接上一篇文章---->JDBC基础篇总结,链接地址为:
JDBC基础篇总结

3. 使用PreparedStatement实现CRUD操作

3.1 PreparedStatement介绍

①可以通过调用 Connection 对象的 preparedStatement(String sql) 方法获取PreparedStatement 对象
②PreparedStatement 接口是 Statement 的 子接口,它表示一条 预编译过的 SQL 语句
③PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement 对象的 setXxx() 方法来设置这些参数. setXxx() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从1开始),第二个是设置的 SQL 语句中的参数的值

3.2 PreparedStatement vs Statement

代码的可读性和可维护性。
PreparedStatement 能最大可能提高性能:

①DBServer会对预编译语句提供性能优化。因为预编译语句有可能被重复调用,所以语句在被DBServer的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中就会得到执行。
 ②在statement语句中,即使是相同操作但因为数据内容不一样,所以整个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存。这样每执行一次都要对传入的语句编译一次。
 ③(语法检查,语义检查,翻译成二进制命令,缓存)

3.3 Java与SQL对应数据类型转换表

Java类型SQL类型booleanBITintINTEGERbyteTINYINTshortSMALLINTlongBIGINTStringCHAR,VARCHAR,LONGVARCHARbyte arrayBINARY , VAR BINARYjava.sql.DateDATEjava.sql.TimeTIMEjava.sql.TimestampTIMESTAMP

3.4 使用PreparedStatement实现增、删、改、查操作

(1)实现增删改通用的操作
实现的步骤主要如下:

1.获取数据库的连接
2.预编译sql语句,获取PreparedStatement实例
3.填充占位符
4.执行操作
5.资源关闭

publicvoidupdate(String sql,Object...args)throwsException{Connection connection =null;PreparedStatement ps =null;try{//1.获取数据库的连接
            connection =JDBCUtils.getConnection();//2.预编译sql语句,获取PreparedStatement实例
            ps = connection.prepareStatement(sql);//3.填充占位符for(int i =0; i < args.length; i++){
                ps.setObject(i +1,args[i]);}//4.执行操作
            ps.execute();}catch(Exception e){
            e.printStackTrace();}finally{//5.资源的关闭JDBCUtils.closeResource(connection,ps);}}

在此之前用到的配置文件以及Java文件(根据自己的实际情况需要做出修改)
jdbc.properties

user=root
password=111111
url=jdbc:mysql://localhost:3306/testcharacterEncoding=utf8&rewriteBatchedStatements=true
driverClass=com.mysql.jdbc.Driver

数据库的连接

//获取数据库的连接publicstaticConnectiongetConnection()throwsException{//1.读取四个基本配置信息InputStream is =JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");Properties properties =newProperties();
        properties.load(is);String user = properties.getProperty("user");String password = properties.getProperty("password");String url = properties.getProperty("url");String driverClass = properties.getProperty("driverClass");//2.加载驱动Class.forName(driverClass);//3.获取连接Connection connection =DriverManager.getConnection(url, user, password);return connection;}

关闭数据库的连接

publicstaticvoidcloseResource(Connection conn,PreparedStatement ps,ResultSet rs){if(conn !=null){try{
                conn.close();}catch(SQLException e){
                e.printStackTrace();}}if(ps !=null){try{
                ps.close();}catch(SQLException e){
                e.printStackTrace();}}if(rs !=null){try{
                rs.close();}catch(SQLException e){
                e.printStackTrace();}}}

(2)实现查询操作
提示:在进行查询前的准备工作:数据的连接,配置信息等在上面已经展示

查询操作步骤:

①获取数据库的连接
②预编译sql语句,获取PreparedStatement实例
③填充占位符
④获取结果集
⑤获取元数据
⑥获取字段数目
⑦创建一个ArrayList集合
⑧创建一个T (根据每个不同的类创建不同类型的对象)对象
⑨获取列值和字段名
⑩通过反射给属性赋值------将对象添加到集合-------资源关闭

使用集合来记录每一条数据

public<T>ArrayList<T>getForList(Class<T> clazz,String sql,Object...args){Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;try{//获取连接
            conn =JDBCUtils.getConnection();
            ps = conn.prepareStatement(sql);for(int i =0; i < args.length; i++){
                ps.setObject(i +1,args[i]);}//获取结果集
            rs = ps.executeQuery();//获取元数据ResultSetMetaData ramd = rs.getMetaData();int columnCount = ramd.getColumnCount();ArrayList<T> arrayList =newArrayList<T>();while(rs.next()){T t = clazz.newInstance();for(int i =0; i < columnCount; i++){//获取列值Object columnValue = rs.getObject(i +1);String columnLabel = ramd.getColumnLabel(i +1);//通过反射给属性赋值Field field = clazz.getDeclaredField(columnLabel);
                    field.setAccessible(true);
                    field.set(t,columnValue);}
                arrayList.add(t);}return arrayList;}catch(Exception e){
            e.printStackTrace();}finally{JDBCUtils.closeResource(conn,ps,rs);}returnnull;}

4.操作BLOB类型字段

4.1 MySQL BLOB类型

①MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
②插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。
③MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)
类型大小(单位:字节)TinyBlob255Blob64KMediumBlob16MLongBlob4G
④如果在指定了相关的Blob类型以后,还报错:xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数:max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务

4.2 向数据表中插入大数据类型

插入图片,注意:需要将插入的图片放到通一个工程下:
实现步骤:

①获取数据库的连接
②预编译sql语句,获取PreparedStatement实例
③填充占位符
④执行操作
⑥关闭资源

@TestpublicvoidInsertCustomer()throwsException{Connection conn =JDBCUtils.getConnection();String sql ="insert into customers(name,email,birth,photo) values (?,?,?,?)";PreparedStatement ps = conn.prepareStatement(sql);
        ps.setObject(1,"张杰");
        ps.setObject(2,"[email protected]");
        ps.setObject(3,"1999-06-05");FileInputStream fis =newFileInputStream(newFile("张杰.png"));
        ps.setBlob(4,fis);

        ps.execute();JDBCUtils.closeResource(conn,ps);}

4.3 从数据表中读取大数据类型

实现步骤:

①获取数据库的连接
②预编译sql语句,获取PreparedStatement实例
③填充占位符
④获取结果集
⑤执行查询操作
⑤获取字段值
⑥创建类的对象,将字段值填充进去
⑦获取图片的二进制对象Blob以及获取字节输入流,创建字节输出流
⑧将输入从内存读到硬盘
⑨资源关闭

@TestpublicvoidtestQuary(){Connection conn =null;PreparedStatement ps =null;ResultSet rs =null;InputStream is =null;FileOutputStream fos =null;try{
        conn =JDBCUtils.getConnection();String sql ="select id,name,email,birth,photo from customers where id = ?";
        ps = conn.prepareStatement(sql);
        ps.setObject(1,21);

        rs = ps.executeQuery();
        is =null;
        fos =null;if(rs.next()){int id = rs.getInt("id");String name = rs.getString("name");String email = rs.getString("email");Date birth = rs.getDate("birth");Customer customer =newCustomer(id,name,email,birth);Blob photo = rs.getBlob("photo");//获取字节输入流
            is = photo.getBinaryStream();
            fos =newFileOutputStream(newFile("Jason.jpg"));byte[] buffer =newbyte[20];int len;while((len = is.read(buffer))!=-1){
                fos.write(buffer,0,len);}}}catch(Exception e){
        e.printStackTrace();}finally{JDBCUtils.closeResource(conn,ps,rs);if(is !=null){try{
                is.close();}catch(IOException e){
                e.printStackTrace();}}if(fos !=null){try{
                fos.close();}catch(IOException e){
                e.printStackTrace();}}}}

5. 批量插入

5.1 批量执行SQL语句

当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率

JDBC的批量处理语句包括下面三个方法:
①addBatch(String):添加需要批量处理的SQL语句或是参数;
②executeBatch():执行批量处理语句;
③clearBatch():清空缓存的数据

通常我们会遇到两种批量执行SQL语句的情况:
(1)多条SQL语句的批量处理;
(2)一个SQL语句的批量传参;

5.2 高效的批量插入

第一种方式

每一次的插入单独执行,插入一次执行提交一次

@TestpublicvoidtestInsert1(){Connection conn =null;PreparedStatement ps =null;try{
            conn =JDBCUtils.getConnection();String sql ="insert into goods(name) values (?)";
            ps = conn.prepareStatement(sql);for(int i =0; i <200; i++){
                ps.setObject(1,"name_"+i);
                ps.execute();}}catch(Exception e){
            e.printStackTrace();}finally{JDBCUtils.closeResource(conn,ps);}}

第二种方式

做出以下修改:
1.addBatch(), executeBatch()、cleatBatch()
2.mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。 ?rewriteBatchedStatements=true写在配置文件的url后

获得多个SQL语句之后执行一次

@TestpublicvoidtestInsert2(){Connection conn =null;PreparedStatement ps =null;try{
            conn =JDBCUtils.getConnection();String sql ="insert into goods(name) values (?)";
            ps = conn.prepareStatement(sql);for(int i =1; i <=200000; i++){
                ps.setObject(1,"name_"+i);//添加多条数据之后再进行提交
                ps.addBatch();if(i %50==0){
                    ps.executeBatch();
                    ps.clearBatch();}}}catch(Exception e){
            e.printStackTrace();}finally{JDBCUtils.closeResource(conn,ps);}}

添加方式三:

最优方案:
设置为不允许自动提交,在所有的数据都加载完毕之后,再提交数据

@TestpublicvoidtestInsert3(){Connection conn =null;PreparedStatement ps =null;try{
            conn =JDBCUtils.getConnection();String sql ="insert into goods(name) values (?)";
            ps = conn.prepareStatement(sql);

            conn.setAutoCommit(false);for(int i =1; i <=200000; i++){
                ps.setObject(1,"name_"+i);//添加多条数据之后再进行提交//‘攒’sql
                ps.addBatch();if(i %50==0){//执行executeBatch()
                    ps.executeBatch();//清空executeBatch()
                    ps.clearBatch();}}
            conn.commit();}catch(Exception e){
            e.printStackTrace();}finally{JDBCUtils.closeResource(conn,ps);}}
标签: sql 数据库 java

本文转载自: https://blog.csdn.net/weixin_44606952/article/details/125337088
版权归原作者 镜 玄 所有, 如有侵权,请联系我们删除。

“JDBC基础篇总结”的评论:

还没有评论