>

JDBC的连接mySql的基本知识

- 编辑:大富豪棋牌游戏下载 -

JDBC的连接mySql的基本知识

  这只是我自己的随笔博客~,用于偶尔回忆知识,可能存在一些错误,如有错误,欢迎指正~

一、eclipse的使用

原生JDBC,jdbc

JDBC
Java DataBase Connectivity,java数据库连接,是一种用于执行SQL语句的Java API。
JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。

驱动
JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。

JDBC规范(掌握四个核心对象
DriverManager:用于注册驱动
Connection: 表示与数据库创建的连接
Statement: 操作数据库sql语句的对象
ResultSet: 结果集或一张虚拟表

使用JDBC技术,通过mysql提供的驱动程序,操作数据库实现步骤:
1.注册驱动
告知JVM我们使用的是什么驱动程序(mysql,oracle....)
DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用
原因有2个:
>导致驱动被注册2次。
>强烈依赖数据库的驱动jar
解决办法:
Class.forName("com.mysql.jdbc.Driver");
2.获取数据库的连接
数据库是TCP程序服务器,连接服务器(通过3次握手)
就相当于建立了一条java程序通往数据库服务器的连接通路
static Connection getConnection(String url, String user, String password)
试图建立到给定数据库 URL 的连接。
参数说明:url 需要连接数据库的位置(网址) user用户名 password 密码
例如:getConnection("jdbc:mysql://localhost:3306/day06", "root", "root");
URL:SUN公司与数据库厂商之间的一种协议。
jdbc:mysql://localhost:3306/day06
协议子协议 IP :端口号数据库
mysql: jdbc:mysql://localhost:3306/day04或者jdbc:mysql:///day14(默认本机连接)
oracle数据库: jdbc:oracle:thin:@localhost:1521:sid
3.获取执行者对象
执行SQL语句的对象,作用就是执行SQL
接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。
Statement createStatement(); //创建操作sql语句的对象
4.执行SQL语句,获取结果集
使用执行者对象执行SQL语句
获取SQL语句的结果集(增删改:整数,执行有效行数 查询:返回的就是一个结果集)
常用方法:
? int executeUpdate(String sql); --执行insert update delete语句.
? ResultSet executeQuery(String sql); --执行select语句.
? boolean execute(String sql); --仅当执行select并且有结果时才返回true,执行其他的语句返回false.
5.处理结果集
ResultSet实际上就是一张二维的表格,我们可以调用其boolean next()方法指向某行记录,当第一次调用next()方法时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法(与索引从0开始不同个,列从1开始)来获取指定列的数据:
rs.next();//指向第一行
rs.getInt(1);//获取第一行第一列的数据
常用方法:
? Object getObject(int index) / Object getObject(String name) 获得任意对象
? String getString(int index)/ String getString(String name) 获得字符串
? int getInt(int index)/int getInt(String name) 获得整形
? double getDouble(int index)/ double getDouble(String name) 获得双精度浮点型
6.释放资源
与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。
使用JDBC对数据库进行增删改查代码演示:

  1 public static void main(String[] args) throws Exception {
  2         //1.注册驱动
  3         Class.forName("com.mysql.jdbc.Driver");
  4         //2.获取数据库连接
  5         String url = "jdbc:mysql://localhost:3306/mybase4";
  6         String user = "root";
  7         String password = "root"; 
  8         Connection conn = DriverManager.getConnection(url, user, password);
  9         //3.获取执行者对象
 10         Statement stat = conn.createStatement();
 11         //调用更新数据的方法
 12         //update(stat);
 13         //调用删除数据的方法
 14         //delete(stat);
 15         //调用增加数据的方法
 16         //insert(stat);
 17         //调用查询数据的方法
 18         select(stat);
 19         //6.释放资源
 20         stat.close();
 21         conn.close();
 22     }
 23 
 24     /*
 25      * 使用JDBC技术,查询数据库中表的数据
 26      */
 27     private static void select(Statement stat) throws Exception {
 28         //拼接sql语句
 29         String sql = "SELECT * FROM category";
 30         /*
 31          * 4.执行sql语句
 32          * 使用Statement中的方法
 33          * ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 
 34          * 返回值ResultSet标准接口的实现类对象,实现类对象由mysql驱动提供,可以使用ResultSet接口接收
 35          */
 36         ResultSet rs = stat.executeQuery(sql);
 37         System.out.println(rs);//[email protected]
 38         /*
 39          * 5.处理结果
 40          * ResultSet中有一个方法
 41          * boolean next() 将光标从当前位置向前移一行。
 42          * 如果新的当前行有效,则返回 true;如果不存在下一行,则返回 false 
 43          * 如果有结果集返回true,若果没有结果集返回false
 44          * 相当于迭代器中的hasNext方法
 45          */
 46         while(rs.next()){
 47             /*
 48              * next返回true,有结果集
 49              * 取出结果集
 50              * 使用ResultSet中的方法getXXX(参数);
 51              * 参数:
 52              *     int columnIndex:列所在的索引,从1开始
 53              *     String columnLabel:列名
 54              * 注意:
 55              *     如果使用getInt,getDouble指定数据类型的方法,返回值就是对应的数据类型
 56              *     如果使用getObject方法返回值是object类型(只是打印可用)
 57              * 如果使用getString方法返回值是String类型
 58              */
 59             /*int i1 = rs.getInt(1);
 60             String s2 = rs.getString(2);
 61             System.out.println(i1 "t" s2);*/
 62             
 63             //System.out.println(rs.getObject(1) "t" rs.getObject(2));
 64             System.out.println(rs.getObject("cid") "t" rs.getObject("cname"));
 65             //5.释放资源
 66             rs.close();
 67         }
 68     }
 69 
 70     /*
 71      * 使用JDBC技术,对数据库中的表数据进行增加
 72      */
 73     private static void insert(Statement stat) throws SQLException {
 74         //拼接sql语句
 75         String sql = "INSERT INTO category(cname) VALUES('玩具')";
 76         //4.执行sql语句
 77         int row = stat.executeUpdate(sql);
 78         //5.处理结果
 79         if(row>0){
 80             System.out.println("增加数据成功!");
 81         }else{
 82             System.out.println("增加数据失败!");
 83         }
 84         
 85     }
 86 
 87     /*
 88      * 使用JDBC技术,对数据库中的表数据进行删除
 89      */
 90     private static void delete(Statement stat) throws Exception {
 91         //拼接sql语句
 92         String sql = "DELETE FROM category WHERE cid=5";
 93         //4.执行sql语句
 94         int row = stat.executeUpdate(sql);
 95         //5.处理结果
 96         if(row>0){
 97             System.out.println("删除数据成功!");
 98         }else{
 99             System.out.println("删除数据失败!");
100         }
101     }
102 
103     /*
104      * 使用JDBC技术,对数据库中的表数据进行更新
105      */
106     private static void update(Statement stat) throws Exception {
107         //拼接sql语句
108         String sql = "UPDATE category SET cname='鞋帽' WHERE cid=6";
109         //4.执行sql语句
110         int row = stat.executeUpdate(sql);
111         //5.处理结果
112         if(row>0){
113             System.out.println("更新数据成功!");
114         }else{
115             System.out.println("更新数据失败!");
116         }
117     }

 1 JDBC工具类
 2 “获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils。提供获取连接对象的方法,从而达到代码的重复利用。
 3 代码演示:
 4 public class JDBCUtils {
 5     
 6     //私有构造方法,防止外界创建对象调用方法
 7     private JDBCUtils() {
 8     }
 9     
10     //定义Connectionn变量
11     private static Connection conn;
12     
13     //保证代码只执行一次,可以放入静态代码块中
14     static{
15         try {
16             //注册驱动
17             Class.forName("com.mysql.jdbc.Driver");
18             //获取连接
19             String url="jdbc:mysql://127.0.0.1:3306/mybase4";
20             String user="root";
21             String password = "root";
22             conn = DriverManager.getConnection(url, user, password);
23         } catch (Exception e) {
24             //注意,如果连接数据库失败,停止程序
25             throw new RuntimeException(e "连接数据库失败");
26         }
27     }
28     
29     //创建一个静态方法,获取数据库连接对象,并返回
30     public static Connection getConnection(){
31         return conn;
32     }
33     
34     /*
35      * 创建一个静态方法,对资源进行释放
36      * ResultSet rs
37      * Statement stat
38      * Connection conn
39      */
40     public static void close(ResultSet rs,Statement stat,Connection conn){
41         try {
42             if(rs!=null){
43                 rs.close();
44             }
45         } catch (SQLException e) {
46             e.printStackTrace();
47         }
48         try {
49             if(stat!=null){
50                 stat.close();
51             }
52         } catch (SQLException e) {
53             e.printStackTrace();
54         }
55         try {
56             if(conn!=null){
57                 conn.close();
58             }
59         } catch (SQLException e) {
60             e.printStackTrace();
61         }
62     }
63 }

sql注入问题
SQL注入:用户输入的内容作为了SQL语句语法的一部分,改变了原有SQL真正的意义。
假设有登录案例SQL语句如下:
SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;
此时,当用户输入正确的账号与密码后,查询到了信息则让用户登录。但是当用户输入的账号为XXX 密码为:XXX’ OR ‘a’=’a时,则真正执行的代码变为:
SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’ OR ’a’=’a’;
此时,上述查询语句时永远可以查询出结果的。那么用户就直接登录成功了,显然我们不希望看到这样的结果,这便是SQL注入问题。
为此,我们使用PreparedStatement来解决对应的问题。

preparedStatement:预编译对象,是Statement对象的子类。
特点:
性能高
会把sql语句先编译
能过滤掉用户输入的关键字。

PreparedStatement预处理对象,处理的每条sql语句中所有的实际参数,都必须使用占位符?替换。
String sql = "select * from user where username = ? and password = ?";
PreparedStatement使用,需要通过以下3步骤完成:
1.PreparedStatement预处理对象代码:
获得预处理对象,需要提供已经使用占位符处理后的SQL语句
PreparedStatement psmt = conn.prepareStatement(sql)
2.设置实际参数
void setXxx(int index, Xxx xx) 将指定参数设置指定类型的值
参数1:index 实际参数序列号,从1开始。
参数2:xxx 实际参数值,xxx表示具体的类型。
例如:
setString(2, "1234") 把SQL语句中第2个位置的占位符?替换成实际参数 "1234"
3.执行SQL语句:
int executeUpdate(); --执行insert update delete语句.
ResultSet executeQuery(); --执行select语句.
boolean execute(); --执行select返回true 执行其他的语句返回false.

JDBC Java DataBase Connectivity,java数据库连接,是一种用于执行SQL语句的Java API。 JDBC是Java访问数据库的标准规范,可以为不同的关系...

首先对于JDBC连接MySQL,要了解基本的框架结构

1、修改注释内容

图片 1

选择window---->>preferences

画的比较烂,大约就是这样的结构

图片 2

然后看一下具体实现的 代码:;

选择Java---->>codestyle---->>code template---->>comments,然后双击types,修改里面的内容即可!

public class DBUtil {
 private String user = "root";
 private String password = "root";
 private String url = "jdbc:mysql://localhost:3306/mydb6";
 private static DBUtil dbUtil;
 Connection connection = null;

 // 单例:构造方法私有化
 private DBUtil() {

 }

 public synchronized static DBUtil getInstance() {
  if (dbUtil == null) {
   dbUtil = new DBUtil();
  }
  return dbUtil;
 }

 /**
  * 创建数据库连接
  */
 public Connection getConnection() {
  if (connection == null) {
   try {
    // 注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    // 获取连接
    connection = DriverManager.getConnection(url, user, password);
   } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  return connection;
 }
}

 

  上面这个是通过单例模式  建立了DBUtil这样一个类。通过这个类可以干什么呢?可以实现----数据库的连接!

图片 3

没错,Connection接口的作用就是连接数据库-
与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。

2、修改Eclipse里面的快捷键

怎样才能得到这个连接呢?--想要建立这个连接,你需要注册一个驱动---嗯~就是这个代码   Class.forName("com.mysql.jdbc.Driver");  

举例:修改复制行内容快捷键。

它是通过反射的机制来获得的,不了解反射?嗯~那你记住就完了 哈哈哈

1.点击window菜单->preferences子菜单->general->keys,进入快捷键管理界面

connection = DriverManager.getConnection(url, user, password);这一句话的是用来获取连接的 ,这三个参数分别是   数据的地址,jdbc:mysql://IP地址:端口号/数据库的名称

图片 4

嗯~然年再将一下如何通过jdbc向数据库写入数据

 

public int insertStuByStatement() {
        String sql1 = "insert into stu(sname,sage) values('aaa',1)";
        String sql2 = "insert into stu(sname,sage) values('bbb',1)";
        String sql3 = "insert into stu(sname,sage) values('ccc',1)";
        Connection connection = getConnection();// 获得数据库的连接
        Statement stmt = null;
        try {
            stmt = (Statement) connection.createStatement();
            connection.setAutoCommit(false);
            stmt.addBatch(sql1);//批量添加sql语句
            stmt.addBatch(sql2);//批量添加sql语句
            stmt.addBatch(sql3);//批量添加sql语句
            //一次性执行
            stmt.executeBatch();
            connection.commit();
            System.out.println("批处理成功");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (Exception e2) {

            }
        }
        return i;
    }

 

这里使用的statement 来实现的,写出你要操作的 sql语句。(提一下,一般这些操作都是放在DBUtil类中的额 ,这个方法我也是放在DBUtil的)。

2.在这里可以查找所有功能的快捷键,需要修改或新增时,点击需要修改或新增的命令,在binding里设置快捷键

第二步:根据上面的定义的方法获取数据库。

图片 5

下面就是获取一个Statement 对象,然后通过这个对象的stmt.executeBatch();就可以在数据库中执行刚才就的语句了,这样就做到了静态插入数据。

 

那动态插入数据是怎样的呢 ?-----那就是用到了另一个能够实现语句的对象PreparedStatement

3.设置完快捷键后,还需要设置在什么时候可以使用该快捷键,eclipse提供各种场景供选择,一般选择In Windows(即在eclipse窗口激活状态)即可

直接上代码吧 

图片 6

public int insertStu(String sname,int sage){
        String sql = "insert into stu(sname,sage) values(?,?)";
        Connection connection = getConnection();//获得数据库的连接
        PreparedStatement ps = null;
        int i = 0;
        try {
            ps  = (PreparedStatement) connection.prepareStatement(sql);
            ps.setString(1, sname);
            ps.setInt(2, sage);

            i=ps.executeUpdate();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                if (ps!=null) {
                ps.close();
                }
            } catch (Exception e2) {

            }
        }
        return i;
    }

 

定义的插入方法有了两个参数的数值

完成以上操作,点击OK即完成设置

与statement的区别在哪呢?--一个是sql字符串语句的区别,多了“?”,作用是---看下面这两行代码

图片 7

 ps.setString(1, sname);
 ps.setInt(2, sage);
 ps.set****(a,b)有两个参数,sql语句中也有两个?,所以参数a,代表的是sql语句的第几个“?”,如果参数是1,则说明sql语句中第一个“?”的位置替换为参数b,
 如果 同理如果参数是2,则说明sql语句中第一个“?”的位置替换为参数b.这样就做到了动态的插入数据,我们只要在调用插入方法的时候传入想要插入的数据就好了,不用每次都写新的sql语句。
 对于 i=ps.executeUpdate();语句,它返回的这次你的数据库操作后有有几条数据有影响.这种方法对于插入,当然是i=1了

但是对于产出和修改的就不是一定了,删除修改我直接贴代码了就不再做讲解

//修改
public int updateStu(int sage,String sname){
        String sql = "updae stu set sage = ? where sname = ?";
        Connection connection = getConnection();
        PreparedStatement ps =null;
        int i  = 0;
        try {
            ps = (PreparedStatement) connection.prepareStatement(sql);
            ps.setInt(1, sage);
            ps.setString(2, sname);

            i  = ps.executeUpdate();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                if (ps!=null) {
                ps.close();
                }
            } catch (Exception e2) {

            }
        }
        return i;
    }
    //删除
        public int deleteStu(String sname,int sage) {
            String sql = "delete from stu where sname=? and sage = ?";
            Connection conn = getConnection();//获得数据库连接
            PreparedStatement ps = null;
            int i = 0;
            try {
                ps = (PreparedStatement) conn.prepareStatement(sql);
                ps.setString(1, sname);
                ps.setInt(2,sage );

                i = ps.executeUpdate();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                try {
                    if(ps != null)
                        ps.close();
                }catch (Exception e) {
                    // TODO: handle exception
                }
            }
            return i;

        }

