JDBC操作MySQL数据库

复习一下jdbc操作mysql数据库

画图软件的分析:

maven依赖

xml 复制代码
<dependencies>
    <!--junit依赖-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>

    <!--jdbc驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    
    <!--lombok依赖-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.36</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

建表语句

sql 复制代码
CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(255) NOT NULL,
  `email` varchar(100) DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

pojo

java 复制代码
@Data
public class User {
    private Integer id;
    private String userName;
    private String password;
    private String email;
    private Date createAt;
    private Date updateAt;
}

JDBCUtils

java 复制代码
public class JDBCUtils {
    private static String url;
    private static String user;
    private static String password;

    static {
        try {
            Properties properties = new Properties();
            // 反射获取路径
            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            URL resource = classLoader.getResource("jdbc.properties");
            String path = resource.getPath();
            properties.load(new FileReader(path));
            url = properties.getProperty("jdbc.url");
            user = properties.getProperty("jdbc.username");
            password = properties.getProperty("jdbc.password");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     * @return 连接
     */
    public static Connection getConnection(){
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url,user,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }return connection;
    }

    /**
     * 关闭连接
     *
     * @param
     * @param connection
     */
    public static void close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 关闭连接
     * @param statement
     * @param connection
     */
    public static void close(Statement statement,Connection connection){
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭查询连接
     * @param resultSet
     * @param statement
     * @param connection
     */
    public static void close(ResultSet resultSet,Statement statement, Connection connection){
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

DateUtils

java 复制代码
/**
 * 日期工具类
 */
public class DateUtils {

    // 常用日期格式
    public static final String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_DATE = "yyyy-MM-dd";
    public static final String FORMAT_TIME = "HH:mm:ss";
    public static final String FORMAT_CN = "yyyy年MM月dd日 HH:mm:ss";

    /**
     * 获取当前时间
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    /**
     * 获取当前时间字符串
     */
    public static String getCurrentDateStr() {
        return formatDate(new Date(), FORMAT_FULL);
    }

    /**
     * 日期格式化
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * 字符串转日期
     */
    public static Date parseDate(String dateStr, String pattern) {
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return null;
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取指定日期的开始时间
     */
    public static Date getStartOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定日期的结束时间
     */
    public static Date getEndOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取两个日期之间的天数
     */
    public static long getDaysBetween(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return 0;
        }
        long diff = Math.abs(date1.getTime() - date2.getTime());
        return diff / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取两个日期之间的小时数
     */
    public static long getHoursBetween(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return 0;
        }
        long diff = Math.abs(date1.getTime() - date2.getTime());
        return diff / (60 * 60 * 1000);
    }

    /**
     * 获取两个日期之间的分钟数
     */
    public static long getMinutesBetween(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return 0;
        }
        long diff = Math.abs(date1.getTime() - date2.getTime());
        return diff / (60 * 1000);
    }

    /**
     * 判断日期是否在指定范围内
     */
    public static boolean isDateInRange(Date date, Date startDate, Date endDate) {
        if (date == null || startDate == null || endDate == null) {
            return false;
        }
        return date.after(startDate) && date.before(endDate);
    }

    /**
     * 获取指定日期是星期几
     */
    public static String getWeekDay(Date date) {
        if (date == null) {
            return null;
        }
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int w = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        return weekDays[w];
    }

    /**
     * 获取指定日期是星期几(数字)
     */
    public static int getWeekDayNum(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 获取指定日期是当月的第几天
     */
    public static int getDayOfMonth(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定日期是当年的第几天
     */
    public static int getDayOfYear(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 获取指定日期是当月的第几周
     */
    public static int getWeekOfMonth(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_MONTH);
    }

    /**
     * 获取指定日期是当年的第几周
     */
    public static int getWeekOfYear(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取指定日期所在月份的天数
     */
    public static int getDaysInMonth(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定日期所在年份的天数
     */
    public static int getDaysInYear(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
    }

    /**
     * 判断是否是闰年
     */
    public static boolean isLeapYear(Date date) {
        if (date == null) {
            return false;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    }

    /**
     * 获取指定日期加上指定天数后的日期
     */
    public static Date addDays(Date date, int days) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, days);
        return calendar.getTime();
    }

    /**
     * 获取指定日期加上指定月数后的日期
     */
    public static Date addMonths(Date date, int months) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, months);
        return calendar.getTime();
    }

    /**
     * 获取指定日期加上指定年数后的日期
     */
    public static Date addYears(Date date, int years) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, years);
        return calendar.getTime();
    }

    /**
     * 获取指定日期加上指定小时数后的日期
     */
    public static Date addHours(Date date, int hours) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hours);
        return calendar.getTime();
    }

