Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(下)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)

Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)(上):https://developer.aliyun.com/article/1580591

8 Service 业务

8.1 什么是业务

代表用户完成的一个业务功能,可以由一个或多个DAO的调用组成。(软件所提供的一个功能都叫业务)

8.2 转账业务开发

转账业务分析

image.png

public class AccountServiceImpl implements AccountService {
    AccountDao accountDao = new AccountDaoImpl();
    @Override
    public String zhuanZhang(String fromName, String password, String toName, double money) {
        try {
            //1、验证我方用户密码
            Account account = accountDao.selectAccount(fromName);
            if(account == null){
                return "用户名不存在";
            }
            if(!account.getPassword().equals(password)){
                return "用户密码不正确";
            }
            //2、验证余额
            if(account.getMoney() < money){
                return "用户余额不足";
            }
            //3、验证对方用户
            if(accountDao.selectAccount(toName) == null){
                return "对方用户名不存在";
            }
            //4、我方扣钱
            accountDao.updateAccount(fromName,-money);

            System.out.println(10/0);

            //5、对方加钱
            accountDao.updateAccount(toName,money);

            return "转账成功";
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return "转账失败";
    }
}

9 事务

在JDBC 中,获得 Connection 对象开始事务–提交或回滚–关闭连接。其事务操作是