3、设置工作空间的编码

 

 图片 8

数据库最重要的是什么---查询数据,相对于增删改--查可能稍微繁琐一点
代码如下:

/**
     * 查询所有学生
     * @return
     */
    public ArrayList<Stu> queryStu(){
        String sql = "select * from stu ";// select *  或的字段的顺序和数据库中的是一致
        Connection conn = getConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;
        ArrayList<Stu> stus = new ArrayList<Stu>();//此集合用于存储每一个学生对象
        try {
            ps = (PreparedStatement) conn.prepareStatement(sql);
            rs = ps.executeQuery();
            //遍历rs
            while(rs.next()) {//true表示有下一条数据
                int id = rs.getInt("id");
                String sname = rs.getString("sname");
                int sage = rs.getInt("sage");
                //创建stu对象
                Stu stu = new Stu(id, sname, sage);
                //收集对象
                stus.add(stu);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            try {
                if(rs != null)
                    rs.close();
                if(ps != null)
                    ps.close();
            }catch (Exception e) {
                // TODO: handle exception
            }
        }

        return stus;
    }

 

讲一下重点的地方     ResultSet rs

null;  这个对象存储的一个查询的结果集合。select * from stu这个返回的 应该是查询的学生表中每个学生的所有数据,

所以rs就可以储存这样的一个集合,然后通过遍历得到其中的数据,将数据赋值给一个学生对对象,将对象加入到集合中,就得到可表中所有的数据~

 

这次讲的主要是基础部分,等下次继续探讨JDBC联合其他的一些操作~

Class.forName("com.mysql.jdbc.Driver");

二、JUnit单元测试

1、介绍:JUnit是一个java语言的单元测试框架。属于第三方工具,一般情况下需要导入jar包,不过多数java开发环境已经集成了JUnit作为单元测试工具。

创建“day07”java项目,并创建“cn.itcast.a_junit”包 

 图片 9

2、编写测试类,简单理解可以用于取代java的main方法

3、在测试类方法上添加注解@Test

4、注解修饰方法要求:public void 方法名(){...},方法名自定义建议test开头

图片 10

5、添加STS中集成的Junit库,鼠标点击“@Test”,使用快捷键“ctrl 1”,点击“Add Junit...”

图片 11

结果

图片 12

6、使用:选中方法右键,执行当前方法;选中类名右键,执行类中所有方法(方法必须标注@Test)

图片 13

7、常用注解

    @Test,用于修饰需要执行的方法

    @Before,测试方法前执行的方法

    @After,测试方法后执行的方法

图片 14

8、常见使用错误,如果没有添加“@Test”,使用“Junit Test”进行运行,将抛异常

图片 15

三、JDBC

1、什么是JDBC

JDBC(Java DataBase Connectivity)就是java数据库连接,简单地说就是用java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句

<1>JDBC是一种用于执行SQL语句的java API

<2>JDBC可以为多种关系数据库提供统一访问入口

<3>JDBC由一组java工具类和接口组成

2、JDBC原理

早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC。而各个厂商提供的,遵循了JDBC规范的,可以访问自数据库的API被称之为驱动。

图片 16

JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。

当然还有第三方公司专门为某一数据库提供驱动,这样的驱动往往不是开源免费的!

3、JDBC核心类(接口)介绍

JDBC中的核心类有:DriverManager、Connection、Statement和ResultSet

DriverManager(驱动管理器)的作用有两个

<1>注册驱动:这可以让JDBC知道要使用的是哪个驱动;

<2>获取Connection:如果可以获取到Connection,那么说明已经与数据库连接上了。

    Connection对象表示连接,与数据库的通讯都是通过这个对象展开的;

<3>Connection最为重要的一个方法就是用来获取Statement对象;

<4>Statement是用来向数据库发送SQL语句的,这样数据库会执行发送过来的的SQL语句

<5>void executeUpdate(String sql):执行更新操作(insert、update、delete等);

<6>ResultSet executeQuery(String sql):执行查询操作,数据库在执行查询后会返回查询结果,查询    结果就是ResultSer;

    ResultSet对象表示查询结果集,只有在执行查询操作后才会有结果集的产生。结果集是一个人二维     的表格,有行有列。操作结果集要学习移动ResultSet内部的“行光标”,以及获取当前行上的数据

<7>boolean next():使“行光标”移动到下一行,并返回移动后的行是否存在;

<8>xxx getxxx(int col):获取当前行指定列上的值,参数就是列数,列数从1开始,而不是0

4、JDBC开发步骤

4.1 导入mysql数据库的驱动jar包:

<1>创建lib目录,用于存放当前项目需要的所有jar包

<2>选择jar包,右键执行build path/Add to Build Path

图片 17

4.2 注册驱动

注册驱动就只有一句话:Class.forName("com.mysql.jdbc.Driver"),

下面的内容都是对这句代码的解释。今后我们的代码中,与注册驱动相关的代码只有这一句。

<1>分析步骤1:JDBC规范定义驱动接口:java.sql.Driver,

               MySql驱动包提供了实现类:com.mysql.jdbc.Driver 
<2>分析步骤2:DriverManager工具类,提供注册驱动的方法registerDriver(),

               方法的参数是java.sql.Driver,所以我们可以通过如下语句进行注册

               DriverManager.registerDriver(new com.mysql.jdbc.Driver());

               以上代码不推荐使用,存在两方面不足:

               1.硬编码,后期不易于程序扩展和维护

               2.驱动被注册两次

<3>分析步骤3:通常开发我们使用Class.forName()加载一个使用字符串描述的驱动类。

               如果使用Class.forName()将加载到内存,该类的静态代码将自动执行

               通过查询com.mysql.jdbc.Driver源码,我们发现Driver类“主动”将自己进行注册 

DriverManager类的registerDriver()方法的参数是java.sql.Driver,但java.sql.Driver是一个接口,实现类由mysql驱动来提供,mysql驱动中的java.sql.Driver接口的实现类为com.mysql.Driver那么注册驱动的代码如下:

    DriverManager.registerDriver(new com.mysql.jdbc.Driver());

    上面的代码虽然可以注册驱动,但是出现硬编码(代码依赖mysql驱动jar包),如果将来想连接Oracle数据库,那么必须要修改代码。并且其实这种注册驱动的方式是注册了两次驱动!

    JDBC中规定,驱动类在被加载时,需要自己“主动”把自己注册到DriverManager中,下面来看看com.mysql.jdbc.Driver类的源代码:

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch(SQLException E) {
            throw newRuntimeException("Can't register driver!");
        }
    }
