MySQL成长之路(005)

一、CURD操作:增删该查操作

junit单元测试的使用

  • 让方法能脱离main方法直接运行.
  • 主要是用来开发测试时使用,线上的生产场景不能使用!
  • 线上的生产场景只能使用正常的方法调用!
package com.test1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import org.junit.Test;

/*
 * 增删改查
 * 
 */
public class CRUDDemo {

    //可以自己运行的方法,不需要main方法调用!
    //
    @Test
    public void insert() throws Exception{
        //
        Class.forName("com.mysql.jdbc.Driver");
        
        //
        Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
        
        Statement st = conn.createStatement();//语义直通器
        int res = st.executeUpdate("insert into stu2 values('Tyson','male','yes')");
        //通过返回值是否是非0判断是否执行成功
        if(res != 0){
            System.out.println("插入数据成功");
        }
        //
        st.close();
        conn.close();
    }
    
    @Test
    public void delete() throws Exception{
        //
        Class.forName("com.mysql.jdbc.Driver");
        
        //
        Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
        
        Statement st = conn.createStatement();
        int res = st.executeUpdate("delete from stu2 where name = 'Tyson'");
        //通过返回值是否是非0判断是否执行成功
        if(res != 0){
            System.out.println("删除数据成功");
        }
        //
        st.close();
        conn.close();
    }

    
    @Test
    public void update() throws Exception{
        //
        Class.forName("com.mysql.jdbc.Driver");
        
        //
        Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb1", "root", "123");
        
        Statement st = conn.createStatement();
        int res = st.executeUpdate("update stu2 set zhuxiao = 'yes' where name = 'Frank'");
        //通过返回值是否是非0判断是否执行成功
        if(res != 0){
            System.out.println("更新数据成功");
        }
        //
        st.close();
        conn.close();
    }
    
    
    @Test
    public void search() throws Exception{
        //
        Class.forName("com.mysql.jdbc.Driver");
        
        //
        Connection conn = DriverManager.getConnection("jdbc:mysql:///day229", "root", "123");
        
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery("select * from stu2");
        while(rs.next()){
            String name = rs.getString(1);
            String gender = rs.getString(2);
            String zhuxiao = rs.getString(3);
            System.out.println(name+","+gender+","+zhuxiao);
        }
        //
        rs.close();
        st.close();
        conn.close();
    }
}

封装数据库操作工具类:

  • 注册驱动和获取连接对象的操作是每种操作都需要进行的步骤!
  • 所以考虑将相同的操作封装到工具类中以方便使用!
  • 优化:由于数据库连接使用的四大参数有可能随时发生变化,最好放到配置文件中指定!防止硬编码!
public class Dbutils {
    //构造方法私有化
    private Dbutils(){}
    //公共的静态方法,获取连接对象
    public static Connection getConnection() throws Exception{
        //通过配置文件获取参数
        Properties p = new Properties();
        p.load(new FileInputStream("dbconfig.txt"));
        //
        String driverName = p.getProperty("driverName");
        String url = p.getProperty("url");
        String userName = p.getProperty("userName");
        String password = p.getProperty("password");
        Class.forName(driverName);
        //将连接对象返回
        return DriverManager.getConnection(url,userName,password);
    }
}

 

 

package com.utils;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/*
 * 数据库操作的工具类
 * 主要用来获取连接对象!
 * 通过连接对象有可能获取Statement对象,也有可能获取的是预编译的对象
 * 
 * 共同的操作:
 *     1.注册驱动
 *     2.获取连接对象
 * 
 * 
 * 
 * 优化:
 * 将四大参数放到配置文件中!!!
 * 
 */
public class Dbutils {
    private Dbutils(){
        
    }
    
    //公共的静态方法,获取连接对象
    public static Connection getConnection() throws Exception{
        //通过配置文件获取参数
        Properties p = new Properties();
        p.load(new FileInputStream("dbconfig.txt"));
        
        //
        String driverName = p.getProperty("driverName");
        String url = p.getProperty("url");
        String userName = p.getProperty("userName");
        String password = p.getProperty("password");
        
        
        Class.forName(driverName);
        //
        Connection conn = DriverManager.getConnection(url,userName,password);
        return conn;
    }
}

 

 

