JDBC

jdbc:java操纵数据库技术

在jdk中 : 定义了多个接口,接口中约定了一些规则(抽象方法)

数据库厂商 : 定义一些类,实现接口,并且按约定实现接口中的方法

接口简介

java.sql.Connection : 规定数据库的连接
java.sql.PreparedStatement:sql发送工具
java.sql.ResultSet: 处理结果集
java.sql.Driver: 数据库驱动
java.sql.DriverManager: 数据库驱动管理

JDBC主要步骤

PLSql操纵数据库的步骤

1.连接数据库 用户名 密码 数据库库名(xe)

2.创建sql发送窗口

3.编写sql.发送sql

4.接收并处理结果集

5.关闭客户端

JDBC

1.加载驱动

2.获得数据库连接对象(Connection对象)

3.获取sql发送工具对象(PreparedStatement对象)

4.编写sql,发送sql

5.接收并处理结果集对象(ResultSet对象)

6.关闭资源 ResultSet PreparedStatement Connection

第一个JDBC代码

需求:向t_person表中添加一条数据

create table t_person(
  id number(3) primary key,
  name varchar2(50),
  age  number(3),
  sex  number(1), ---0表示女性  1表示男性
  mobile varchar2(20),
  address varchar2(100)     
)

insert into t_person values(100,'王xx',18,0,'12312341234','河南郑州')
导包: ojdbc6.jar
1.项目---右键----new---folder---lib---将ojdbc6.jar放入lib
2.jar包---右键---build path-----add to  build  path


class JDBC{
public static void main(String[] args) throws Exception {
        //1.加载驱动  
        Class.forName("oracle.jdbc.OracleDriver");
        //2.获得数据库连接对象(Connection对象)
        /**
         * url:指明数据库的路径
         *     jdbc:oracle:thin:@电脑ip:端口号:数据库库名
         *     jdbc:oracle:thin:@localhost:1521:xe
         */
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
        System.out.println(conn);
        //3.获取sql发送工具对象(PreparedStatement对象)
        String sql = "insert into t_person values(111,'小杰',16,0,'11122222222','河南郑州')";//sql不加;
        PreparedStatement pstm = conn.prepareStatement(sql);
        //4.发送sql   pstm.executeUpdate()  作用于dml(增删改)语句     返回值这次sql操作影响了表中的几条数据
        int executeUpdate = pstm.executeUpdate();
        System.out.println("影响表中数据:"+executeUpdate);
        //5.接收并处理结果集对象(ResultSet对象)
        //6.关闭资源  ResultSet PreparedStatement Connection  后开的先关
   pstm.close();
   conn.close();
   
    }



}

JDBC的查询

ResultSet

  结果集对象

需求:查询id=100的信息

public static void main(String[] args) throws Exception {
        //加载驱动
        Class.forName("oracle.jdbc.OracleDriver");
        //获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
        //获取sql发送工具对象
        PreparedStatement pstm = conn.prepareStatement("select * from t_person ");
        //发送sql 
        ResultSet rs = pstm.executeQuery();
        //接收并处理结果集
        //将指针下移一行航
        while(rs.next()) {
            //代表有值
            int id = rs.getInt("id");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            int sex = rs.getInt(4);
            String mobile = rs.getString(5);
            String addr = rs.getString(6);
            System.out.println("id="+id+"   name="+name+"   age="+age+"   sex="+sex+"     mobile="+mobile+"   addr="+addr);
        }
        //关闭资源
        rs.close();
        pstm.close();
        conn.close();
    }

JDBC的动态参数设置

1.拼接字符串

问题:不能防止sql注入

2.设置占位符

  占位符:?

  sql当中需要动态写入值的地方

public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("id:");
        int id = sc.nextInt();
        System.out.println("name:");
        String name = sc.next();
        System.out.println("age:");
        int age = sc.nextInt();
        System.out.println("sex:");
        int sex = sc.nextInt();
        System.out.println("mobile:");
        String mobile = sc.next();
        System.out.println("address:");
        String addr = sc.next();
        //1.加载驱动  
        Class.forName("oracle.jdbc.OracleDriver");
        //2.获得数据库连接对象(Connection对象)
        /**
         * url:指明数据库的路径
         *     jdbc:oracle:thin:@电脑ip:端口号:数据库库名
         *     jdbc:oracle:thin:@localhost:1521:xe
         */
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
        System.out.println(conn);
        //3.获取sql发送工具对象(PreparedStatement对象)
        String sql = "insert into t_person values(?,?,?,?,?,?)";//sql不加;
        PreparedStatement pstm = conn.prepareStatement(sql);
        //给站位符赋值
        pstm.setInt(1, id);
        pstm.setString(2, name);
        pstm.setInt(3, age);
        pstm.setInt(4, sex);
        pstm.setString(5, mobile);
        pstm.setString(6, addr);
        
        
        //4.发送sql   pstm.executeUpdate()  作用于dml(增删改)语句     返回值这次sql操作影响了表中的几条数据
        int executeUpdate = pstm.executeUpdate();
        System.out.println("影响表中数据:"+executeUpdate);
        //5.接收并处理结果集对象(ResultSet对象)
        //6.关闭资源  ResultSet PreparedStatement Connection  后开的先关
   pstm.close();
   conn.close();
   
    }