……
}

com.mysql.jdbc.Driver类中的static块会创建本类对象,并注册到DriverManager中,这说明只要去加载com.mysql.jdbc.Driver类,那么就会执行这个static块,从而也就会把com.mysql.jdbc.Driver注册到DriverManager中,所以可以把注册驱动类的代码修改为加载驱动类。

Class.forName("com.mysql.jdbc.Driver");    

4.3 获取连接

代码:Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydbl","root","root")

获取连接需要两步,一是使用DriverManager来注册驱动,二是使用DriverManager来获取Connection对象。

    获取连接的也只有一句话代码:

    DriverManager.getConnection(url,username,password);

    其中username和password是登录数据库的用户名和密码

    url相对复杂一点,它是用来找到要连接数据库的“网址”,就好比你要在浏览器中查找百度时,也需要提供一个url。下面是mysql的url:

    jdbc:mysql://localhost:3306/mydbl

    JDBC规定url的格式由三部分组成,每个部分中间使用冒号分割。

    <1>第一部分是jdbc,这是固定的;

    <2>第二部分是数据库名称,那么连接mysql数据库,第二部分当然是mysql了;

    <3>第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别      由数据库服务器的IP地址(localhost)、端口号(3306),以及database名称(mybdl)组成

    下面是获取连接的语句: 

    Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/web08","root","root");

     还可以在url中提供参数:

    jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=UTF8

    useUnicode参数指定这个连接数据库的过程中,使用的字节集是Unicode字节集;

    characterEncoding参数指定java程序连接数据库的过程中,使用的字符集编码为UTF-8编码。注意,mysql中指定UTF-8编码给出的是UTF8,而不是UTF-8