package com.test1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import org.junit.Test;

import com.utils.Dbutils;

/*
 * 使用工具类实现增删改查
 * 
 */
public class CRUDDemo2 {

    //可以自己运行的方法,不需要main方法调用!
    //
    @Test
    public void insert() throws Exception{
        
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        int res = st.executeUpdate("insert into stu2 values('Tyson','male','yes')");
        //通过返回值是否是非0判断是否执行成功
        if(res != 0){
            System.out.println("插入数据成功");
        }
        //
        st.close();
        conn.close();
    }
    
    @Test
    public void delete() throws Exception{
        Connection conn = Dbutils.getConnection();
        Statement st = conn.createStatement();
        int res = st.executeUpdate("delete from stu2 where name = 'Tyson'");
        //通过返回值是否是非0判断是否执行成功
        if(res != 0){
            System.out.println("删除数据成功");
        }
        //
        st.close();
        conn.close();
    }

    
    @Test
    public void update() throws Exception{
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        int res = st.executeUpdate("update stu2 set zhuxiao = 'yes' where name = 'Frank'");
        //通过返回值是否是非0判断是否执行成功
        System.out.println(res);
        if(res != 0){
            System.out.println("更新数据成功");
        }
        //
        st.close();
        conn.close();
    }
    
    
    @Test
    public void search() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery("select * from stu2");
        while(rs.next()){
            String name = rs.getString(1);
            String gender = rs.getString(2);
            String zhuxiao = rs.getString(3);
            System.out.println(name+","+gender+","+zhuxiao);
        }
        //
        rs.close();
        st.close();
        conn.close();
    }
}

 

 

Statement接口详解:

是一个sql语句的执行器,可以执行sql语句.同时可以指定将来获取到的结果集的类型:

  • statement语句执行的方法:
  • DML:insert ,update ,delete
  • DDL:create table
  • DQL:select
  • 如果是查询语句,建议使用executeQuery方法,直接得到结果集对象!
  • 如果是更新类语句,建议使用executeUpdate方法,得到的结果是一个int值,通常用返回值是否非0来判断是否执行成功.
  • 特例:execute方法可以执行任何类型的sql语句.返回值是boolean类型.
  • 如果是true表示结果是一个结果集.
package com.test1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

import org.junit.Test;

import com.utils.Dbutils;

/*
 * Statement接口
 * 
 * executeUpdate(String sql):增删改操作
 * executeQuery(String sql):针对查询
 * execute(String sql):执行任意的sql语句,返回的是个布尔类型
 * 
 * 结果集的操作:
 * 游标的移动:
 * next():
 * previous():
 * void afterLast():
 * void beforFirst():
 * boolean first():
 * boolean last():
 * 
 * absolute(int row):
 * relative(int count):count正数,往下移动,负数,往上移动
 * 
 * getRow():获取当前行编号!
 * 
 * 获取结果集的特性:
 * 通过获取Statement语句时指定的参数指定!!!
 * 
 * 
 * 结果集的元数据:描述数据的数据!
 * 如果我不知道结果集有多少列!如何遍历结果集?
 * 通过结果集的元数据!!
 * 元数据里可以获取列的数量.
 * 通过while循环遍历行,通过for循环遍历列.
 * 
 */
public class CRUDDemo3 {
    
    @Test
    public void search3() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        
        ResultSet rs = st.executeQuery("select * from stu2");
        //如果不知道结果集的列数,如果遍历?
        ResultSetMetaData metaData = rs.getMetaData();
        
        int count = metaData.getColumnCount();
        //遍历结果集
        while(rs.next()){
            //遍历列:
            for(int i = 1;i<=count;i++){
                Object obj = rs.getObject(i);
                System.out.print(obj);
                if(i != count){
                    System.out.print(", ");
                }
            }
            //
            System.out.println();
        }
        
        //
        st.close();
        conn.close();
    }
    
    
    
    @Test
    public void search() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        
        
        
