JDBC

来源:互联网 发布:ubuntu 提权root 编辑:程序博客网 时间:2024/06/04 23:32

JDBC (java database connection)

    作用:是由sun公司提供的一套 jdbc api 可以使用纯java代码连接"任意"数据库

数据库连接操作

    1.加载驱动        驱动:数据库厂商根据sun公司提供的接口 完成的对自己公司数据库连接的实现        Class.forName("oracle.jdbc.OracleDriver");        //加载驱动,注册Driver,利用反射原理    2.获取数据库连接(java.sql.Connection)        //getConnection(   (协议:ip地址:端口号:数据库名字),用户名,密码   )        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "ami", "ami");    3.获取Statement对象,发送sql语句(java.sql.Statement)        Statement st = conn.createStatement();    //Statement 接口代表了一个数据库的状态        executeUpdate(String sql):int        //返回值的作用,经常用来判断实际更新值是否与预期更新值相符        executeQuery(String sql):ResultSet            //当已知查询返回单条记录时使用if(rs.next())即可            while( rs.next() ){   // next()代表是否有一条数据  true代表有 进入while循环  false代表没有 不会进入while循环                int userid = rs.getInt("userid");                String uname = rs.getString("uname");                String pwd = rs.getString("upwd");                System.out.println( userid + " " + uname + " " + pwd );            }    4.关闭数据库连接(释放资源)        rs.close(); sta.close(); con.close();        依次依赖        按先ResultSet结果集,后Statement,最后Connection的顺序关闭资源,        因为Statement和 ResultSet 是需要连接时才可以使用的,        所以在使用结束之后有可能其它的 Statement 还需要连接,不能现关闭 Connection

PreparedStatement(Statement的子类)

    使用Statement出现的问题:i.效率低 因为创建过多的字符串对象    ii.sql注入    //"aa"和123' or '1'='1    PreparedStatement ps = conn.prepareStatement(String sql);    //预加载sql语句        占位符 ?    //填充sql语句    //将SQL语句中取值发生变化的部分用占位符(?)代替        //给?赋值(也称参数绑定)        ps.setXXX(第几个占位符,值);    //第几个占位符:“?”出现的次数           空值处理:如果要设置某个?取值为null,需要做如下操作:           ps.setObject(4, null); // 这种较好理解,建议使用           ps.setNull(4, java.sql.Types.DECIMAL);           // 第2参数为?对应列的数据类型,常量    模糊查询:        eg:String sql=" select * from emp where ename like ?";            PreparedStatement ps = conn.prepareStatement(sql);            ps.setString(1,"%M%");    //强调:%的位置不是写在?附近,而是通过setString方法调用时传入

封装重复代码 DBUtils.java

    工具类:XxxUtils.java    //内部常写静态方法    java中的配置文件:xxx.properties        1)properties文件中格式采用key=value的形式        2)properties文件中的注释使用#开头        3)properties文件中不能出现中文(习惯上都是以ISO-8859-1编码)    //工具类,内部常写静态方法    public class DBUtils {        private static Properties pro = new Properties();    //获取Properties对象,需要设置static,类加载时分配空间    且    静态方法中只能调用静态属性        static{    //设置静态代码块,类加载时执行一次,只需要读取一次配置文件            InputStream is=null;            try {                is = new FileInputStream("src\\jdbc.properties");    //读取文件                pro.load(is);    //加载输入流            } catch (Exception e) {e.printStackTrace();            }finally{                if(is!=null){    //关闭读写流                    try{                        is.close();                    }catch(Exception e) {e.printStackTrace();}                }            }        }        // 声明一个静态的ThreadLocal变量,泛型表示它只能存取Connection类型的变量        private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();    //定义ThreadLocal对象        public static Connection getConnection(){    //静态方法,获取数据库连接            Connection conn = tl.get();    //先获取conn对象,如果是null,则继续执行,否则要直接返回            try {                if(conn==null){                    Class.forName(pro.getProperty("Driver"));    //加载驱动    //根据key值获取value值                    conn = DriverManager.getConnection(pro.getProperty("url"),pro.getProperty("username"),pro.getProperty("userpassword"));    //获取数据库连接                    tl.set(conn);    //保存conn对象到ThreadLocal中                }            } catch (Exception e) {e.printStackTrace();}            return conn;        }        public static void close(ResultSet rs,Statement st,Connection conn){    //静态方法,关闭资源            try {                if(rs!=null)rs.close();                if(st!=null)st.close();                if(conn!=null){                    conn.close();                    // 连接关闭后移除Thread中的conn对象                    tl.remove();    //清除ThreadLocal对象,防止对下一个线程造成破坏                }                } catch (SQLException e) {e.printStackTrace();}        }    }关闭资源:    由于Service(Biz) 和 Dao 公用了一个数据库连接,所以要在最后关闭数据库连接    如果中途关闭数据库连接,则会出现数据库连接已关闭这样的异常    在Biz中统一关闭数据库连接        DBUtils.close(null,null,conn);    在Dao中关闭ResultSet,Statement,但不关闭Connection        DBUtils.close(rs,ps,null);

