Java 基础 —— JDBC

Java JDBC的简单使用

一.思路
Ⅰ.单体上看:
① 导入相关 jar 包
② 加载 数据库驱动
③ 获取数据库连接
④ 执行数据库相关操作
⑤ 关闭数据库连接
Ⅱ.从整体上看
① Service 层获取数据库连接,负责整体的逻辑处理
② Dao 层负责将数据库数据处理、封装或转换成Service 层需要的数据
③ Util 层,提供数据库连接、查询、关闭等操作
个人观点:在不考虑使用数据库连接池的情况下,我是这么想的。具体想法如下:
1.我为什么要在 Service层上获取数据库连接?
我的想法是,并非每个人的业务都只需要对数据库执行一次操作,可能要执行2次操作,这谁说的准呢?看功能需求,自己来,我觉得这样会好一点;再说,并非每个人都有能力写出一个复杂的 sql 语句,不行的时候拆成几条 sql 执行,再根据数据结果执行逻辑操作
2.Dao负责将数据库执行的结果封装返回,毕竟咱现在是面向对象,不能向学C的时候那么干了
3.不足?
每一个 Service 逻辑操作都要获取和关闭连接,要知道数据库连接是一个比较耗时的操作,这也没办法,没用连接池

二.代码
上面那么多废话,下面直接看看代码吧,不足的地方忘大家指正…

Util层

public class DBUtile {
    private static  String MYSQL_URL = "jdbc:mysql://localhost:3306/mytest";
    private static String DRIVER = "com.mysql.jdbc.Driver";
    private static String MYSQL_ROOT = "root";
    private static String MYSQL_PASSWORD = "123456";
    private static Connection connection;