//        boolean b = st.execute("select * from stu2");
//        if(b){
//            //获取结果集
//            ResultSet rs = st.getResultSet();
//            while(rs.next()){
//                String name = rs.getString(1);
//                System.out.println(name);
//            }
//            rs.close();
//        }
        
        ResultSet rs = st.executeQuery("select * from stu2");
        System.out.println(rs.getRow());
        
        rs.absolute(5);
        System.out.println(rs.getRow());
        
        //获取结果集的行数
        rs.afterLast();
        rs.previous();
        System.out.println(rs.getRow());
        
        rs.close();
        
        //
        st.close();
        conn.close();
    }
    
    
    @Test
    public void search2() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        /*
         * 第一个参数:结果集的类型:可滚动,不敏感,不可更新
         * ResultSet.TYPE_FORWARD_ONLY: 结果集的游标只能往下滚动
         * ResultSet.TYPE_SCROLL_INSENSITIVE : 对数据库底层数据变化不敏感
         * ResultSet.TYPE_SCROLL_SENSITIVE : 对数据库底层数据变化敏感
        *    MySQL只支持第二种!!!
         * 
         * 第二个参数:结果集的变化是否能更新到底层数据库,
         * ResultSet.CONCUR_READ_ONLY : 结果集的更改不更新到底层的数据库
          * ResultSet.CONCUR_UPDATABLE : 结果集的更改更新到底层的数据库
         * 目前,所有的数据库都只支持第一种!!!
         * 
         * MySQL获取的Statement对象,默认是以下组合!!
         * ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY
         * 
         */
        
        ResultSet rs = st.executeQuery("select * from stu2");
        System.out.println(rs.getRow());
        
        rs.absolute(5);
        System.out.println(rs.getRow());
        
        //获取结果集的行数
        rs.afterLast();
        rs.previous();
        System.out.println(rs.getRow());
        
        rs.close();
        
        //
        st.close();
        conn.close();
    }
}

 

结果集游标操作:

绝对定位:

  • boolean first():
  • boolean last():
  • void beforeFirst():
  • void afterLast():
  • boolean absolute(int row):

相对定位:从当前位置移动

  • boolean next():
  • boolean previous():
  • boolean relative(int amount):正数表示往后移动,负数表示往前移动

判断操作:

  • boolean isAfterLast():
  • boolean isBeforeFirst():
  • boolean isFirst():
  • boolean isLast():

 

结果集的元数据操作:

若不知道具体的结果集有多少列,可以通过结果集的元数据获取结果集的描述信息,其中就包括列的数量.

 

通过列的数量就可以遍历一行数据的各个列.

通过游标的返回值就可以遍历行.

二者结合,就可以遍历一个不知道具体行数和列数的结果集!

ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount();
//遍历结果集
while(rs.next()){
    //遍历列:
    for(int i = 1;i<=count;i++){
        Object obj = rs.getObject(i);
        System.out.print(obj);
        if(i != count){
            System.out.print(", ");
        }
    }
    //
    System.out.println();
}

 

加上异常处理的完整程序!

  • 对非内存资源的释放一般是放在finally块中.就需要将资源的定义放在try块外.
  • finally中需要对资源进行非空判断!!!

sql注入

  1. sql注入:sql语句中出现了一些sql中的关键字,导致整个sql语句的含义发生了变化.即为sql注入!
  2. 防止sql注入的主要方法是让sql语句中不能出现特殊的关键字.
  3. 使用预编译语句即可保证sql语句中只能填入指定类型的值!

 

PreparedStatement对象

  • 连接对象通过prepareStatement方法,可以获取一个预编译的对象,在获取时需要传递一个需要预先编译的sql语句.
  • SQL语句中一般都会包含占位符?
  • 在得到预编译语句后,通过setXXX(占位符索引,值)方法对占位符进行赋值!
  • 占位符索引从1开始.
  • 优点:提高效率,防止sql注入

二进制大对象:blob:***

  • binary large object:
  • 使用流技术上传和下载数据!

 

二进制大文本:text:***

使用流技术上传和下载数据!

 

 

 

批处理:

Statement接口和PreparedStatement接口都可以实现批处理!

 

前者更适合多种sql语句混合使用的场景.

后者更适合同种sql语句一起执行的场景.

 

注意:不同的数据库驱动版本可能对批处理有不同的支持!

MySQL默认没有开启批处理功能!

需要在url后添加如下属性开启此功能!

url=jdbc:mysql:///day17?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true

更改的是客户端的配置,不需要重启.

 

事务操作:

事务的操作都是通过连接对象进行的:

  • 手动开启事务:
  • void setAutoCommit(boolean on):设置为false就是开启了手动事务!
  • 事务回滚:
  • void rooback():
  • 事务提交:
  • void commit():

 

回滚点:

回滚点也是通过连接对象进行的操作!savepoint是接口

  • 设置回滚:
  • Savepoint setSavepoint():
  • 回滚到回滚点:
  • void rollback(Savepoint sp):

   标准事务处理:

  try中处理

  final中释放资源

连接池(数据源)

dbcp连接池(数据源):apache开源的数据源.

需要导入两个包:

 

需要设置的数据:

  • 数据库连接四大参数:
  • 第一种方式:将数据库连接的四大参数在程序中直接提供(硬编码)
  • 第二种方式:使用Properties类关联到一个配置文件.将四大参数用配置文件提供!

 

  • 池参数:一般保持默认!
  • 最大空闲连接数
  • 最大活动连接数
  • 初始连接数

 

 

装饰者模式:decorator Wrapper

  • 需要被装饰的类装饰类有共同的父类或者是接口!
  • 先创建一个底层被包装对象,
  • 再创建包装类对象时,将底层对象通过构造方法传递!!!
  • 是你还有你!(是你:装饰类和被装饰的类有共同的父类(接口),还是你:在成员变量位置保持一个被装饰对象的引用)
  • 一切拜托你!!(不关心的方法,直接调用底层被包装的对象的相应方法)
  • 增强点上增强!!!(在增强方法肾功能进行逻辑上的增强)
package com.test7;
/*
 * 装饰器模式:
 * 包装一个对象,绝大多数方法保持不变,只在少数方法上进行增强!
 * 
 * 
 * 
 * 对象增强的手段:常用的是继承!
 * A
 * AA extends A{
 *     ///
 * }
 * 
 * 咖啡 :
 * 加奶咖啡:
 * 加糖咖啡:
 * 加盐咖啡:
 * 加糖,加奶咖啡:
 * ...
 * 随着需求的不断变化,会导致类的暴增!!!
 * 
 * 使用装饰器模式:
 * 咖啡 :
 * 
 * 咖啡 a = new 咖啡();
 * 加奶咖啡 b = 加奶咖啡(a);
 * 加糖咖啡 c = 加糖咖啡(b);
 * 
 * 
 * 连接池:
 * getConnection
 * createStatement.
 * prepareStatement
 * 
 * 
 * 连接池在close方法上进行了增强!!!
 * close
 * 
 * jdk中使用装饰者典型的是:io流
 * 
 * BufferedReader(Reader r)
 * 
 * 
 * 
 */

abstract class Animal{
    public abstract void test1();
    public abstract void test2();
    public abstract void test3();
    public abstract void test4();
}

class Dog extends Animal{

    @Override
    public void test1() {
        System.out.println("dog test1");
    }

    @Override
    public void test2() {
        System.out.println("dog test2");
    }

    @Override
    public void test3() {
        System.out.println("dog test3");
    }

    @Override
    public void test4() {
        System.out.println("dog test4");
    }
}

//装饰器类:让装饰器类和被装饰的类有共同的父类(接口).
//在装饰类中保持一个父类(接口)的引用.在构造方法中对其进行赋值
//在增强点方法上进行修改,其余的非增强点方法保持原样!!!
class DogWrapper extends Animal{
    //保持一个父类的引用
    Animal an = null;
    //构造方法中对其赋值
    public DogWrapper(Animal an){
        this.an = an;
    }
    
    @Override
    public void test1() {
        an.test1();
    }

    @Override
    public void test2() {
        an.test2();
    }

    @Override
    public void test3() {
        an.test3();
    }

    //增强点方法
    @Override
    public void test4() {
        System.out.println("hello");
        an.test4();
        System.out.println("world");
    }
}


public class WrapperDemo {

    public static void main(String[] args) {
//        Animal a = new Dog();
        
        Animal an = new Dog();
        Animal a = new DogWrapper(an);
        a.test1();
        a.test2();
        a.test3();
        a.test4();

    }

}

 

 

 

 

 

 

package com.test1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import org.junit.Test;

import com.utils.Dbutils;