4.4 获得语句执行

String sql="insert into category(cid,cname) values('c007','分类')";

Statement stmt=con.createStatement();

在得到Connection之后,说明已经与数据库连接上了,下面是通过Connection获取Statement对象的代码:

    Statement stmt=con.createStatement();

    Statement是用来向数据库发送要执行的SQL语句的

常用方法:

执行SQL语句:

    <1>int executeUpdate(String sql);---执行insert update delete语句.(DML语句)

    <2>ResultSet executeQuery(String sql);---执行select语句(DQL语句)

    <3>boolean execute(String sql);---执行select返回true,执行其他的语句返回false 

        如果返回true,需要使用getResultSet()获得查询结果

        如果返回false,需要使用getUpdateCount()获得影响行数

执行批处理:(可选)

    addBatch(String sql);

    clearBatch();

    executeBatch();

4.5 预处理对象

使用处理对象时,建议每条sql语句所有的实际参数,都使用逗号分隔

String sql="insert into category(cid,cname) values(?,?)";

PreparedStatement psmt=con.prepareStatement(sql);

常用方法:

执行SQL语句:

    <1>int executeUpdate(String sql);---执行insert update delete语句.(DML语句)

    <2>ResultSet executeQuery(String sql);---执行select语句(DQL语句)

    <3>boolean execute(String sql);---执行select返回true,执行其他的语句返回false 

