今天突然想多说两句,刚刚在知乎看到一个人说,在当今世界,没有技术型驱动的公司,全都是业务型。即便是表面上看似技术型公司,其本质还是为了服务业务。这段话推翻了我以前关于编程的所有看法,觉得颇有道理。下面也来说说web应用的本质。
1.什么是web应用?就是用户通过浏览器,访问服务器,进行一系列操作,保存数据,修改数据的应用。其核心,就是对数据的操作。不管什么框架、什么UI,其目的还是对数据进行操作。所以,对于数据库的操作,是web应用的重中之重。而jdbc又是数据库操作中最为重要的基石。
2.jdbc的基本操作,看如下代码及注释:
首先加载数据库驱动程序,然后用驱动管理器获取数据库连接
private static final String URL="jdbc:mysql://127.0.0.1:3306/xiao"; private static final String NAME="root"; private static final String PASSWORD="13720994358lhp"; static Connection connection=null; static { try { //1.加载数据库驱动程序 Class.forName("com.mysql.jdbc.Driver"); //2.获取数据库连接 connection = DriverManager.getConnection(URL, NAME, PASSWORD); }catch (ClassNotFoundException e){ System.err.println("未找到数据库加载程序"); }catch (SQLException e){ System.err.println("数据库错误" +e); } }
然后用获取到的连接connection获取一个数据库操作对象,该对象可以执行sql
Statement statement=connection.createStatement();
statement.execute("sql语句");
还有另一种执行sql的对象,叫做预处理。什么意思呢?就是先把sql的模板放进去,然后执行的时候再把具体的参数一一带入,这样做可以减少连接数据库的次数。代码如下:
PreparedStatement preparedStatement=connection.prepareStatement(sql); preparedStatement.setString(1,goddess.getUserName()); preparedStatement.setInt(2,goddess.getSex()); preparedStatement.setInt(3,goddess.getAge()); preparedStatement.setDate(4,new Date(goddess.getBirthday().getTime())); preparedStatement.setString(5,goddess.getEmail()); preparedStatement.setString(6,goddess.getMobile()); preparedStatement.setString(7,goddess.getCreateUser()); preparedStatement.setString(8,goddess.getUpdateUser()); preparedStatement.setInt(9,goddess.getIsdel());
增删改查基本上操作都一样,区别在于,增加删除修改,最后statement调用执行sql的方法有所不同查询是preparedStatement.executeQuery(),修改是preparedStatement.executeUpdate()等等
3.jdbc调用无参存储过程。存储过程怎么写在此不做说明,只说java代码如何调用存储过程。
//1.获得连接 Connection connection= DBUtil.getConnection(); //2.要获得执行存储过程的对象 CallableStatement callableStatement=connection.prepareCall("call sp_select_nofilter()"); //3.执行存储过程 callableStatement.execute(); //4.获得结果集对象 ResultSet rs=callableStatement.getResultSet();
4.JDBC调用带入参的存储过程,相比于不带参数就多了一点变化:先用?代替sql中的参数,再在后面设置参数的具体值。
Connection connection=DBUtil.getConnection(); CallableStatement callableStatement=connection.prepareCall("call sp_filter(?)"); callableStatement.setString("1",""); callableStatement.execute(); ResultSet resultSet=callableStatement.getResultSet();
5.JDBC调用带有出参的存储过程,相比于带有入参的又多了一点变化,请看代码:
Connection connection=DBUtil.getConnection(); CallableStatement callableStatement=connection.prepareCall("call sp_select_count(?)"); //与入参存储过程不同的是,出参不能提前设置,而需要注册,第一个参数是索引,第二个参数是数据库字段类型 callableStatement.registerOutParameter(1, Types.INTEGER); callableStatement.execute(); int count=callableStatement.getInt("1"); return count;
6.JDBC的事务操作。具体什么是事务操作,在这里不做详细说明,网上百度一大把,很详细。简而言之就是一句话,要一次完成一系列对数据库的操作,如果中间某个环节出现问题,则需要将所有操作回退。举个最简单的例子:银行转账,先在A的账户扣一百块,再给B的账户加一百块,这样完成了从A到B的转账,假如在A已经扣钱而B没有加钱的情况下,程序突然出错了,那怎么办?A的钱已经扣了,而B的钱还没加,钱去哪了??这就是事务操作的重要性。请看代码:
public static business(){ Connection connection=DBUtil.getConnection(); //本来数据库默认自动提交数据,现在关掉 connection.setAutoCommit(false); try{ //进行数据库操作之后,手动提交数据,在提交完成后才生效 connection.commit(); }catch (Exception e){ //当陈程序发生异常,首先要把所有对数据库的操作回退 connection.rollback(); } }
7.数据库连接池。上文讲到,当程序需要对数据库进行操作的时候,第一步请求连接数据库,第二步进行数据库操作,第三步关闭数据库连接。加入一个项目很大,每一次请求都会走这三步,将非常消耗资源。不如创造一个池子,专门管理一些常态连接,当需要的时候从池子里拿,不需要的时候再放回去。这样可以节约资源。比较常用的有dbcp连接池和c3p0连接池,使用方法如下:
##首先设置配置文件,将连接数据库需要的相关参数放进来统一管理 c3p0.driverClass=com.mysql.jdbc.Driver c3p0.jdbcURL=jdbc\:mysql\://127.0.0.1\:3306/xiao c3p0.user=root c3p0.password=13720994358lhp
上面是一个properties文件,里面有一些连接数据库需要的常量。
然后当程序启动的时候会自动加载这个配置文件,获得数据库连接,代码如下:
private static ComboPooledDataSource dataSource=new ComboPooledDataSource(); public static Connection getConnection()throws SQLException { return dataSource.getConnection(); }