/*
 * 使用工具类实现增删改查
 * 
 */
public class CRUDDemo2 {

    //可以自己运行的方法,不需要main方法调用!
    //
    @Test
    public void insert() throws Exception{
        
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        int res = st.executeUpdate("insert into stu2 values('Tyson','male','yes')");
        //通过返回值是否是非0判断是否执行成功
        if(res != 0){
            System.out.println("插入数据成功");
        }
        //
        st.close();
        conn.close();
    }
    
    @Test
    public void delete() throws Exception{
        Connection conn = Dbutils.getConnection();
        Statement st = conn.createStatement();
        int res = st.executeUpdate("delete from stu2 where name = 'Tyson'");
        //通过返回值是否是非0判断是否执行成功
        if(res != 0){
            System.out.println("删除数据成功");
        }
        //
        st.close();
        conn.close();
    }

    
    @Test
    public void update() throws Exception{
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        int res = st.executeUpdate("update stu2 set zhuxiao = 'yes' where name = 'Frank'");
        //通过返回值是否是非0判断是否执行成功
        System.out.println(res);
        if(res != 0){
            System.out.println("更新数据成功");
        }
        //
        st.close();
        conn.close();
    }
    
    
    @Test
    public void search() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery("select * from stu2");
        while(rs.next()){
            String name = rs.getString(1);
            String gender = rs.getString(2);
            String zhuxiao = rs.getString(3);
            System.out.println(name+","+gender+","+zhuxiao);
        }
        //
        rs.close();
        st.close();
        conn.close();
    }
}

 

 

package com.test1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

import org.junit.Test;

import com.utils.Dbutils;

/*
 * Statement接口
 * 
 * executeUpdate(String sql):增删改操作
 * executeQuery(String sql):针对查询
 * execute(String sql):执行任意的sql语句
 * 
 * 结果集的操作:
 * 游标的移动:
 * next():
 * previous():
 * void afterLast():
 * void beforFirst():
 * boolean first():
 * boolean last():
 * 
 * absolute(int row):
 * relative(int count):count正数,往下移动,负数,往上移动
 * 
 * getRow():获取当前行编号!
 * 
 * 获取结果集的特性:
 * 通过获取Statement语句时指定的参数指定!!!
 * 
 * 
 * 结果集的元数据:描述数据的数据!
 * 如果我不知道结果集有多少列!如何遍历结果集?
 * 通过结果集的元数据!!
 * 元数据里可以获取列的数量.
 * 通过while循环遍历行,通过for循环遍历列.
 * 
 */
public class CRUDDemo3 {
    
    @Test
    public void search3() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        
        ResultSet rs = st.executeQuery("select * from stu2");
        //如果不知道结果集的列数,如果遍历?
        ResultSetMetaData metaData = rs.getMetaData();
        
        int count = metaData.getColumnCount();
        //遍历结果集
        while(rs.next()){
            //遍历列:
            for(int i = 1;i<=count;i++){
                Object obj = rs.getObject(i);
                System.out.print(obj);
                if(i != count){
                    System.out.print(", ");
                }
            }
            //
            System.out.println();
        }
        
        //
        st.close();
        conn.close();
    }
    
    
    
    @Test
    public void search() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        
        
        
//        boolean b = st.execute("select * from stu2");
//        if(b){
//            //获取结果集
//            ResultSet rs = st.getResultSet();
//            while(rs.next()){
//                String name = rs.getString(1);
//                System.out.println(name);
//            }
//            rs.close();
//        }
        
        ResultSet rs = st.executeQuery("select * from stu2");
        System.out.println(rs.getRow());
        
        rs.absolute(5);
        System.out.println(rs.getRow());
        
        //获取结果集的行数
        rs.afterLast();
        rs.previous();
        System.out.println(rs.getRow());
        
        rs.close();
        
        //
        st.close();
        conn.close();
    }
    
    
    @Test
    public void search2() throws Exception{
        //
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        /*
         * 第一个参数:结果集的类型:可滚动,不敏感,不可更新
         * ResultSet.TYPE_FORWARD_ONLY: 结果集的游标只能往下滚动
         * ResultSet.TYPE_SCROLL_INSENSITIVE : 对数据库底层数据变化不敏感
         * ResultSet.TYPE_SCROLL_SENSITIVE : 对数据库底层数据变化敏感
        *    MySQL只支持第二种!!!
         * 
         * 第二个参数:结果集的变化是否能更新到底层数据库,
         * ResultSet.CONCUR_READ_ONLY : 结果集的更改不更新到底层的数据库
          * ResultSet.CONCUR_UPDATABLE : 结果集的更改更新到底层的数据库
         * 目前,所有的数据库都只支持第一种!!!
         * 
         * MySQL获取的Statement对象,默认是以下组合!!
         * ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY
         * 
         */
        
        ResultSet rs = st.executeQuery("select * from stu2");
        System.out.println(rs.getRow());
        
        rs.absolute(5);
        System.out.println(rs.getRow());
        
        //获取结果集的行数
        rs.afterLast();
        rs.previous();
        System.out.println(rs.getRow());
        
        rs.close();
        
        //
        st.close();
        conn.close();
    }
}

 

 