设置实际参数:

    setxxx(int,T)通过setter方法将?占位符替换成实际参数

    例如:setString()实际参数类型为hi字符串

执行批处理:(可选)

    addBatch; 添加批处理的实际参数,需要调方法前执行对应setter方法

    clearBatch();

    executeBatch();

4.6 处理结果集

ResultSet就是一张二维的表格,它内部有一个“行光标”,光标默认位置在“第一行上方”,我们可以调用rs对象的next()方法把“行光标”向下移动一行,当第一次调用next()方法时,“行光标”就到了第一行记录的位置,这时就可以使用ResultSet提供的getxxx(int col)方法来获取指定列的数据了:

    rs.next();//光标移动到第一行

    rs.getInt(1);//光标移动到第一列的数据

图片 18

    当你使用rs.getInt(1)方法时,你必须可以肯定第1列的数据类型就是int类型,如果你不能肯定,那么最好使用rs.getObject(1)。在ResultSet类中提供了一系列的getxxx()方法,比较常用的方法有:

    Object getObject(int col)

    String getString(int col)

    int getInt(int col)

    double getDouble(int col)

4.7 释放资源

与IO流一样,使用后的东西都需要关闭,关闭的顺序是先得到的后关闭,后得到的先关闭

    rs.close();

    stmt.close();

    con.close;

4.8 完成查询操作代码

    public static Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url ="jdbc:mysql://localhost:3306/web08";
        return DriverManager.getConnection(url, "root", "root");
    }

    @Test
    public void query() throws Exception{
        Connectioncon = getConnection();
        Statementstmt = con.createStatement();
        String sql ="select * from user";
        ResultSet rs= stmt.executeQuery(sql);
        while(rs.next()){
            String username = rs.getString(1);
            String password = rs.getString(2);
            System.out.println(username  ", "   password);
        }
    }

4.9 规范化代码

所谓规范化代码就是无论是否出现异常,都要关闭ResultSet、Statement,以及Connection

    @Test
    public void query() {
        Connection con = null;
        Statement stmt = null;
        ResultSet rs= null;
        try {
            con = getConnection();
            stmt =con.createStatement();
            String sql = "select * from user";
            rs =stmt.executeQuery(sql);
            while(rs.next()){
                String username = rs.getString(1);
                String password = rs.getString(2);
                System.out.println(username  ", "   password);
            }
        } catch(Exceptione) {
            throw newRuntimeException(e);
        } finally {
            try {
                if(rs != null)rs.close();
                if(stmt != null) stmt.close();
                if(con != null)con.close();
            } catch(SQLExceptione) {}
        }
    }

4.10 案例:查询所有

图片 19

图片 20

5、JDBC对象介绍

5.1JDBC中的主要类(接口)

<1>DriverManager

<2>Connection

<3>Statement

<4>ResultSet

5.2 DriverManager

我们今后只需要会用DriverManager的getConnection()方法即可:

<1>Class.forName("com.mysql.jdbc.Driver");

<2>String url="jdbc:mysql://localhost:3306/web08";

<3>String username="root"

<4>String password="root"

<5>Connection con=DriverManager.getConnection(url,username,password);

注意:上面代码可能出现的两种异常:

<1>ClassNotFoundException:这个异常是在第1句上出现的,出现这个异常有两个可能:

    (1)你没有给出mysql的jar包;

    (2)你把类名打错了,查看类名是不是com.mysql.jdbc.Driver。

<2>SQLException:这个异常出现在第5句,出现这个异常就是三个参数的问题,往往username和password一般不会出错,所以需要认真查看url是否打错

    对于DriverManager.registerDriver()方法了解即可,因为我们今后注册驱动只会用                 Class.forName(),而不会使用这个方法

