千锋逆战班学习日志


千锋逆战班学习第44天
努力或许没有收获,但不努力一定没收获,加油。
今天我学习了JDBC。
中国加油!!!武汉加油!!!千锋加油!!!我自己加油!!!

连接池

JDBC每次连接数据库,都要获得一个连接对象。每次创建一个连接对象,都是一个较大的资源,如果在连接量较大的场景下,会极大的浪费资源。容易内存溢出。

自定义连接池

Java中提供了一个接口DataSource,通过实现该接口,可以创建连接池

Druid(德鲁伊)

Druid 是目前比较流行高性能的,分布式列存储

  1. 亚秒级查询
  2. 实时数据注入
  3. 可扩展的PB级存储
  4. 多环境部署
  5. 丰富的社区
Druid配置
  • 创建database.properties 配置文件
  • 引入druid-1.1.5.jar
database.properties 文件配置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/userinfo?useUnicode=true&characterEncoding=utf8
username=root
password=123456
#初始化连接
initialSize=10
#最大连接数量
maxActive=30
#最小空闲连接
minIdle=5
#超时等待时间以毫秒为单位
maxWait=5000
连接池工具类
 package com.qf.day44.t2;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.xml.transform.Result;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    public class DBPoolUtils {
        //连接池对象
        private static DruidDataSource ds;
    
        static {
            Properties properties = new Properties();
            InputStream is = DBPoolUtils.class.getResourceAsStream("/database.properties");
            try {
                properties.load(is);
                //使用德鲁伊工厂创建连接池
                ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection() {
            try {
                //在连接池中获得Connection
                return ds.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    statement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
  • 注意:连接池中获得的Connection是DruidPooledConnection实现类,调用的close()方法不是关闭资源,而是将资源放回池中!

Service(Biz/Business)

概念:用户要完成的一个业务功能,是由一个或多个的DAO调用组成。

软件、程序提供的一个功能都叫业务

业务层的实现

    package com.qf.day44.t3;
    
    /**
     * Userinfo的业务逻辑层对象
     */
    public class UserinfoServiceImpl {
    
        /**
         * 用户的注册功能(业务)
         */
        public String register(Userinfo userinfo){//1.接收参数
            UserinfoDaoImpl userinfoDao = new UserinfoDaoImpl();
    
            //2.调用数据访问层对象的查询方法!
            Userinfo check = userinfoDao.select(userinfo.getUser_name());
            if(check!=null){//用户存在!~
                return "用户名已存在!";
            }
            //3.调用数据访问层对象的新增方法
            int result = userinfoDao.insert(userinfo);
            //4.将操作结果返回给调用者
            if(result >0 ){
                return "注册成功!";
            }else{
                return "注册失败!";
            }
        }
        /**
        * 登录功能业务
        */
        public Userinfo login(String user_name,String user_pwd){//收参
            UserinfoDaoImpl userinfoDao = new UserinfoDaoImpl();
            //2.调用数据访问层对象的查询方法
            Userinfo userinfo = userinfoDao.select(user_name);
    
            //3.接收结果,处理结果
            if(userinfo!=null){//用户存在!
                //检验查询到的用户密码和输入的密码是否一致!
                if(userinfo.getUser_pwd().equals(user_pwd)){
                    return userinfo;
                }
            }
            //4.响应给调用者结果
            return null;
        }
    }

复用

  • DAO数据访问操作复用
  • 业务功能的复用 //不同的终端访问

15.4 转账案例

import day44.t4.Utils.DBUtil;
import day44.t4.dao.AccountDaoImpl;
import day44.t4.entity.Account;

import java.sql.Connection;
import java.sql.SQLException;

public class AccountServiceImpl {
    private AccountDaoImpl accountDao = new AccountDaoImpl();
    //转账功能
    public String transfer(String fromNo,String password,String toNo,double money){//收参
        String result = "转账失败";
        //组织业务功能
        Connection connection = null;
        try {
            connection = DBUtil.getConnection();
            connection.setAutoCommit(false);//开启事务
            Account fromAcc = accountDao.select(fromNo);
            if (fromAcc == null) {
                throw new RuntimeException("用户不存在");
            }
            if (!fromAcc.getPassword().equals(password)) {
                throw new RuntimeException("密码不正确");
            }
            if (fromAcc.getBalance() < money) {
                throw new RuntimeException("余额不足");
            }
            Account toAcc = accountDao.select(toNo);
            if(toAcc == null){
                throw new RuntimeException("对方账户不存在");
            }
            fromAcc.setBalance(fromAcc.getBalance() - money);
            accountDao.updata(fromAcc);

            toAcc.setBalance(toAcc.getBalance() + money);
            accountDao.updata(toAcc);
            result = "执行成功";
            connection.commit();
        }catch (Exception e){
            e.printStackTrace();
            try {
                System.out.println("出现异常,回滚");
                connection.rollback();
            }catch (SQLException ex){
                ex.printStackTrace();
            }
        }finally {
            DBUtil.closeAll(connection,null,null);
        }
        return result;
    }
}

解决转账事务问题

1、传递Connection:如果将Service获得的Connection对象,传递给DAO各个方法。可以。//BadSmell 臭味

定义接口是为了更容易更换实现!而将Connection参数定义在接口方法中,就会污染当前接口,而无法复用。JDBC-Connection。MyBatis使用SqlSession

2、单例:当前项目只能有一个客户端连接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值