package com.test1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.Test;

import com.utils.Dbutils;

/*
 * 加上异常处理的程序
 * 资源的释放一般放在finally块中!!
 * 
 */

public class CRUDDemo4 {
    
    @Test
    public void search3(){
        //作用域提升
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try{
            conn = Dbutils.getConnection();
            
            st = conn.createStatement();
            
            rs = st.executeQuery("select * from stu2");
            //如果不知道结果集的列数,如果遍历?
            ResultSetMetaData metaData = rs.getMetaData();
            
            int count = metaData.getColumnCount();
            //遍历结果集
            while(rs.next()){
                //遍历列:
                for(int i = 1;i<=count;i++){
                    Object obj = rs.getObject(i);
                    System.out.print(obj);
                    if(i != count){
                        System.out.print(", ");
                    }
                }
                //
                System.out.println();
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }finally{
            //
            try {
                //非空判断
                if(st != null){
                    st.close();
                }
            } catch (SQLException e) {
            }
            try {
                if(conn != null){
                    conn.close();
                }
            } catch (SQLException e) {
            }
            
            try {
                if(rs != null){
                    rs.close();
                }
            } catch (SQLException e) {
            }
        }
    }
}

 

 

package com.test3;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;

import com.utils.Dbutils;

/*
 * blob:
 * binary large object
 * 可执行程序,图片,视频,音频....
 * 
 * 一般不会放到数据库中,效率低:
 * 
 * 数据库存放的绝大多数都是字符串!
 * 数据库中保存的是资源的路径!!!
 * 
 * tinyblob:255字节
 * blob:64K
 * midumblob:16M
 * longblob:4G
 * 
 */
public class BlobDemo {

    public static void main(String[] args) throws Exception {
        insert2();

    }

    // 往数据库中存图片
    private static void insert2() throws Exception {
        Connection conn = Dbutils.getConnection();
        PreparedStatement pst = conn.prepareStatement("insert into my_blob values(null,?)");
        // 对占位符进行赋值
        pst.setBinaryStream(1, new FileInputStream("c:/dog.jpg"));

        // 插入数据
        int res = pst.executeUpdate();
        if (res != 0) {
            System.out.println("插入图片成功");
        }
        //
        pst.close();
        conn.close();
    }

    // 往数据库中存图片
    private static void insert() throws Exception {
        Connection conn = Dbutils.getConnection();
        PreparedStatement pst = conn.prepareStatement("insert into my_blob values(null,?)");
        // 对占位符进行赋值
        pst.setBinaryStream(1, new FileInputStream("c:/PresionBreak.jpg"));

        // 插入数据
        int res = pst.executeUpdate();
        if (res != 0) {
            System.out.println("插入图片成功");
        }
        //
        pst.close();
        conn.close();
    }

}

 

 

package com.test3;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.utils.Dbutils;

/*
 * blob:
 * binary large object
 * 可执行程序,图片,视频,音频....
 * 
 * 一般不会放到数据库中,效率低:
 * 
 * 数据库存放的绝大多数都是字符串!
 * 数据库中保存的是资源的路径!!!
 * 
 * tinyblob:255字节
 * blob:64K
 * midumblob:16M
 * longblob:4G
 * 
 */
public class BlobDemo {