    public static Connection getConnection(){
        try {      
            Class.forName(DRIVER);      //加载数据库驱动
            connection = DriverManager.getConnection(MYSQL_URL,MYSQL_ROOT,MYSQL_PASSWORD); 		//获取连接对象
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  connection;
    }

    public static  boolean closeConnection(){
        try {
            if(connection!=null){
                connection.close();
                connection = null;
            }
            return true;
        }catch (Exception e){
            System.out.println("无法关闭 数据库连接,位置,util包下的DBUtil类");
            return  false;
        }
    }

    private PreparedStatement setParam( PreparedStatement p ,Object ... param){
        try {
            for(int i = 0; i < param.length;i++) {  //从下标1开始
                String typeName = param[i].getClass().getName();
                if ("java.lang.Integer".equals(typeName)) {
                    p.setInt(i + 1, (Integer) param[i]);
                } else if ("java.lang.Long".equals(typeName)) {
                    p.setLong(i + 1, (Long) param[i]);
                } else if ("java.lang.String".equals(typeName)) {
                    p.setString(i + 1, (String) param[i]);
                } else if ("java.lang.Float".equals(typeName)) {
                    p.setFloat(i + 1, (Float) param[i]);
                } else if ("java.lang.Double".equals(typeName)) {
                    p.setDouble(i + 1, (Double) param[i]);
                } else if ("java.lang.Byte".equals(typeName)) {
                    p.setByte(i + 1, (Byte) param[i]);
                } else if ("java.lang.Short".equals(typeName)) {
                    p.setShort(i + 1, (Short) param[i]);
                } else {
                    throw new Exception("传入数据库的是:非基本类型");
                }
            }
        }catch (Exception e){
            System.out.println("请仔细检查sql语句,参数的类型和位置");
        }
        return p;
    }

    /**
     * 查询 ,返回结果集,这里并没有关闭数据库连接,请自己关闭
     */
    public ResultSet executeQuery(String sql,Connection con,Object ... param){
        System.out.println("executeQuery....");
        ResultSet rs = null;
        Connection conn = con;
        try {
            PreparedStatement p = conn.prepareStatement(sql);
            if(param.length > 0){       //param数组有值 即代表着 有传入参数,并且sql语句中含有占位符
                p = setParam(p,param);
            }
            rs = p.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
        return  rs;
    }

    /**
     * 修改
     */
    public int executeUpdate(String sql,Connection con,Object ... param){
        System.out.println("executeUpdate....");
        int rs = 0;
        Connection conn = con;
        try {
            PreparedStatement p = conn.prepareStatement(sql);
            if(param.length > 0){
                p = setParam(p,param);
            }
            rs = p.executeUpdate();
        }catch (Exception e){
            System.out.println("DBUtile executeUpdate 异常。。。");
            e.printStackTrace();
        }
        return rs;
    }

    /**
     * 删除
     */
    public int executeDelete(String sql,Connection con,Object ... param){
        System.out.println("executeUpdate....");
        int rs = 0;
        Connection conn = con;
        try {
            PreparedStatement p = conn.prepareStatement(sql);
            if(param.length > 0) {
                p = setParam(p, param);
            }
        }catch (Exception e){
            System.out.println("DBUtile executeUpdate 异常。。。");
            e.printStackTrace();
        }
        return rs;
    }
}

Dao层

public class OperationDao {

    public OperationDao() {

    }

    /**
     * 获取 DBUtile类从数据库的查询结果,封装成自己/业务 需要的结果并返回
     * @param sql  sql语句
     * @param con   service层连接对象
     * @param param  参数数组
     * @return      自己数据库查询后想要的对象或数据,此处是boolean
     */
    public boolean QueryCarName(String sql, Connection con,Object ... param) {
        Connection conn = null;		//这个param要注意一下
        try {
            conn = con;
            DBUtile utile = new DBUtile();
            ResultSet rs = utile.executeQuery(sql,conn);
            while (rs.next()){
                String licensePlate = rs.getString("licensePlate");
                int id = rs.getInt("id");
                String brand = rs.getString("brand");
                System.out.println("----------------------->"+licensePlate+",id :"+idd+",brand:"+brand);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    } 
}

Service层

public class CarOperationService {

    @Inject   //和 @Autowired 一样,都是注入一个对象,你也可以通过new的方式,创建一个 Dao对象
    private CarOperationDao carOperationDao;

    public CarOperationService(){

    }
    public boolean modifyCamereName(int id, String oldName, String newName){
        System.out.println("MonitorService do modifyCamereName...");
        String  sql = "update car set DriverName = ?,DriverAge = ? where id = ?";
        try{
            Connection conn = DBUtile.getConnection();  //获取连接
            carOperationDao.updateCarName(sql,conn,"张三",22,1);
        }finally {
            DBUtile.closeConnection();
        }
        return false;
    }


}

三.注意事项
1.在代码中的有这么一行代码(这个在 Dao 层 和 Util层):

 public int executeUpdate(String sql,Connection con,Object ... param){

这里的重点是: Object … param,对,就是这个玩意;
先来看一张图片吧!
在这里插入图片描述
你会在 Util 层看到这么一句:

if(param.length > 0){
                p = setParam(p,param);
            }

没错,param 就是一个数组,不过它的长度是取决于传过来的参数,当然你也可以不传,这里的效果就和图片的效果是一样的,它的本质就是一个 Object的数组;

再看之前的代码吧,比如:你要调用方法:

 public ResultSet executeQuery(String sql,Connection con,Object ... param)

你的调用可以是:

	对象.executeQuery(sql,con,id,name);	//这里的 id,name,会被存放在 param 的数组里,当然这里你还可以传更多的参数
	对象.executeQuery(sql,con);	//也可以是这样,没有其它参数,这里也不会报错

2.我犯过的坑,对没错,我就在 Object … param 摔了跟头,当时我要根据条件更新数据库的一条数据,然后 sql语句里面有 ?号占位符,预编译后,我没有传对应的参数过去,但是调用根本是不会报错的,所以,使用 Object … param这个的时候一定要注意,有没有参数要传,参数位置是否与sql语句中的对应

3.我的发现

//  Worker method called by the public getConnection() methods.
private static Connection getConnection(
        String url, java.util.Properties info, Class<?> caller) throws SQLException {
        /*
         * When callerCl is null, we should check the application's
         * (which is invoking this class indirectly)
         * classloader, so that the JDBC driver class outside rt.jar
         * can be loaded from here.
         */
        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
        synchronized(DriverManager.class) {
            // synchronize loading of the correct classloader.
            if (callerCL == null) {
                callerCL = Thread.currentThread().getContextClassLoader();
            }
        }

当时匆匆一瞥,看到了这个玩意,小本本记下来

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值