数据库编程
1 数据库编程
PS:如果没有数据库的基础,可以先去学习一下基本的语句操作就可以了。
这就需要将数据库知识和Java结合起来了。数据库是一种规范的数据存储方式,在这里笔者向大家介绍的是基于MySQL数据库的JDBC操作(因为MySQL简便轻巧,不安装和使用非常方便,不像SQL Server那么复杂)。
MySQL说的好听点叫做数据库,说的通俗点就是操作数据的形式和工具。
大家应该知道,对存储设备上的数据进行操作,无非就只有四种:增删改查。数据库编程就是那么简单。
除了介绍基本的JDBC之外,笔者还会在后面扩展一下C3P0连接池。
2 四大步骤
Java中的JDBC编程基本上就分为四个大的步骤:加载驱动、获取连接对象、操作数据库、关闭连接。
加载驱动
加载驱动很简单,如果学过反射那么应该很容易就理解,没有学过也不要紧,因为这是固定的代码。
首先,需要准备的东西有:mysql的驱动jar包、数据库和表必须要建立起来、需要记住安装mysql时指定的用户名和密码。如果是Eclipse开发环境,还需要创建相关目录,然后将jar包复制进去再添加路径。如果是MyEclipse,那么只需要建立一个Web Project项目工程就行。
记住:一定要右键mysql的jar包,选择Build Path。
加载驱动代码:
Class.forName("com.mysql.jdbc.Driver");
获取连接对象
获取连接对象需要指明三个要素:创建的数据库、用户名、密码。
String url = "jdbc:mysql://localhost:3306/mydb";
String username = "root";
String password = "123456";
//获取连接对象
Connection con = DriverManager.getConnection(url, username, password);
操作数据库
操作数据库就是要和数据库进行增删改查操作,具体的语句和数据库中的是一样的,操作数据库对象一般有种:Statement和PrepareStatement。
Statement就是未编译的对象。
PrepareStatement是预编译对象,在编译期间就将sql语句进行编译,防止SQL注入,常使用。
关闭连接
关闭连接只有一个要求,先创建的后关闭。
如果不关闭连接的话,程序会一直占用CPU资源。
3 完整的案例
查询学生表的数据。
public class JDBCTest {
//将三个对像先定义
private Connection con = null;
private Statement stmt = null;
private ResultSet rs = null;
//创建标准的JDBC语句
public void Standard() throws Exception{
try{
//加载驱动类,不同的数据库有不同的写法
Class.forName("com.mysql.jdbc.Driver");
//指定三个参数,笔者自己创建的数据库、用户名和密码
String url = "jdbc:mysql://localhost:3306/mydb";
String username = "root";
String password = "123456";
//获取连接对象
con = DriverManager.getConnection(url, username, password);
//发送数据库语句,sql语句,千万别加分号
String sql = "select * from tb_stu";
//创建数据库操作对象
stmt = con.createStatement();
/**此种方式会出现漏洞,万能密码获取数据库所有密码,解决办法如下:
*1. 使用Statement的一个实现类PrepareStatement:PrepareStatement ps = con.prepareStatement(sql);
*2. 将sql语句的插入内容用占位符?
*3. 为占位符赋值:ps.setString(占位符坐标(从1开始),插入对应字段的内容);
*/
//利用stmt调用executeQuery方法执行Sql语句,并获取数据集ResultSet
rs = stmt.executeQuery(sql);
//设置输出格式
System.out.println("学号\t" + "姓名\t" + "性别\t" + "年龄\t" + "家庭住址\t");
//对结果集进行遍历
while(rs.next()) {
//通过下标获取,下标从1开始
int number = rs.getInt(1);
//通过表中的列名获取
String name = rs.getString("name");
String gender = rs.getString("gender");
int age = rs.getInt("age");
String location = rs.getString("location");
System.out.println(number + "\t" + name + "\t" + gender + "\t" + age + "\t" + location + "\t");
}
} catch(Exception e) {
throw e;
} finally {
if(rs!=null) {
rs.close();
}
if(stmt!=null) {
stmt.close();
}
if(con!=null) {
con.close();
}
}
}
}
扩展
通过上面的语句,我们知道了JDBC的基本过程,但是在实际开发中并不会这样使用,因为这样太费时费力了。费时的主要是在创建连接对象Connection上面,所以说,我们可不可以预先将连接对象创建好,在需要使用的时候就拿来用,不需要的时候就放在一边。
C3P0连接池就是可以解决这样的一个问题,他就是预先将一批连接对象创建好了放在连接池中,用的时候就取出来,不用就放进去。当然,C3P0不仅仅是有这个好处,他还将数据库的配置放到了配置文件中,不需要在Java源代码里写数据库的配置。
配置文件:可以放在源目录下(src目录下)
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<named-config name="c3p0Config">
<property name="user">root</property>
<property name="password">123456</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb</property>
<!--以上的user是数据库的用户,password是数据库的密码,driverClass是mysql的数据库驱动,jdbcUrl是连接数据库的url -->
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 -->
<property name="acquireIncrement">10</property>
<!--初始化时获取十个连接,取值应在minPoolSize与maxPoolSize之间 -->
<property name="initialPoolSize">10</property>
<!--连接池中保留的最小连接数 -->
<property name="minPoolSize">10</property>
<!--连接池中保留的最大连接数 -->
<property name="maxPoolSize">50</property>
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池。
所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
<property name="maxStatements">20</property>
<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
读取配置文件并获取连接对象:
package c3p0Pool;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0Util {
private static DataSource dataSource = null;
static{
//dataSource资源只能初始化一次,加载C3P0配置文件,加载数据库相关信息
dataSource= new ComboPooledDataSource("c3p0Config");
}
/**
* 获取连接
*/
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
/**
* 释放连接
*/
public static void releaseConnection(Connection connection){
try {
if(connection != null ) {
//这里是将连接对象重新放回到连接池中,而不是将其关闭
connection.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
基本上就是这些了,至于操作数据库的方式和原始的是一样的,只是连接对象的不同而已。
说明:C3P0连接池的实现和反射、配置文件xml相关,一般推荐使用配置文件创建连接池。