    public static void main(String[] args) throws Exception {
//        insert2();
        read();

    }

    //从数据库读取图片:底层使用的是流!!!
    private static void read() throws Exception {
        Connection conn = Dbutils.getConnection();
        
        PreparedStatement pst = conn.prepareStatement("select data from my_blob where id = 2");
        ResultSet rs = pst.executeQuery();
//        while(rs.next()){
//            
//        }
        rs.next();
        //列的序号是结果集中的列的序号,而不是表设计时的序号!!
        InputStream in = rs.getBinaryStream(1);
        //创建输出流
        FileOutputStream out = new FileOutputStream("c:/dog22.jpg");
        byte[] buf = new byte[1024 * 8];
        int len = 0;
        while((len = in.read(buf)) != -1){
            out.write(buf, 0, len);
        }
        
        //
        out.close();
        in.close();
        rs.close();
        pst.close();
        conn.close();
    }

    // 往数据库中存图片
    private static void insert2() throws Exception {
        Connection conn = Dbutils.getConnection();
        PreparedStatement pst = conn.prepareStatement("insert into my_blob values(null,?)");
        // 对占位符进行赋值
        pst.setBinaryStream(1, new FileInputStream("c:/dog.jpg"));

        // 插入数据
        int res = pst.executeUpdate();
        if (res != 0) {
            System.out.println("插入图片成功");
        }
        //
        pst.close();
        conn.close();
    }

    // 往数据库中存图片
    private static void insert() throws Exception {
        Connection conn = Dbutils.getConnection();
        PreparedStatement pst = conn.prepareStatement("insert into my_blob values(null,?)");
        // 对占位符进行赋值
        pst.setBinaryStream(1, new FileInputStream("c:/PresionBreak.jpg"));

        // 插入数据
        int res = pst.executeUpdate();
        if (res != 0) {
            System.out.println("插入图片成功");
        }
        //
        pst.close();
        conn.close();
    }
}

 

 

package com.test3;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.utils.Dbutils;

/*
 * tinytext:255字节
 * text:64K
 * mediumtext:16M
 * longtext:4G
 * 
 */
public class TextDemo {

    public static void main(String[] args) throws Exception {
//        insert();
        read();
    }

    //从数据库读取文本
    private static void read() throws Exception {
        Connection conn = Dbutils.getConnection();
        PreparedStatement pst = conn.prepareStatement("select data from my_text where id = 1");
        ResultSet rs = pst.executeQuery();
        rs.next();
        
        Reader r = rs.getCharacterStream(1);
        //创建字符输出流
        FileWriter w = new FileWriter("c:/text.txt");
        char[] buf = new char[1024 * 8];
        int len = 0;
        while((len = r.read(buf)) != -1){
            w.write(buf, 0, len);
        }
        //
        w.close();
        r.close();
        rs.close();
        pst.close();
        conn.close();
        
    }

    //插入文本
    private static void insert() throws Exception {
        Connection conn = Dbutils.getConnection();
        
        PreparedStatement pst = conn.prepareStatement("insert into my_text values(null,?)");
        pst.setCharacterStream(1, new FileReader("dbconfig.txt"));
        
        int res = pst.executeUpdate();
        if(res != 0){
            System.out.println("插入数据成功");
        }
        pst.close();
        conn.close();
        
    }

}

 

 

package com.test4;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import com.utils.Dbutils;

/*
 * 批处理:
 * Statement接口中的方法:
 *     PreparedStatement接口也可以使用!!!
 * 
 * addBatch(String sql):
 * executeBatch():
 * clearBatch():
 * 
 * 
 * Statement:适合多种类型的操作混合在一起操作
 * PreparedStatement:适合同一种操作,但是参数不同!!
 * 
 */
public class BatchDemo {

    public static void main(String[] args) throws Exception {
//        test1();
        long start = System.currentTimeMillis();
        test2();
        System.out.println(System.currentTimeMillis() - start);
    }

    //使用预编译语句的批处理
    private static void test2() throws Exception {
        Connection conn = Dbutils.getConnection();
        
        PreparedStatement pst = conn.prepareStatement("insert into stu values(null,?,?)");
        
        for(int i = 1;i<=1000;i++){
            pst.setString(1, "name" + i);
            pst.setInt(2, i);
            //把当前语句放到批处理中
            pst.addBatch();
            //
            if(i % 200 == 0){
                pst.executeBatch();
            }
        }
        
        //执行批处理
        pst.executeBatch();
        
        //
        pst.close();
        conn.close();
    }

