datetime对应的jdbc mysql_JDBC核心实战案例

c198772c571b22c93cb8db19c394c6b3.png
Java数据库连接核心代码,这一篇就够了。​

文章适合于刚入行不久或即将开始学习JAVA的小伙伴,你将看到鲜活的真实错误案例、代码开发需求清单,还有学习的注意事项。

ea2d3a9076c8d1eda71713388944483f.png

JDBC概述

JDBC概述Java Database Connectivity的缩写,即JAVA数据库连接,规范客户端如何访问第三方数据库。
(以下以JDBC_mysql代码为例)
学习资源路径[视频教程,5个半小时]:https://www.bilibili.com/video/BV1Bt41137iB(动力节点杜老师,课讲得还是很赞的!)
前置学习JAVA语言基础有全面的学习、熟悉mysql增删改查的核心代码
核心主题实现JAVA对mysql数据库的DQL(查)、DML(增、删、改),以及TCL(事务控制)
完整六步骤注册驱动-->获取连接-->获取数据库操作对象-->执行访问-->处理结果集-->释放资源
JDBC概述Java Database Connectivity的缩写,即JAVA数据库连接,规范客户端如何访问第三方数据库。
(以下以JDBC_mysql代码为例)
学习资源路径[视频教程,5个半小时]:https://www.bilibili.com/video/BV1Bt41137iB(动力节点杜老师,课讲得还是很赞的!)
前置学习JAVA语言基础有全面的学习、熟悉mysql增删改查的核心代码
核心主题实现JAVA对mysql数据库的DQL(查)、DML(增、删、改),以及TCL(事务控制)
完整六步骤注册驱动-->获取连接-->获取数据库操作对象-->执行访问-->处理结果集-->释放资源
https://www. bilibili.com/video/BV1B t41137iB
JDBC概述Java Database Connectivity的缩写,即JAVA数据库连接,规范客户端如何访问第三方数据库。
(以下以JDBC_mysql代码为例)
学习资源路径[视频教程,5个半小时]:https://www.bilibili.com/video/BV1Bt41137iB(动力节点杜老师,课讲得还是很赞的!)
前置学习JAVA语言基础有全面的学习、熟悉mysql增删改查的核心代码
核心主题实现JAVA对mysql数据库的DQL(查)、DML(增、删、改),以及TCL(事务控制)
完整六步骤注册驱动-->获取连接-->获取数据库操作对象-->执行访问-->处理结果集-->释放资源

JDBC应用开发框架

cde82bcf783908ebf8b03aa27095389b.png

注:JDBC本质是很多工具类的集成,意味着很多代码不仅复用、同时服务多个应用场景,需要结合灵活配置;

本节重点阐述图示第一层、第二层的核心代码错误案例;第三层、第四层在下节Servlet核心练习题进行说明。

核心案例一:JDBC基础层--注册数据库驱动、获取数据库连接

1、注册数据库驱动适合参考底层写成静态代码;

2、IO流结合Properties属性配置文件,实现灵活访问不同数据库,而不用修改代码和重新部署。