5.3 Connection

    Connection最为重要的方法就是获取Statement:

    (1)Statement stmt=con.createStatement();

    后面在学习ResultSet方法时,还要学习一下下面的方法

    (2)Statement stmt=con.createStatement(int,int);

5.4 Statement

    Statement最为重要的方法是:

    <1>int executeUpdate(String sql):执行更新操作,即执行insert、update、delete语句,其实

    这个方法也可以执行create table、alter table,以及drop table等语句,但我们很少会使JDBC

    来执行这些语句;

    <2>ResultSet executeQuery(String sql):执行查询语句,执行查询操作会返回ResultSet,即结果集;

    <3>boolean execute():Statement还有一个boolean execute()方法,这个方法可以用来执行       增、删、改、查所有的SQL语句,该方法返回的是boolean类型,表示SQL语句是否执行成功。

    如果使用execute()方法执行的是更新语句,那么还要调用int getUpdateCount()来获取insert、       update、delete语句所影响的行数

    如果使用execute()方法执行的是查询语句,那么还要调用ResultSet、getResultSet()来获取         select语句的查询结果

5.5 ResultSet之滚动结果集(了解)

    ResultSet表示结果集,它是一个二维的表格!ResultSet内部维护一个行光标(游标),ResultSet提供了一系列的方法来移动游标:

    <1>void beforeFirst():把光标放到第一行的前面,这也是光标默认的位置;

    <2>void afterLast():把光标放到最后一行的后面;

    <3>boolean first():把光标放到第一行的位置上,返回值表示调控光标是否成功;

    <4>boolean last():把光标放到最后一行的位置上;返回值表示调控光标是否成功

    <5>boolean isBeforeFirst():当前光标位置是否在第一行前面;

    <6>boolean isAfterLast():当前光标位置是否在最后一行的后面;

    <7>boolean isFirst():当前光标位置是否在第一行上;

    <8>boolean isLast:当前光标位置是否在最后一行上;

    <9>boolean next():把光标向下挪一行;

    <10>boolean relative(int row):相对位移,当row为正数时,表示向下移动row行,为负数时     表示向上移动row行;

    <11>boolean absolute(int row):绝对位移,把光标移动到指定行上;

    <12>int getRow():返回当前光标所有行

    上面方法分为两类,一类用来判断游标位置的,另一类是用来移动游标的。如果结果集是不可滚动的,那么只能使用next()方法来移动游标。而beforeFirst()、afterLast()、first()、last()、previous()、relative()方法都不能使用!

    结果集是否支持滚动,要从Connection类的createStatement()方法说起,也就是说创建的Statement决定了使用Statement创建的ResultSet是否支持滚动

    Statement createStatement(int resultSetType,int resultSetConcurrency)

    resultSetType的可选值:

    (1)ResultSet.TYPE_FORWARD_ONLY:不滚动结果集

    (2)ResultSet.TYPE_SCROLL_INSENSITIVE:滚动结果集,但结果集数据不会再跟随数据库而变      化;

    (3)ResultSet.TYPE_SCROLL_SENSITIVE:滚动结果集,但结果集数据不会在跟随数据库而变化

    可以看出,如果想使用滚动的结果集,我们应该选择TYPE_SCROLL_INSENSITIVE!其实很少有数据库驱动会支持TYPE_SCROLL_SENSITIVE的特性!通常我们也不需要查询到的结果集再受到数据库变化的影响

    resultSetConcurrency的可选值:

    (1)CONCUR_READ_ONLY:结果集是只读的,不能通过修改结果集而反向影响数据库;

    (2)CONCUR_UPDATABLE:结果集是可更新的,对结果集的更新可以反向影响数据库;

    通常可更新结果集这一“高级特性”我们也是不需要的!

    获取滚动结果集的代码如下:

    Connection con=Statement stmt=con.createStatement(ResultSet.TYPE.SCROLL.INSENSITIVE,CONCUR_READ_ONLY);

    String sql=....//查询语句

   ResultSet rs=stmt.executeQuery(sql);//这个结果集是可滚动的

5.6 ResultSet之获取列数据

    可以通过next()方法使ResultSet的游标向下移动,当游标移动到你需要的行时,就需要来获取该行的数据了,ResultSet提供了一系列的获取列数据的方法:

    (1)String getString(int columnIndex):获取指定列的String类型数据;

    (2)int getInt(int columnIndex):获取指定列的int类型数据

    (3)double getDouble(int columnIndex):获取指定列的double类型数据;

    (4)boolean getBoolean(int columnIndex):获取指定列的boolean类型数据

    (5)Object getObject(int columnIndex):获取指定列的Object类型的数据

    上面的方法中,参数columnIndex表示列的索引,列索引从1开始,而不是0,这第一点与数组不同,如果你清楚当前列的数据类型,那么可以使用getInt()之类的方法来获取,如果你不清楚列的类型,那么你应该使用getObject()方法类获取

    ResultSet还提供了一套通过列名称来获取列数据的方法:

    (1)String getSting(String columnName):获取名称为columnName的列的String数据;

    (2)int getInt(String columnName):获取名称为columnName的列的int数据

    (3)double getDouble(String columnName):获取名称为columnName的列的double数据;

    (4)boolean getBoolean(String columnName):获取名称为columnName的列的boolean数据;

    (5)Object getObject(String columnName):获取名称为columnName的列的Object数据

6、SQL注入

6.1 什么是SQL攻击

    在需要用户输入的地方,用户输入的是SQL语句的片段,最终用户输入的SQL片段与我们dao中写的SQL语句合成一个完整的SQL语句!例如用户在登录时输入的用户名和密码都是为SQL语句的片段