    /**
     * 获取指定日期加上指定分钟数后的日期
     */
    public static Date addMinutes(Date date, int minutes) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    /**
     * 获取指定日期加上指定秒数后的日期
     */
    public static Date addSeconds(Date date, int seconds) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return calendar.getTime();
    }
}

jdbc.propert

properties 复制代码
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/leetcode_sql_db
jdbc.username=root
jdbc.password=123456

测试类

java 复制代码
public class TestJdbcInsertWithGeneratedKeys {

    private Connection connection;

    @Before
    public void getConnection() {
        connection = JDBCUtils.getConnection();
    }

    @Test
    public void testConnection() {
        //测试数据库链接是否正常
        assertNotNull("数据库连接失败", connection);
    }



    @Test
    public void testInsert() {
        //编写sql语句
        String sql = "insert into " +
                "leetcode_sql_db.users" +
                "(username,password,email)" +
                "values (?,?,?)";

        try {
            //预编译sql语句
            PreparedStatement ps = connection.prepareStatement(sql);
            //填充字段
            ps.setString(1, "sunwukong");
            ps.setString(2, "1234");
            ps.setString(3, "sunwukong.outlook.com");

            //执行sql语句
            //使用 executeUpdate() 而不是 execute()
            //对于 INSERT、UPDATE 和 DELETE 操作,应该使用 executeUpdate() 方法。该方法返回一个整数值,表示受影响的行数。
            int execute = ps.executeUpdate();
            if (execute==1) {
                System.out.println("插入成功");
            }else {
                System.out.println("插入失败");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //关闭连接
            JDBCUtils.close(connection);
        }

    }


    @Test
    public void testDelete() {
        //编写sql
        String sql = "delete from users where id=?";


        try {
            //预编译sql
            PreparedStatement ps = connection.prepareStatement(sql);

            //填充字段
            ps.setInt(1, 14);

            //执行sql
            int res = ps.executeUpdate();
            if (res == 1) {
                System.out.println("删除成功");
            }else{
                System.out.println("删除失败");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭连接
            JDBCUtils.close(connection);
        }

    }


    @Test
    public void testUpdate() {
        /*
         created_at | timestamp    | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED                             |
        | updated_at | timestamp    | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP
        更新的时候不需要更新update_at,建表的时候设置了
        */
        //预编译sql
        String sql=
                "update " +
                "leetcode_sql_db.users " +
                "set " +
                "username=?,password=?,email=? " +
                "where " +
                "id=?";

        try {
            //预编译sql语句
            PreparedStatement ps = connection.prepareStatement(sql);
            //填充sql
            ps.setString(1, "apple");
            ps.setString(2, "999");
            ps.setString(3, "apple.qq.com");
            ps.setInt(4,13);

            //执行sql
            int res = ps.executeUpdate();

            if (res == 1) {
                System.out.println("更新成功");
            }else{
                System.out.println("更新失败");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭连接
            JDBCUtils.close(connection);
        }

    }


    @Test
    public void testSelectOne() {
        //编写sql
        String sql =
                "select * from users where id=?";


        try {
            //预编译sql语句
            PreparedStatement ps = connection.prepareStatement(sql);
            //填充字段
            ps.setInt(1, 13);
            //执行sql
            //拿到结果集
            ResultSet rs = ps.executeQuery();

            //处理结果集

            List<Object> list = new ArrayList<>();
            while (rs.next()) {
                //拿到id
                int id = rs.getInt(1);

                //拿到username
                String username = rs.getString(2);

                //拿到password
                String password = rs.getString(3);

                //拿到email
                String email = rs.getString(4);
                //拿到create_at
                String createAt = DateUtils.formatDate(rs.getTimestamp(5), DateUtils.FORMAT_CN);
                //拿到update_at
                String updateAt = DateUtils.formatDate(rs.getTimestamp(6), DateUtils.FORMAT_CN);

                //封装进行List中

                list.add(id);
                list.add(username);
                list.add(password);
                list.add(email);
                list.add(createAt);
                list.add(updateAt);
            }
            //打印List
            System.out.println(list);


        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //关闭连接
            JDBCUtils.close(connection);
        }
    }

    @Test
    public void selectAll() {
        //编写sql

        //起别名
        String sql = "select " +
                "id,username as userName,password,email,created_at as createAt, updated_at as updateAt " +
                "from users";
        try {

            //预编译sql
            PreparedStatement ps = connection.prepareStatement(sql);
            //填充sql

            //执行sql
            ResultSet rs = ps.executeQuery();
            //定义容器存储
            List<User> userList = new ArrayList<>();
            while (rs.next()) {
                User user = new User();

                user.setId(rs.getInt("id"));
                user.setUserName(rs.getString("userName"));
                user.setPassword(rs.getString("password"));
                user.setEmail(rs.getString("email"));
                user.setCreateAt(rs.getTimestamp("createAt"));
                user.setUpdateAt(rs.getTimestamp("updateAt"));
                userList.add(user);
            }

            //遍历list
            for (User user : userList) {
                System.out.println(user);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //关闭连接
            JDBCUtils.close(connection);
        }



        

        
        

        

    }


    @Test
    public void testGeneratedKeys() {
        //我要干什么???
        //测试数据库的自增主键,要拿到数据库的自增主键。

        //编写sql
        String sql = "insert into users(username, password, email) values (?,?,?)";

        try {
            //预处理sql
            //注意这里,是拿到自增主键
            PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            //填充
            ps.setString(1, "hututu");
            ps.setString(2, "123123123");
            ps.setString(3, "hututu.outlook.com");
            //执行sql
            int res = ps.executeUpdate();
            if (res > 0) {
                //拿到自增主键
                ResultSet rs = ps.getGeneratedKeys();
                if (rs.next()) {
                    long generatedKey = rs.getLong(1);
                    System.out.println("刚刚插入的行的自增主键为:" + generatedKey);
                }else{
                    throw new SQLException("创建用户失败!!!");
                }
            }else{
                System.out.println("插入失败!!!");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //关闭连接
            JDBCUtils.close(connection);
        }
    }



}

AI关于JDBC时间的总结

在 JDBC 中,getDate, getTimestamp, 和 getTime 是用于从 ResultSet 对象中获取日期和时间数据的方法。每个方法都有其特定的用途和返回的数据类型。以下是这三个方法的详细分析:

1. getDate

  • 签名java.sql.Date getDate(String columnLabel)java.sql.Date getDate(int columnIndex)
  • 作用:从指定的列中获取日期部分(年、月、日),不包括时间信息。
  • 返回值 :一个 java.sql.Date 对象,它只包含日期信息,没有时间部分。
  • 适用场景:当你只需要处理日期而不需要时间时使用。
java 复制代码
java.sql.Date date = resultSet.getDate("date_of_birth");

注意,java.sql.Date 是基于 java.util.Date 的子类,但是它被设计为仅表示日期而不含时间信息。然而,在实践中,数据库中的日期可能仍然包含时间信息,但这些信息会被忽略或丢失。

2. getTimestamp

  • 签名java.sql.Timestamp getTimestamp(String columnLabel)java.sql.Timestamp getTimestamp(int columnIndex)
  • 作用:从指定的列中获取完整的日期和时间信息(包括年、月、日、小时、分钟、秒及纳秒)。
  • 返回值 :一个 java.sql.Timestamp 对象,它包含了完整的日期和时间信息。
  • 适用场景:当你需要精确到秒甚至纳秒的时间点时使用。
java 复制代码
java.sql.Timestamp timestamp = resultSet.getTimestamp("created_at");

java.sql.Timestamp 扩展了 java.util.Date 并增加了对纳秒的支持。因此,它可以存储比标准 Date 更精细的时间信息。

3. getTime

  • 签名java.sql.Time getTime(String columnLabel)java.sql.Time getTime(int columnIndex)
  • 作用:从指定的列中获取时间部分(小时、分钟、秒),不包括日期信息。
  • 返回值 :一个 java.sql.Time 对象,它只包含时间信息,没有日期部分。
  • 适用场景:当你只需要处理时间而不需要日期时使用。
java 复制代码
java.sql.Time time = resultSet.getTime("start_time");

类似于 java.sql.Datejava.sql.Time 也是基于 java.util.Date 的子类,但它被设计为仅表示时间而不含日期信息。

总结

  • getDate : 适用于只需要日期的情况,返回 java.sql.Date 对象。
  • getTimestamp : 当你需要完整的日期和时间信息时使用,返回 java.sql.Timestamp 对象,支持更高精度的时间。
  • getTime : 只需要时间信息时使用,返回 java.sql.Time 对象。

注意事项

  • 在 JDBC 中,确保你使用的获取方法与数据库表中字段的实际类型相匹配。例如,如果你尝试从一个 TIMESTAMP 类型的字段调用 getDate 方法,可能会丢失时间信息;反之,如果从 DATE 类型的字段调用 getTimestamp 方法,则可能得到不可预期的结果。

  • 现代 Java 应用程序通常会使用 LocalDate, LocalTime, 和 LocalDateTime(来自 java.time 包)来代替旧的 java.sql.Date, java.sql.Time, 和 java.sql.Timestamp,因为它们提供了更强大且易于使用的 API 来处理日期和时间。要将 JDBC 返回的对象转换为这些新的类型,可以先将其转换为对应的 Instant 或者直接通过 toInstant() 方法进行转换。例如:

java 复制代码
LocalDate localDate = resultSet.getDate("date_column").toLocalDate();
LocalDateTime localDateTime = resultSet.getTimestamp("timestamp_column").toLocalDateTime();

这有助于提高代码的可读性和维护性,并避免一些潜在的问题。

相关推荐
苏墨瀚6 分钟前
SQL语言的散点图
开发语言·后端·golang
一只韩非子5 小时前
一句话告诉你什么叫编程语言自举!
前端·javascript·后端
沈二到不行5 小时前
多头注意力&位置编码:完型填空任务
人工智能·后端·deepseek
追逐时光者5 小时前
C# 中比较实用的关键字,基础高频面试题!
后端·c#·.net
GoGeekBaird5 小时前
一文搞懂:Anthropic发布MCP重要更新,告别长连接
后端·操作系统
Asthenia04126 小时前
面试问题分析:为什么Java能实现反射机制,其他语言不行?
后端
拳布离手6 小时前
fastgpt工作流探索
后端
Asthenia04126 小时前
IO 多路复用详解:从概念->系统调用-> Java 在NIO中实现
后端
Asthenia04126 小时前
场景题-Java 单体项目优化:应对高并发客户端访问的性能与线程安全分析
后端
安然无虞6 小时前
31天Python入门——第5天:循环那些事儿
开发语言·后端·python