实体类 把数据库的数据存到的对象中

    根据主键查询数据库后,会得到一组相关数据,这些数据共同描述了Java里关于一个对象的属性信息,    所以将这组数据提取封装成一个整体,方便数据在java程序之间的传递。    这个对象一般称为实体(entity,也称为JavaBean)。    Java实体类型与数据库对应关系:        Java实体类        ?     数据库表        实体类实例      ???      表中一条记录        实体类OID        ?     表主键        实体类普通属性    ?      表中列    标准实体Bean定义的语法要求:        属性全部私有        提供get/set方法        提供无参构造方法    //最好也提供有参构造方法        实现Serializable接口        对于可以为空的属性,定义时选择包装类型,以表示 null 值

Dao层(数据访问层) (database access object) 数据库访问模型

    对一张表做增删改查等操作   ---    写到一个 类中        命名规范:BookDao.java

Biz层(业务逻辑层)(Service) (Business Object)

    主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计    避免写重复的代码,因为有些功能需要同时增删除改查等操作,所以直接在业务层重复调用即可    命名规范:BookBiz.java | BookService.java

view层(视图层/显示层)

    主要完成数据的录入和结果的展示    它面向的群体是真正的用户,主要负责接收用户的访问请求,收集完成请求所需数据    当处理结束后,向用户展示执行结果

事务

    如果在一个事务中有多条sql语句, 我们希望某一条sql语句如果执行是失败了。    那么刚才执行成功的sql语句 能够(撤销执行)回滚    JDBC里默认的事务提交策略是执行成功一条记录就提交一次    conn.setAutoCommit(boolean a);    //true自动提交,false手动提交        注意:此方法一经设置,永久生效。        经由这个conn执行的命令的结果都需要手动提交,不需要反复设置。    conn.commit();    conn.rollback();    //在Biz层回滚    conn.getAutoCommit();    //获取当前提交状态ThreadLocal        --为了保证Service(Biz) 中的  Connection 对象 和 Dao中的 Connection 对象是同一个    在当前自己的线程中保存一个对象到ThreadLocal中,    过一会,在当前线程中可以取出来刚才保存的对象    ThreadLocal<E> tl = new ThreadLocal<E>();    tl.set(value);    //保存对象    tl.get();        //取出对象    tl.remove();    //清除ThreadLocal的对象

日期数据处理

    如何得到一个java.util.Date对象        方法1:从字符串转换为日期            String dateStr = "1999-10-10";            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");            java.util.Date d = sdf.parse(dateStr);        方法2:从日历对象得到日期            Calendar c = Calendar.getInstance(); // 日历对象            c.set(1999,11,23);            java.util.Date d2 = c.getTime();        方法3:从一个毫秒值得到日期            java.util.Date d3 = new java.util.Date(System.currentTimeMillis()));    如何得到一个java.sql.Date对象    //获得java.sql.Time, java.sql.Timestamp与此类似           long time = new java.util.Date().getTime();  // 拿到毫秒时           // 通过毫秒值构造子类型对象            java.sql.Date sd = new java.sql.Date(time);       如何得到一个字符串时间值        java.util.Date  date = new java.util.Date();        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");        String time = sdf.format(date);