    private static void test1() throws Exception, SQLException {
        Connection conn = Dbutils.getConnection();
        
        Statement st = conn.createStatement();
        //添加批处理
        st.addBatch("insert into stu values(null,'zhangsan',10)");
        st.addBatch("insert into stu values(null,'lisi',10)");
        st.addBatch("insert into stu values(null,'赵六',20)");
        st.addBatch("insert into stu values(null,'王五',30)");
        st.addBatch("insert into stu values(null,'Tyson',50)");
        
        //
        st.executeBatch();
        
        //
        st.close();
        conn.close();
    }

}

 

package com.test5;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;

import com.utils.Dbutils;

/*
 * 默认jdbc也是自动事务.
 * 手动开启事务:
 * 使用连接对象的方法:
 * setAutoCommit(boolean on):设置为false,意味着手动事务开启
 * 
 * commit():提交事务
 * rollback():回滚到事务开启之前
 * rollback(Savepoint sp):回滚到指定保存点
 * 
 * setSavepoint():获取一个保存点
 * 
 */
public class TransactionDemo {

    public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        Savepoint sp1 = null;
        try{
            //正常提交
            conn = Dbutils.getConnection();
            
            conn.setAutoCommit(false);
            
            //
            st = conn.createStatement();
            st.executeUpdate("insert into student values (6,'yyy',10,20,1)");
            
            //设置保存点:
            sp1 = conn.setSavepoint();
            
            
            int res = st.executeUpdate("update student set name = 'xxx' where id = 6");
//            if(res != 0){
//                System.out.println("更新成功");
//            }
            
            //异常
            if(true){
                throw new RuntimeException("发生异常");
            }
            //提交
            conn.commit();
        }catch(Exception e){
            //异常回滚
            System.out.println(e.getMessage());
            //回滚到回滚点
            try {
                if(conn != null){
                    conn.rollback(sp1);
                    
                    //结束事务:否则保存点之前的操作不能更新到底层数据库!!!
                    conn.commit();
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally{
            try {
                if(st != null){
                    st.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
            try {
                if(conn != null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    private static void test1() throws Exception, SQLException {
        Connection conn = Dbutils.getConnection();
        
        //手动开启事务
        conn.setAutoCommit(false);
        
        //
        conn.createStatement().executeUpdate("delete from student where id = 2");
        
        //回滚
//        conn.rollback();
        
        //提交
        conn.commit();
        //
        conn.close();
    }

}

 

-----------------------------------------------------------------

作业:

对一个对象的有返回值的方法进行增强!在方法前加"hello",方法调用后,加"world"
package com.homework;
/*
 * 对一个对象的有返回值的方法进行增强!
在方法前加"hello",方法调用后,加"world".
 */

abstract class Animal{
    public abstract void t1();
    public abstract String t2();
}

class Dog extends Animal{

    @Override
    public void t1() {
        System.out.println("Dog.t1()");
    }

    @Override
    public String t2() {
        System.out.println("Dog.t2()");
        return "xxx";
    }
    
}


class DogWrapper extends Animal{
    Animal an ;
    public DogWrapper(Animal an){
        this.an = an;
    }
    
    
    @Override
    public void t1() {
        an.t1();
    }

    @Override
    public String t2() {
        System.out.println("hello");
        String res = an.t2();
        System.out.println("world");
        return res;
    }
    
}


public class Demo {

    public static void main(String[] args) {
        //被包装对象
        Dog d = new Dog();
        //创建包装类对象
        DogWrapper dw = new DogWrapper(d);
        //
        dw.t1();
        
        //
        String res = dw.t2();
        System.out.println(res);

    }

}

 

--------------------------------------------------

使用set local xxx = ... 是对本地变量进行设置.

本次会话立即生效!

 

总结:

对客户端的会话变量进行设置:使用set local ...

对服务端的系统变量进行设置:使用set global ...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2018-12-03 09:10  杜菲  阅读(131)  评论(0编辑  收藏  举报