6.2 演示SQL攻击 

    首先我们需要创建一张用户表,用来存储用户的信息

    CREATE TABLE user(
    uid CHAR(32)PRIMARY KEY,
    username   VARCHAR(30)UNIQUE KEY NOT NULL,
    PASSWORD   VARCHAR(30)
    );
 
    INSERT INTO userVALUES('U_1001', 'zs', 'zs');
    SELECT * FROM user;

    现在用户表中只有一行记录,就是zs。

    下面我们写一个login()方法

    public void login(String username, String password) {
        Connectioncon = null;
        Statementstmt = null;
        ResultSet rs= null;
        try {
            con =JdbcUtils.getConnection();
            stmt =con.createStatement();
            String sql = "SELECT * FROM user WHERE "  
                    "username='"  username   
                    "'and password='"   password   "'";
            rs =stmt.executeQuery(sql);
            if(rs.next()){
                System.out.println("欢迎"  rs.getString("username"));
            } else {
                System.out.println("用户名或密码错误!");
            }
        } catch(Exception e) {
            throw newRuntimeException(e);
        } finally {
            JdbcUtils.close(con,stmt, rs);
        }       
    }

    下面是调用这个方法的代码:

login("a' or 'a'='a", "a'or 'a'='a");

    这行当前会使我们登录成功,因为输入的用户名和密码是SQL语句片段,最终与我们的login()方法中的SQL语句组合在一起,我们来看看组合在一起的SQL语句

SELECT * FROM tab_user WHERE username='a'or 'a'='a' and password='a' or 'a'='a'

6.3防止SQL攻击

    过滤用户输入的数据中是否包含非法字符;

    分步校验,先使用用户名来查询用户,如果查找到了,再比较密码;

    使用PreparedStatement

6.4 PreparedStatement是什么?

    PreparedStatement叫预编译声明

    PreparedStatement是Statement的子接口,你可以使用PreparedStatement来替换Statement

    PreparedStatement的好处:

    (1)防止SQL攻击

    (2)提高代码的可读性,以及可维护性

    (3)提高效率

6.5 PreparedStatement的使用

    使用Connection的prepareStatement(String sql):即创建它时就让它与一条SQL模板绑定;

    调用PreparedStatement的setXXX()系列方法为问号设置值;

    调用executeUpdate()或executeQuery()方法,但要注意,调用没有参数的方法;

String sql = “select * from tab_studentwhere s_number=?”;
PreparedStatement pstmt =con.prepareStatement(sql);
pstmt.setString(1, “S_1001”);
ResultSet rs = pstmt.executeQuery();
rs.close();
pstmt.clearParameters();
pstmt.setString(1, “S_1002”);
rs= pstmt.executeQuery();

   在使用Connection创建PreparedStatement对象时需要给出一个SQL模板,所谓SQL模板就是有“?”的SQL语句,其中“?”就是参数

    在得到PreparedStatement对象后,调用它的setxxx()方法为“?”赋值,这样就可以得到把模板变成一条完整的SQL语句,然后再调用PreparedStatement对象的executeQuery()方法获取ResultSet对象

    注意:PreparedStatement对象独有的executeQuery()方法是没有参数的,而Statement的executeQuery()是需要参数(SQL语句)的。因为在创建PreparedStatement对象时已经让它与一条SQL模板绑定在一起了,所以在调用它的executeQuery()和executeUpdate()方法时就不再需要参数了。

    PreparedStatement最大的好处就是在于重复使用同一模板,给予其不同的参数来重复的使用它。这才是真正提高效率的原因

    所依,在以后的开发中,无论什么情况,都去使用PreparedStatement,而不是使用Statement.

7、使用JDBC完成分类表CRUD(增删改查)的操作

7.1 案例分析

使用JDBC对分类表category进行增删改查操作

7.2 工具类

“获得连接”和“释放资源”两次代码将在之后的增删改查所有功能中都存在,开发中一般遇到此种情况,将采用工具类的方法进行抽取,从而达到代码的重复利用

图片 21

7.3 获得连接

图片 22

图片 23

7.4 释放资源

如果释放资源采用依次关闭三个对象,那么第一个对象关闭时抛出了异常,后面两个对象将无法成功释放资源,通常我们使用try-catch块进行处理

方法1:多个try-catch块,将资源释放,容易理解

图片 24

图片 25

方法2:try-catch-finally嵌套,资源释放时如果出错,将通知调用者

图片 26

7.5 使用properties配置文件

开发中获得连接的4个参数(驱动、URL、用户名、密码)通常都存在配置文件中,方便后期维护,程序如果需要更换数据库,只需要修改配置文件即可

通常情况下,我们习惯使用properties文件,此文件我们将做如下要求:

<1>文件位置:任意,建议src下

<2>文件名称:任意,扩展名为properties

<3>文件内容:一行一组数据,格式是“key=value”

    (1)key命名自定义,如果是多个单词,习惯使用点分割。例如:jdbc.driver

    (2)value值不支持中文,如果需要使用非英文字符,将进行unicode转换

7.5.1 创建配置文件

右键/New/File,输入“db.properties”文件名

图片 27

图片 28

7.5.2 加载配置文件:ResourceBundle对象

ResourceBundle提供getBundle()方法用于只提供properties文件即可,之后使用getString(key)通过key获得value的值

图片 29

图片 30

图片 31

7.5.3 获得连接

图片 32

7.5.4 加载配置文件:Properties对象(可选)

对应properties文件处理,开发中也会使用Properties对象进行。在v3版本中我们将采用加载properties文件获得流,然后使用Properties对象进行处理

图片 33

图片 34

图片 35

7.6 实现

7.6.1 模板

图片 36

图片 37

7.6.2 添加:insert into

图片 38

7.6.3 更新:update...set

图片 39

图片 40

7.6.4 删除:delete

图片 41

7.6.5 通过ID查询

图片 42

四、JDBC连接池

1、案例分析

实际开发中“获得连接”或“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况我们采用连接池技术,来共享连接Connection

2、连接池概述

2.1 概念

用池来管理Connection,这样可以重复使用Connection。有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection"归还"给池。池就可以再利用这个Connection对象了。

图片 43

2.2 规范

java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序才可以方便的切换不同厂商的连接池!

常见的连接池:DBCP、C3P0

3、自定义连接池

3.1 案例分析

我们编写自定义连接池,需要完成一下步骤

3.1.1 创建连接池实现(数据源),并实现接口javax.sql.DataSource。因为我们只使用该接口中getConnection()方法,简化本案例,我们将自己提供方法1,而没有实现接口