//以下是修改前代码
public class JDBCutil {
    private static Connection conn;//下方定义静态方法,此处也要对应静态变量
    private static PreparedStatement ps;
     private static ResultSet rs;    //注册驱动写成静态方法,实现mysql驱动注册(不需要再Driver实例化)一旦加载就会运行此块而且驱动一直存在。
    static {
        try {
            Class c = class.forName(com.mysql.jdbc.DriverManage);//错误标记_Class大写;括号类是方法传参要加引号; 而不是DriverManage
        } catch (ClassNotFoundException e) {
            e.printStackTrace();}
    }
    public static Connection getConnection() throws IOException, SQLException {//
        Properties pro = new Properties();
        FileInputStream fis = null;
        fis = new FileInputStream("/homework/src/jdbc.properties");//错误标记_有时候报错是因为没有写完整路径
        pro=fis_read();//错误标记_ pro=fis_read(),虽然是形似
        String url = pro.getProperty("url");
        String username = pro.getProperty("username");
        String password = pro.getProperty("password");
        Connection conn = DriverManager.getConnection(url, username, password);
  return conn;    }
}
//-----------以下是对应的jdbc.properties配置文件代码-------------------------------------//
url=jdbc:mysql://localhost:3306/JDBCTest##错误标记_有中文时要在配置文件的url字符串加上“?characterEncoding=gbk”
username=root
password=123
//以下是修改后代码
public class JDBCutil {
    private static Connection conn;//下方定义静态方法,此处也要对应静态变量
    private static PreparedStatement ps;
     private static ResultSet rs;    //注册驱动写成静态方法,实现mysql驱动注册(不需要再Driver实例化)一旦加载就会运行此块而且驱动一直存在。
    static {
        try {
            Class c = Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();}
    }
    public static Connection getConnection() throws IOException, SQLException {//
        Properties pro = new Properties();
        FileInputStream fis = null;
        fis = new FileInputStream("/home/psdz/Documents/05javascript/ideasave/Servlet/homework/src/jdbc.properties");
        pro.load(fis);
        String url = pro.getProperty("url");
        String username = pro.getProperty("username");
        String password = pro.getProperty("password");
        Connection conn = DriverManager.getConnection(url, username, password);
  return conn;    }
}
//-----------以下是对应的jdbc.properties配置文件代码-------------------------------------//
url=jdbc:mysql://localhost:3306/JDBCTest?useUnicode=true&characterEncoding=utf-8
username=root
password=123
```

核心案例二:JDBC服务--数据库新增数据

重点要掌握INSERT语句的提前编译和占位补值等,另外实际项目中经常将查询的数据落到一个实体类,并存在集合中。

//以下是修改前代码
Connection conn = JDBCutil.getConnection();//错误标记_不适合作为全局变量,因为服务层每个方法都会涉及释放资源,再调用会报“资源关闭后不能再操作的错误”
public static int insertData(USERS ur) throws IOException, SQLException {
    String sql = "INSERT INTO USERS (UserName,PassWord,Sex,Email) VALUES(?,?,?,?)";
    int tag = 0;
    try {
       ps = conn.prepareStatement(sql);
        ps.setString(1, ur.getUserName());
        ps.setString(2, ur.getPassWord());
        ps.setString(3, ur.getSex().charAt(0));//错误标记_避免使用char类型,尽管此处不报错,但后面还有地方会涉及到此处的隐患
       ps.setString(4, ur.getEmail());
        tag = ps.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();    }
       close();//错误标记_null状态下不用关闭,也因此写在try内
    if (tag > 0) {
        System.out.println("成功存储数据到JDBC");
        return 1;    }else {
        return 0;
    }
}
//USERS类包含UserId、UserName、PassWord、Sex、Email属性,一级封装方法。省略具体代码
//以下是修改后代码
public static int insertData(USERS ur) throws IOException, SQLException {
    String sql = "INSERT INTO USERS (UserName,PassWord,Sex,Email) VALUES(?,?,?,?)";
    int tag = 0;
    try {
       conn = JDBCutil.getConnection();
       ps = conn.prepareStatement(sql);
        ps.setString(1, ur.getUserName());
        ps.setString(2, ur.getPassWord());
        ps.setString(3, ur.getSex());
       ps.setString(4, ur.getEmail());
        tag = ps.executeUpdate();
       close();
   } catch (SQLException e) {
        e.printStackTrace();    }
    if (tag > 0) {
        System.out.println("成功存储数据到JDBC");
        return 1;    }else {
        return 0;
    }
}
//USERS类包含UserId、UserName、PassWord、Sex、Email属性,一级封装方法。省略具体代码

核心案例三:JDBC服务--数据库查询

重点要掌握SELECT的提前编译和占位补值等,另外实际项目中经常将查询的数据落到一个实体类,并存在集合中。

//以下是修改前代码
public static List queryData(){
    String sql = "SELECT * FROM USERS WHERE existTag = 1";//existTag逻辑删除标签
    try {
       conn = JDBCutil.getConnection();
        ps = conn.prepareStatement(sql);
        rs = ps.executeQuery();
        List mylist = new ArrayList();
        while(rs.next()){
           USERS ur = new USERS();
            ur.setUserId(rs.getInt("userId"));//错误标记_字段首字母大写,否则封装的方法命名看起来会有区别
           ur.setUserName(rs.getString("UserName"));
            ur.setPassWord(rs.getString("PassWord"));
            ur.setSex(rs.getString("Sex"));
            ur.setEmail(rs.getString("Email"));
            mylist.add(ur);
        }
    } catch (SQLException | IOException e) {
        e.printStackTrace();    }
        close();//错误标记_null状态下不用关闭,也因此要写在try内
        return mylist; //错误标记_null状态下不用返回list,也因此要写在try内
    return null;//引用方要配if(非null)
}
//USERS类包含UserId、UserName、PassWord、Sex、Email属性,一级封装方法。省略具体代码
//以下是修改后代码
public static List queryData(){
    String sql = "SELECT * FROM USERS WHERE existTag = 1";//existTag逻辑删除标签
    try {
       conn = JDBCutil.getConnection();
        ps = conn.prepareStatement(sql);
        rs = ps.executeQuery();
        List mylist = new ArrayList();
        while(rs.next()){
           USERS ur = new USERS();
            ur.setUserId(rs.getInt("UserId"));
           ur.setUserName(rs.getString("UserName"));
            ur.setPassWord(rs.getString("PassWord"));
            ur.setSex(rs.getString("Sex"));
            ur.setEmail(rs.getString("Email"));
            mylist.add(ur);
        }
        close();
        return mylist;
    } catch (SQLException | IOException e) {
        e.printStackTrace();    }
    return null;//引用方要配if(非null)
}
//USERS类包含UserId、UserName、PassWord、Sex、Email属性,一级封装方法。省略具体代码

核心案例四:JDBC服务--数据库更新&逻辑删除

逻辑删除是一种涉及规范,不让存入的数据被真实删除。通过加一个标签字段实现对“数据是否显示”的一个条件判断。

public static int deleteData(String wheresentence){

    //物理删除:DELETE FROM table_name [WHERE Clause];逻辑删除改标记

    String sql = "UPDATE USERS SET ExistTag=0 " + wheresentence;//错误标记_SQL字符串末尾不能少一个空格

    int rowtag = 0;

    try {

        conn = JDBCutil.getConnection();

        ps = conn.prepareStatement(sql);

        rowtag = ps.executeUpdate();

        close();

    } catch (SQLException | IOException e) {

        e.printStackTrace();

    }

    if (rowtag > 0) {

        System.out.println("成功逻辑删除数据");    }

    return rowtag;}

核心案例五:JDBC服务--事务控制

事务控制是为了保持数据的完整性,避免一批数据中个别异常数据影响中断后,实际改动了前面一部分数据。

属性setAutoCommit()默认是true,要在操作数据库前改成false,并在操作结束后提交。

public static void main(String[] args) throws IOException, SQLException {

    var conn = JDBCutil.getConnection();

    PreparedStatement ps =null;

    ResultSet rs = null;

      try {

       conn.setAutoCommit(false);

        String sql = "update t_trans SET AccountBalance=AccountBalance+? where AccountName=?";

        ps = conn.prepareStatement(sql);

        //第一次占位改值

        ps.setString(2,"zs");

        ps.setDouble(1,-5000);

        int tag = ps.executeUpdate();

        System.out.println("修改"+tag+"行数据进行中");

 

       //制造空指针异常,为了看事务被中断的效果

        //String k = null;

        //k.toString();

 

       //第二次占位改值

        ps.setString(2,"zs");

        ps.setDouble(1,10000);

        tag += ps.executeUpdate();

        System.out.println(tag == 2? "连续修改两次数值成功":"连续修改两次数值失败");

        //事务自动提交重新开启

        conn.commit(); 

    } catch (SQLException throwables) {

        throwables.printStackTrace();   }

    //释放资源

    JDBCutil.close(rs,ps,conn);

}

核心案例六:JDBC服务--释放资源写成单独方法

释放资源的方法适合和其他方法一起写在JDBC服务层上,过程中涉及到的对象由全局变量生成,减少不必要的代码重复

释放的顺序与对象对象的顺序相反,依次是:ResultSet-->PreparedStatement-->Connection

public static void close(ResultSet rs, Statement ps, Connection conn){

    if(rs!=null){

        try{

            rs.close();

        }catch(SQLException e){

            e.printStackTrace();        }

    }

    if(ps!=null){

        try{

            ps.close();

        }catch(SQLException e){

            e.printStackTrace();        }

    }

    if(conn!=null){

        try{

            conn.close();

        }catch(SQLException e){

            e.printStackTrace();        }

    }

}

最后,谢谢查看,更多同类核心实战案例请查看往期文章。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值