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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 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



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4天前
|
XML Java 数据库连接
性能提升秘籍:如何高效使用Java连接池管理数据库连接
在Java应用中,数据库连接管理至关重要。随着访问量增加,频繁创建和关闭连接会影响性能。为此,Java连接池技术应运而生,如HikariCP。本文通过代码示例介绍如何引入HikariCP依赖、配置连接池参数及使用连接池高效管理数据库连接,提升系统性能。
23 5
|
8天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
22 4
|
6天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
19 1
|
16天前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
30 3
|
15天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
77 1
|
16天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
33 2
|
16天前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
16 1
|
3天前
|
运维 关系型数据库 MySQL
安装MySQL8数据库
本文介绍了MySQL的不同版本及其特点,并详细描述了如何通过Yum源安装MySQL 8.4社区版,包括配置Yum源、安装MySQL、启动服务、设置开机自启动、修改root用户密码以及设置远程登录等步骤。最后还提供了测试连接的方法。适用于初学者和运维人员。
27 0
|
16天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
47 0