3.1.2 提供一个集合,用于存放连接,因为移除/添加操作过多,所以选择LinkedList

3.1.3 本案例在静态代码块中,为连接池初始化3个连接

3.1.4 之后程序如果需要连接,调用实现类的getConnection(),本方法将从连接池(容器List)获得连接。为了保证当前连接只能提供给一个线程使用,所以我们将连接先从连接池中移除

3.1.5 当用户使用完连接,释放资源时,不执行close()方法,而是将连接添加到连接池中

3.2 案例实现

图片 44

3.2.1 提供容器及初始化

图片 45

3.2.2 获得连接

图片 46

图片 47

3.2.3 归还连接

图片 48

3.2.4 测试使用

为了体现连接池优势,我们将采用多线程并发访问,使同一个连接在不同的时段,被不同的线程使用

图片 49

图片 50

3.3 自定义连接池:方法增强

3.3.1 需求

自定义连接池中存在严重问题,用户调用getConnection()获得连接后,必须使用release()方法进行连接的归还,如果用户调用conn.close()将连接真正的释放,连接池中将出现无连接可用。

此时我们希望,即使用户调用了close()方法,连接仍归还给连接池。close()方法原有功能释放资源,期望功能:将当前连接归还连接池。说明close()方法没有我们希望的功能,我们将对close()方法进行增强,从而实现将连接归还给连接池的功能

3.3.2 方法增强总结

<1>继承,子类继承父类,将父类的方法进行腹复写,从而进行增强

   使用前提:必须有父类,且存在继承关系

<2>装饰者设计模式,此设计模式专门用于增强方法

   使用前提:必须有接口

   缺点:需要将接口的所有方法都实现

<3>动态代理:在运行时动态的创建代理类,完成增强操作。与装饰者相似

   使用前提:必须有接口

   难点:需要反射技术

<4>字节码增强,运行时创建目标类子类,从而进行增强

   常见第三方框架:cglib、javassist等

3.3.3 装饰者设计模式

设计模式:专门为解决一类问题,而编写的固定格式的代码。

装饰者固定结构:接口A,已知实现类C,需要装饰者创建代理类B

<1>创建类B,并实现接口A

<2>提供类B的构造方法,参数类型为A,用于接收A接口的其他实现类(C)

<3>给类B添加类型为A成员变量,用于存放A接口的其他实现类

<4>增强需要的方法

<5>实现不需要增强的方法,方法体重调用成员变量存放的其他实现类对应的方法

图片 51

3.3.4 实现

3.3.4.1 装饰类

图片 52

图片 53

3.3.4.2 使用装饰者(包装类)

将由DriverManager创建的连接,使用装饰类包装一下,然后添加到连接池中,构造方法中将容器pool传递进去,方便连接的归还

图片 54

3.3.4.3 使用连接

图片 55

4、C3P0连接池

C3P0是开源免费的连接池,目前使用它的开源项目有:Spring、Hibernate等。使用第三方工具需要导入jar包,C3P0使用时还需要添加配置文件c3p0-config.xml

4.1 导入jar包

我们使用的0.9.2版本,需要导入2个jar包

图片 56

4.2 配置文件

<1>配置文件名称:c3p0-config.xml(固定)

<2>配置文件位置:src(类路径)

<3>配置文件内容:命名配置

图片 57

配置文件内容:默认配置

图片 58

图片 59

4.3 常见配置项

图片 60

图片 61

4.4 编写工具类

C3P0提供核心工具类:ComboPooledDataSource,如果要使用连接池,必须创建该类的实例对象。

图片 62

图片 63

图片 64

5、DBCP连接池

DBCP也是一个开源的连接池,是Apache Common成员之一,在企业开发中也比较常见,tomcat内置的连接池

5.1 导入jar包

图片 65

5.2 配置文件

<1>配置文件名称:*.properties

<2>配置文件位置:任意,建议src(classpath/类路径)

<3>配置文件内容:properties不能编写中文,不支持在STS中修改,必须使用记事本修改内容,否则中文注释就乱码了

图片 66

5.3 常见配置项

图片 67

图片 68

5.4 编写工具类

图片 69

图片 70

五、使用DBUtils增删改查的操作

1、案例分析

如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,我们将采用apache commons组件一个成员:DEUtils。

DBUtils就是JDBC的简化开发工具包。需要使用技术:连接池(获得连接),SQL语句都没有少

2、案例相关知识

2.1、JavaBean组件

javaBean就是一个类,在开发中常用于封装数据。具有如下特性

<1>需要实现接口:java.io.Serializable,通常偷懒省略了。

<2>提供私有字段:private类型 字段名;

<3>提供getter/setter方法

<4>提供无参构造

图片 71

图片 72

3、DBUtils完成CRUD

3.1 概述

DBUtils是java编程中的数据库操作实用工具,小巧简单实用

DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码

DBUtils三个核心功能介绍

<1>QueryRunner中提供对sql语句操作的API

<2>ResultSetHandler接口,用于定义select操作后,怎样封装结果集

<3>DBUtils类,它就是一工具类,定义了关闭资源与事务处理的方法

3.2 QueryRunner核心类

<1>QueryRunner(DataSource ds),提供数据源(连接池),DBUtils底层自动维护连接connection

<2>update(String sql,Object...params),执行更新数据

<3>query(String sql,ResultSetHandler<T>rsh,Object...params),执行查询

3.3 ResultSetHandler结果集处理类

图片 73图片 74

3.4 DBUtils工具类

closeQuietly(Connection conn) 关闭连接,如果有异常,try后不抛

commitAndCloseQuietly(Connection conn) 提交并关闭连接

rollbackAndCloseQuietly(Connection conn) 回滚并关闭连接

3.5 实现

3.5.1 添加

图片 75

图片 76

3.5.2 更新

图片 77

3.5.3 删除

图片 78图片 79

3.5.4 通过id查询

图片 80

3.5.5 查询所有

图片 81

图片 82

3.5.6 总记录数

图片 83

本文由关于我们发布,转载请注明来源:JDBC的连接mySql的基本知识