  • conn.setAutoCommit(false);//设置事务为手动提交
  • conn.commit();//手动提交事务
  • conn.rollback();//手动回滚事务

9.1 转账业务实现

public class AccountServiceImpl2 implements AccountService {
    AccountDao accountDao = new AccountDaoImpl();
    @Override
    public String zhuanZhang(String fromName, String password, String toName, double money) {
        Connection conn = JDBCUtils.getConnection();
        try {           
            //1、验证我方用户密码
            Account account = accountDao.selectAccount(fromName);
            if(account == null){
                return "用户名不存在";
            }
            if(!account.getPassword().equals(password)){
                return "用户密码不正确";
            }
            //2、验证余额
            if(account.getMoney() < money){
                return "用户余额不足";
            }
            //3、验证对方用户
            if(accountDao.selectAccount(toName) == null){
                return "对方用户名不存在";
            }
            //4、我方扣钱
            accountDao.updateAccount(fromName,-money);
            //System.out.println(10/0);
            //5、对方加钱
            accountDao.updateAccount(toName,money);
            //提交事务
             conn.commit();
            return "转账成功";
        } catch (Exception throwables) {
            throwables.printStackTrace();
           try {
                //回滚事务
                conn.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        return "转账失败";
    }
}

注意:此时Service中的Connection与Dao中的Connection对象不一致,无法实现事务回滚

9.2 解决方案1:传递 Connection

  • 如果使用传递Connection,容易造成接口污染(BadSmell)。
  • 定义接口是为了更容易更换实现,而将 Connection定义在接口中,会造成污染当前接口。

9.3 解决方案2:ThreadLocal

  • 可以将整个线程中(单线程)中,存储一个共享值。
  • 线程拥有一个类似 Map 的属性,键值对结构。

9.4 使用ThreadLocal更新JDBC工具类

/**
 * ThreadLocal<T>:能保存对象,能保证在同一个线程下获取到的对象是同一个
 *     set(T);
 *     get();
 *     remove();
 */
static ThreadLocal<Connection> tl = new ThreadLocal<>();

public static Connection getConnection(){
    //1、从ThreadLocal获取Connection
    //2、获取获取到了connection对象直接返回
    //3、创建Connection对象并存到ThreadLocal中,在进行返回
    Connection conn = tl.get();
    try {
        if(conn == null){
            conn = DriverManager.getConnection(url,username,password);
            tl.set(conn);
        }
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
    return conn;
}

此时需要注意,如果关闭了Connetion连接,但是在ThreadLocal中还是保存着Connetion对象。下次会获取到一个已经关闭的Connection对象,所以需要从ThreadLocal中移除

9.5 事务封装

将事务的开启、提交、回滚都封装在工具类中,业务层调用即可。

 //封装事务操作的三个方法
public static void begin(){
    //1、获取Connection对象
    Connection conn = getConnection();
    try {
        //2、开启事务
        conn.setAutoCommit(false);
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
}
public static void commit(){
    //1、获取Connection对象
    Connection conn = getConnection();
    try {
        //2、提交事务
        conn.commit();
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }finally {
        try {
            //3、关闭Connection资源
            conn.close();
            //从ThreadLocal中将connection移除掉
            tl.remove();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}
public static void rollback(){
    //1、获取Connection对象
    Connection conn = getConnection();
    try {
        //2、回滚事务
        conn.rollback();
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }finally {
        try {
            //3、关闭Connection资源
            conn.close();
            //从ThreadLocal中将connection移除掉
            tl.remove();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

9.6 最终的转账业务

public class AccountServiceImpl2 implements AccountService {
    AccountDao accountDao = new AccountDaoImpl();
    @Override
    public String zhuanZhang(String fromName, String password, String toName, double money) {
        try {
            //开启事务
            JDBCUtils.begin();
            //1、验证我方用户密码
            Account account = accountDao.selectAccount(fromName);
            if(account == null){
                return "用户名不存在";
            }
            if(!account.getPassword().equals(password)){
                return "用户密码不正确";
            }
            //2、验证余额
            if(account.getMoney() < money){
                return "用户余额不足";
            }
            //3、验证对方用户
            if(accountDao.selectAccount(toName) == null){
                return "对方用户名不存在";
            }
            //4、我方扣钱
            accountDao.updateAccount(fromName,-money);
            //System.out.println(10/0);
            //5、对方加钱
            accountDao.updateAccount(toName,money);
            //提交事务
            JDBCUtils.commit();
            return "转账成功";
        } catch (Exception throwables) {
            throwables.printStackTrace();
            //回滚事务
            JDBCUtils.rollback();
        }
        return "转账失败";
    }
}

10 三层架构

三层架构原理

image.png

三层架构下包结构

image.png

11 单元测试

11.1 单元测试

/**
 * 单元测试:对已经编写完成的类、模块、方法进行测试
 
 * 使用步骤:
 *  1、导入单元测试的两个jar包(与驱动包导入一致)
 *  2、编写方法进行测试
 
 * 常用的注解:
 *    @Test         单元测试的方法
 *    @Before       在单元测试方法之前执行
 *    @After        在单元测试方法之后执行
 *    @BeforeClass  在类加载之前执行
 *    @AfterClass   在类卸载之后执行
 *
 * 单元测试需要注意的问题
 *    1、@BeforeClass测试的方法必须要加static修饰
 *    2、单元测试的方法不能有参数,不能有返回值
 *    3、不能再单元测试中写Scanner输入内容  
 */
@BeforeClass
public static void testBeforeClass(){
    System.out.println("BeforeClass类加载的时候执行");
}

@Before
public void testBefore(){
    System.out.println("Before在单元测试方法之前执行(自动执行)");
}

@Test
public void test01(){
    System.out.println("单元测试");
}
@After
public void testAfter(){
    System.out.println("After在单元测试方法之后执行(自动执行)");
}
@AfterClass
public static void testAfterClass(){
    System.out.println("BeforeClass类卸载的时候执行");
}

执行结果

BeforeClass类加载的时候执行
Before在单元测试方法之前执行(自动执行)
单元测试
After在单元测试方法之后执行(自动执行)
BeforeClass类卸载的时候执行

11.2 实际应用

在实际开发过程中,我们需要对写好的DAO层代码、Service层代码进行测试

一般就是对DAO、Service层中的每一个方法进行测试

public class AccountTest {
    @Test
    public void testZhuanZhang(){
        AccountService accountService = new AccountServiceImpl2();
        String s = accountService.zhuanZhang("jack","123","rose",200);
        System.out.println(s);
    }
}

12 连接池

12.1 Druid连接池

在程序初始化时,预先创建指定数量的数据库连接对象存储在池中。当需要连接数据库时,从连接池中取出现有连接;使用完毕后,也不会进行关闭,而是放回池中,实现复用,节省资源。

  • 创建 db.properties 配置文件。
  • 引入druid的jar 文件,添加到类路径

12.2 db.properties

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///java2303?useSSL=false
username=root
password=123456
#初始化连接   (初始化连接池的,里面默认就已经存在了20个Connection连接)
initialSize=20
#最大连接数量  (当初始的20个连接不够的时候,最大会创建到50个)
maxActive=50
#最小空闲连接  (当连接池中的连接,没有被使用,就会减少到5个)
minIdle=5
#超时等待时间  (当连接数超过最大连接数,会等待5秒,如果5秒后还没有空闲连接,就会抛出异常)
maxWait=5000

12.3 最终版JDBC工具类

DruidDataSourceFactory 导包com.alibaba.druid.pool

public class JDBCUtils {
    //定义数据库连接池
    private static DataSource dataSource;

    //初始化连接池对象
    static{
        try {
            Properties properties = new Properties();
            InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
            properties.load(in);
            //初始化连接池对象
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //返回连接池对象
    public static DataSource getDataSource(){
        return dataSource;
    }
    //使用ThreadLocal保证Connection在同一个线程下唯一
    static ThreadLocal<Connection> tl = new ThreadLocal<>();
    public static Connection getConnection(){
        Connection conn = tl.get();
        try {
            if(conn == null){
                conn = dataSource.getConnection();
                tl.set(conn);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }
    public static void closeAll(Connection connection, Statement statement , ResultSet rs){
        try {
            if(rs!=null)
                rs.close();
            if(statement!=null)
                statement.close();
            if(connection!=null)
                connection.close();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
   }
    public static void begin(){
        Connection conn = getConnection();
        try {
            conn.setAutoCommit(false);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    public static void commit(){
        Connection conn = getConnection();
        try {
            conn.commit();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            try {
                conn.close();
                tl.remove();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    public static void rollback(){
        Connection conn = getConnection();
        try {
            conn.rollback();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            try {
                conn.close();
                tl.remove();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

12.4 连接池测试

public class TestDruidDataSource {
    public static void main(String[] args) throws SQLException {
//        Connection conn1 = JDBCUtils.getConnection();
//        System.out.println(conn1);
//        Connection conn2 = JDBCUtils.getConnection();
//        System.out.println(conn2);
        for (int i = 0; i < 51; i++) {
            Connection connection = JDBCUtils.getDataSource().getConnection();
            System.out.println(connection);
            connection.close();//并不是关闭连接,而是归还到连接池中
        }
    }
}

14 DaoUtils工具类

将Dao层中增删改的代码进行封装

13.1 工具类实现

public class DaoUtils {
    //更新操作(增删改) insert into emp values(?,?,?,?,?,?,?,?)
    public static int commonsUpdate(String sql,Object... args) throws SQLException {
        //1、获取数据库连接对象
        Connection conn = JDBCUtils.getConnection();
        PreparedStatement ps = null;
        try {
            //2、获取数据库操作对象
           ps = conn.prepareStatement(sql);
            //3、设置占位符的值
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1,args[i]);
            }
            //4、执行sql语句
            int count = ps.executeUpdate();
            //5、处理结果
            return count;
        } finally {
            //6、关闭资源
            JDBCUtils.closeAll(null,ps,null);
        }
    }
    public static <T> List<T> commonsQuery(String sql, Class c, Object... args) throws Exception {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1、获取数据库连接对象
            Connection conn = JDBCUtils.getConnection();
            //2、获取数据库操作对象
            ps = conn.prepareStatement(sql);
            //3、设置占位符的值
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1,args[i]);
            }
            //4、执行SQL语句
            rs = ps.executeQuery();
            //5、处理结果集
            List<T> list = new ArrayList<>();
            while(rs.next()){
                //通过类对象获取类的属性
                Field[] fields = c.getDeclaredFields();
                T obj = (T) c.newInstance();
                for (int i = 0; i < fields.length; i++) {
                    //暴力反射
                    fields[i].setAccessible(true);
                    fields[i].set(obj,rs.getObject(i+1));
                }
                //将对象装到List集合中
                list.add(obj);
            }
            return list;
        }finally {
            JDBCUtils.closeAll(null,ps,rs);
        }
    }
}

13.2 DaoUtils工具类使用

public class EmpDaoImpl implements EmpDao {
    @Override
    public int insertEmp(Emp emp) throws SQLException {
        String sql = "insert into emp values(?,?,?,?,?,?,?,?)";
        Object[] args = {emp.getEmpno(),emp.getEname(),emp.getJob(),emp.getMgr(),emp.getHireadate(),emp.getSal(),emp.getComm(),emp.getDeptno()};
        return DaoUtils.commonsUpdate(sql,args);
    }

    @Override
    public int updateEmp(Emp emp) throws SQLException {
        String sql = "update emp set ename=?,job=?,mgr=?,hiredate=?,sal=?,comm=?,deptno=? where empno = ?";
        Object[] args = {emp.getEname(),emp.getJob(),emp.getMgr(),emp.getHireadate(),emp.getSal(),emp.getComm(),emp.getDeptno(),emp.getEmpno()};
        return  DaoUtils.commonsUpdate(sql,args);
    }

    @Override
    public int deleteEmp(int empno) throws SQLException {
        String sql = "delete from emp where empno = ?";
        Object[] args = {empno};
        return DaoUtils.commonsUpdate(sql,args);
    }

    @Override
    public List<Emp> selectAll() throws Exception {
        String sql = "select * from emp";
        return DaoUtils.commonsQuery(sql,Emp.class);
    }
}

14 DBUtils工具类

14.1 DBUtils简介

DbUtils是Java编程中数据库操作实用小工具,小巧、简单、实用

  • 对于数据表的查询操作,可以把结果转换为List、Array、Set等集合。便于操作。
  • 对于数据表的DML操作,也变得很简单(只需要写SQL语句)。

14.2 DbUtils核心API

ResultSetHandler接口:转换类型接口

  • BeanHandler类:实现类,把一条记录转换成对象
  • BeanListHandler类:实现类,把多条记录转换成List集合。
  • ScalarHandler类:实现类,适合获取一行一列的数据。
  • MapHandler类: 实现类,把一条记录转换成Map集合
  • MapListHandler类:实现类,把多条记录转换成List集合。
  • QueryRunner:执行sql语句的类
  • 增、删、改:update();
  • 查询:query();

14.3 DbUtils的使用步骤

导入jar包

14.4 DBUtils使用

使用DBUtils实现增删改查

public class EmpDaoImpl implements EmpDao {
    @Override
    public int insertEmp(Emp emp) throws SQLException {
        //1、创建QueryRunner对象
        //如果是更新(增删改)操作,那么就用无参的构造
        QueryRunner qr = new QueryRunner();
        //2、通过QueryRunner对象调用update
        String sql = "insert into emp values(?,?,?,?,?,?,?,?)";
        Object[] args = {emp.getEmpno(),emp.getEname1(),emp.getJob(),emp.getMgr(),emp.getHireadate(),emp.getSal(),emp.getComm(),emp.getDeptno()};
        return qr.update(JDBCUtils.getConnection(),sql,args);
    }

    @Override
    public int updateEmp(Emp emp) throws SQLException {
        //1、创建QueryRunner对象
        //如果是更新(增删改)操作,那么就用无参的构造
        QueryRunner qr = new QueryRunner();
        //2、通过QueryRunner对象调用update
        String sql = "update emp set ename=?,job=?,mgr=?,hiredate=?,sal=?,comm=?,deptno=? where empno = ?";
        Object[] args = {emp.getEname1(),emp.getJob(),emp.getMgr(),emp.getHireadate(),emp.getSal(),emp.getComm(),emp.getDeptno(),emp.getEmpno()};
        return qr.update(JDBCUtils.getConnection(),sql,args);
    }

    @Override
    public int deleteEmp(int empno) throws SQLException {
        //1、创建QueryRunner对象
        //如果是更新(增删改)操作,那么就用无参的构造
        QueryRunner qr = new QueryRunner();
        //2、通过QueryRunner对象调用update
        String sql = "delete from emp where empno = ?";
        Object[] args = {empno};
        return qr.update(JDBCUtils.getConnection(),sql,args);
    }
    @Override
    public List<Emp> selectAll() throws Exception {
        //1、创建QueryRunner对象
        //如果是查询操作,那么就用有参的构造,传递连接池对象(使用完成之后QueryRunner会自动关闭(回收))
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        //2、通过QueryRunner对象调用query
        String sql = "select empno,ename ename1,job,mgr,hiredate hireadate,sal,comm,deptno from emp";
        //如果是集合就创建BeanListHandler对象,如果是实体类就创建BeanHandler对象
        List<Emp> empList = qr.query(sql, new BeanListHandler<Emp>(Emp.class));
        return empList;
    }
    @Override
    public Emp selectOne(int empno) throws SQLException {
        //1、创建QueryRunner对象
        //如果是查询操作,那么就用有参的构造,传递连接池对象(使用完成之后QueryRunner会自动关闭(回收))
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        //2、通过QueryRunner对象调用query
        String sql = "select * from emp where empno = ?";
        Object[] args = {empno};
        Emp emp = qr.query(sql, new BeanHandler<Emp>(Emp.class),args);
        return emp;
    }

    @Override
    public long count() throws SQLException {
        //1、创建QueryRunner对象
        //如果是查询操作,那么就用有参的构造,传递连接池对象(使用完成之后QueryRunner会自动关闭(回收))
        QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
        String sql = "select count(*) from emp";
        Long count = qr.query(sql, new ScalarHandler<Long>());
        return count;
    }
}

14.5 字段与属性名不一致

如果数据库的字段名与实体类中的属性名不一致,则无法完成映射,值会显示null

2种解决:

  • 在查询语句中取别名

后期自定义映射

@Override
public List<Emp> selectAll() throws Exception {
    //1、创建QueryRunner对象
    //如果是查询操作,那么就用有参的构造,传递连接池对象(使用完成之后QueryRunner会自动关闭(回收))
    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
    //2、通过QueryRunner对象调用query
    //通过别名进行数据映射
  String sql = "select empno,ename ename1,job,mgr,hiredate hireadate,sal,comm,deptno from emp";
    //如果是集合就创建BeanListHandler对象,如果是实体类就创建BeanHandler对象
    List<Emp> empList = qr.query(sql, new BeanListHandler<Emp>(Emp.class));
    return empList;
}
public class Emp {
    private Integer empno;
    private String ename1; //这个与数据库字段不一致
    private String job;
    private Integer mgr;
    private Date hireadate; //这个与数据库字段不一致
    private Double sal;
    private Double comm;
    private Integer deptno;
  //省略set、get、构造方法
}

15 Lombok插件

Lombok简化编写类的构造方法、setget方法以及toString方法

使用步骤

开启IEDA注解可用需要在setting中进行设置还需要在setting for newproject中设置
新版本使用lombok插件需要添加配置需要在setting中进行设置还需要在setting for newproject中设置
-Djps.track.ap.dependencies=false

image.png

导入jar包

image.png

编写实体类

image.png



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
5月前
|
SQL Java 数据库连接
除了JDBC,还有哪些常见的数据库访问技术?
除了JDBC,还有哪些常见的数据库访问技术?
507 2
|
10月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
9月前
|
Java API 微服务
2025 年 Java 从入门到精通学习笔记全新版
《Java学习笔记:从入门到精通(2025更新版)》是一本全面覆盖Java开发核心技能的指南,适合零基础到高级开发者。内容包括Java基础(如开发环境配置、核心语法增强)、面向对象编程(密封类、接口增强)、进阶技术(虚拟线程、结构化并发、向量API)、实用类库与框架(HTTP客户端、Spring Boot)、微服务与云原生(容器化、Kubernetes)、响应式编程(Reactor、WebFlux)、函数式编程(Stream API)、测试技术(JUnit 5、Mockito)、数据持久化(JPA、R2DBC)以及实战项目(Todo应用)。
492 5
|
12月前
|
存储 Java
# 【Java全栈学习笔记-U1-day02】变量+数据类型+运算符
本篇笔记主要围绕Java全栈学习的第二天内容展开,涵盖了变量、数据类型、运算符以及Scanner类的应用。首先介绍了变量的概念与命名规范,以及如何定义和使用变量;接着详细讲解了Java中的基本数据类型,包括整型、浮点型、字符型、布尔型等,并通过实例演示了数据类型的运用。随后,深入探讨了各类运算符(赋值、算术、关系、逻辑)及其优先级,帮助理解表达式的构成。最后,介绍了如何利用Scanner类实现用户输入功能,并通过多个综合示例(如计算圆面积、购物打折、变量交换及银行利息计算)巩固所学知识。完成相关作业将进一步加深对这些基础概念的理解与实践能力。
234 13
|
6月前
|
SQL Java 关系型数据库
Java连接MySQL数据库环境设置指南
请注意,在实际部署时应该避免将敏感信息(如用户名和密码)硬编码在源码文件里面;应该使用配置文件或者环境变量等更为安全可靠地方式管理这些信息。此外,在处理大量数据时考虑使用PreparedStatement而不是Statement可以提高性能并防止SQL注入攻击;同时也要注意正确处理异常情况,并且确保所有打开过得资源都被正确关闭释放掉以防止内存泄漏等问题发生。
306 13
|
6月前
|
小程序 Java 知识图谱
Java 学习笔记 —— BMI & BMR 计算器
这是一个使用 Java 编写的 BMI 与 BMR 计算器小程序,可输入年龄、性别、身高和体重,计算身体质量指数(BMI)和基础代谢率(BMR),并输出健康评估结果。通过该项目,掌握了 Java 的输入处理、数据验证、条件判断、数学运算及格式化输出等基础知识,是 Java 初学者的理想练习项目。
|
6月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
8月前
|
人工智能 Java 关系型数据库
Java的时间处理与Mysql的时间查询
本文总结了Java中时间与日历的常用操作,包括时间的转换、格式化、日期加减及比较,并介绍了MySQL中按天、周、月、季度和年进行时间范围查询的方法,适用于日常开发中的时间处理需求。
161 0
|
存储 消息中间件 缓存
面试疑难点解析——Java数据库开发(一)
阿里云再offer 5000人,数据库人才求贤若渴!7月9日 19:00,阿里云数据库事业部的两位技术大咖在线直招10多个岗位,想要进入阿里云吗?快来投递简历吧:https://developer.aliyun.com/special/offerday01
面试疑难点解析——Java数据库开发(一)
|
NoSQL Java 关系型数据库
面试疑难点解析——Java数据库开发(七)
本文介绍事务处理的四个特性:ACID,以及开发中可能见到的事务处理模式。

推荐镜像

更多