pstm预编译

实体类

一个实体类对应了数据库中的一张表

实体类中的一个属性对应了表中的一个字段

一个书体类对象对应了表中的一行数据

实体类的存放位置: com.baizhi.entity

Dao

date access object:数据库访问对象

public class BookDao {
    //添加
    public void insert(Book b) {
        //获取数据库连接对象
        Connection conn = null;
        //获取sql发送工具对象
        PreparedStatement pstm = null;
        try {
            //加载驱动
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            pstm = conn.prepareStatement("insert into t_book values(seq_book.nextval,?,?,?)");
            //给占位符赋值
            pstm.setString(1, b.getName());
            pstm.setString(2, b.getAuthor());
            pstm.setDouble(3, b.getPrice());
            //发送sql
            pstm.executeUpdate();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println("添加失败,原因为:");
            e.printStackTrace();
        } finally {
            //接收并处理结果集
            //关闭资源
            if (pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        }
        
    }
    //根据id删除
    public void delete(int id) {
        //获取数据库连接对象
        Connection conn = null;
        //获取sql发送工具对象
        PreparedStatement pstm = null;
        try {
            //加载驱动
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            pstm = conn.prepareStatement("delete from t_book where book_id = ?");
            //给占位符赋值
            pstm.setInt(1, id);
            //发送sql
            pstm.executeUpdate();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println("删除失败,原因为:");
            e.printStackTrace();
        } finally {
            //接收并处理结果集
            //关闭资源
            if (pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    //修改
    public void update(Book b) {
        Connection conn = null;
        PreparedStatement pstm = null;
        try {
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            pstm = conn.prepareStatement("update t_book set book_name=?,AUTHOR=?,PRICE=? where book_id=?");
            pstm.setString(1, b.getName());
            pstm.setString(2, b.getAuthor());
            pstm.setDouble(3, b.getPrice());
            pstm.setInt(4, b.getId());
            pstm.executeUpdate();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if (pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
    }
    //根据id查询一个
    public Book selectById(int id) {
        Book book =  null;
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            book = new Book();
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            pstm = conn.prepareStatement("select * from t_book where book_id = ?");
            pstm.setInt(1, id);
            rs = pstm.executeQuery();
            if(rs.next()) {
                book.setId(rs.getInt("book_id"));
                book.setName(rs.getString("book_name"));
                book.setAuthor(rs.getString("author"));
                book.setPrice(rs.getDouble("price"));
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }    
            }
            if (pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        }
        return book;
    }
    //查询全部
    public List<Book> selectAll(){
        List<Book> list = new ArrayList<Book>();
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            pstm = conn.prepareStatement("select * from t_book");
            rs = pstm.executeQuery();
            while(rs.next()) {
                Book book = new Book();
                book.setId(rs.getInt("book_id"));
                book.setName(rs.getString("book_name"));
                book.setAuthor(rs.getString("author"));
                book.setPrice(rs.getDouble("price"));
                list.add(book);
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }    
            }
            if (pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        }
        return list;
    }
}

ORM

Object Realtioonal Mapping:对象关系映射

主要含义:使数据库中的数据以对象的形式在程序中流转

dao+实体类=ORM

接口编程



项目的包结构

com.baizhi.entity ----- 实体类

com.baizhi.dao ------- dao的接口

com.baizhi.dao.impl ----- dao的实现类

com.baizhi.test ----- 测试类

 

JDBCUtil

编写JDBC的工具类,将创建连接以及关闭连接等每个dao方法当中都要重复编写的代码(获取连接,关闭连接)给封装起来(封装成一个方法),每当dao要使用这段代码时,就调用JDBCUtil当中的方法即可

位置:com.baizhi.util

第一版

public class JDBCUtil {
    //加载驱动.获取连接
    public static Connection getConn() {
        Connection conn = null;
        try {
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        return conn;
    }
    
    
    //关闭资源    
    public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(pstm != null) {
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

第二版

第一版问题

第一版解决办法

public class JDBCUtil {
    //加载驱动.获取连接
    public static Connection getConn() {
        Connection conn = null;
        try {
            //创建properties
            Properties pro = new Properties();
            //获取输入流
            InputStream is = JDBCUtil.class.getResourceAsStream("/JDBCUtil.properties");
            //读取JDBCUtil.properties
            pro.load(is);
            //获取键值对
            String className = pro.getProperty("className");
            String url = pro.getProperty("url");
            String user = pro.getProperty("user");
            String pwd = pro.getProperty("pwd");
            Class.forName(className);
            conn = DriverManager.getConnection(url, user, pwd);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        return conn;
    }
    
    
    //关闭资源    
    public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(pstm != null) {
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

第三版

第二版的问题

  • 每次调用getConnection,都会执行一遍读取配置文件操作,影响程序的运行效率

解决方案:

  将读取配置文件的操作,放置到静态代码块中,保证读取文件的操作有且必须执行1遍

public class JDBCUtil {
    private static String  className;
    private static String  url;
    private static String  user;
    private static String  pwd;
    static {
        //创建properties
        Properties pro = new Properties();
        //获取输入流
        InputStream is = JDBCUtil.class.getResourceAsStream("/JDBCUtil.properties");
        //读取JDBCUtil.properties
        try {
            pro.load(is);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //获取键值对
        className = pro.getProperty("className");
        url = pro.getProperty("url");
        user = pro.getProperty("user");
        pwd = pro.getProperty("pwd");
        //关流
        try {
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //加载驱动.获取连接
    public static Connection getConn() {
        Connection conn = null;
        try {
            
            Class.forName(className);
            conn = DriverManager.getConnection(url, user, pwd);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        return conn;
    }
    
    
    //关闭资源    
    public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(pstm != null) {
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

项目的三层结构

视图层(view)

作用:完成与用户的交互,接收用户输入的信息,向用户展示信息

技术:HTML CSS JS JQuery....目前使用主函数代替

业务层(service)

作用:根据功能需求,调用dao,完成逻辑判断

编码过程:马上学

持久层(dao)

作用:将数据持久化的保存在数据库,从数据库提取数据

编码过程:已经学了

 

业务层详解

存放位置:com.baizhi.service --- service的接口

com.baizhi.service.impl --- service的实现类

项目编程步骤

1.建项目

2.导入jar包

3.导入工具类

a. JDBCUtil.java ------ com.baizhi.util

b.JDBCUtil.properties ----- src

4.建表

5.建实体类 ------ com.baizhi.entity

6.dao

a.dao的接口 ------ com.baizhi.dao

b.dao的实现类 ----- com.baizhi.dao.impl

7.测试dao

a. 测试类 ------- com.baizhi.test

8.service

a.service的接口 ---- com.baizhi.service

b.service的实现类 ----- com.baizhi.service.impl

9.测试service

a. 测试类 ------- com.baizhi.test

service事务控制

什么叫事务

含义:在一个功能(一系列的sql操作),要么全部成功,要么全部失败

例:

范大头老师在5月20号时,要给女朋友转500元,为了过光棍劫

service{
转账(){
  try{
      conn.setAutoCommit(false);
//1.从范大头的账户中-500元
  //2.给女朋友+500元
  conn.commit();
  }catch(Exception e){
      conn.rollback();
      throw new RuntimeException(e);
  }        
}    
}

JDBC控制事务

jdbc的事务控制
默认每完成一次sql操作,自动提交一次事务


手动控制事务
开启手动控制事务: conn.setAutoCommit(false);

提交事务:  conn.commit();

回滚事务: conn.rollback();

解决service和dao的连接不相同问题

方法一:将conn作为dao方法中的参数传入

interface XXDao{
void insert(User user, Conncetion conn);

}

class XXservice{
insert(User user){
  Conncetion conn = JDBCUtil.getConn()
  XXDao dao = new XXDaoImpl();
  dao.insert(user,conn);    
}
}

缺点:

1.将连接对象定义在了Dao方法声明中,强耦合

2.修改的代码太多了

方法二 : Threadlocal(储存空间)

1.有效范围

在同一个线程中有效 ---- 存的时间
存一个键值对(线程对象,value) ---- 存内容的多少

2.怎么存(方法)

tl.set(value)

3.怎么取(方法)

tl.get();

4.怎么移除(方法)

tl.remove();

JDBCUtilFinal

public class JDBCUtil {
    private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); 
    private static String className;
    private static String url;
    private static String user;
    private static String pwd;
    static {
        //创建properties
        Properties pro = new Properties();
        //获取输入流
        InputStream is = JDBCUtil.class.getResourceAsStream("/JDBCUtil.properties");
        //读取JDBCUtil.properties
        try {
            pro.load(is);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //获取键值对
         className = pro.getProperty("className");
         url = pro.getProperty("url");
         user = pro.getProperty("user");
         pwd = pro.getProperty("pwd");
    }
    //加载驱动.获取连接
    public static Connection getConn() {
        if (tl.get() == null) {
            try {
                Class.forName(className);
                Connection conn = DriverManager.getConnection(url, user,pwd);
                tl.set(conn);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } 
        return tl.get();
    }
    
    
    //关闭资源    
    public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                throw new RuntimeException(e);
            }
        }
        if(pstm != null) {
            try {
                pstm.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                throw new RuntimeException(e);
            }
        }
        if(conn != null) {
            try {
                conn.close();
                tl.remove();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                throw new RuntimeException(e);
            }
        }
    }
}

注意:

1.在dao中不能关闭conn

2.在service中关闭conn

JUint单元测试

步骤:

1.添加@Test注解,方法上添加

2.引入JUnit jar包

 

3.定义方法

要求: 无参无返回值,方法名随意的方法

4.运行方法时.点击方法名,右键------runs ------ Junit Test

注意事项

1.类名 方法名都不要叫Test

以粮为纲全面发展
原文地址:https://www.cnblogs.com/alexliuf/p/13788244.html