使用的是mysql数据库,myeclipse环境。
使用java连接数据库一般分为以下几步:
1.在依赖库中添加mysql connect的jar包。
2.加载mysql数据库驱动。一般使用Class.forName(DRIVER)来加载。DRIVER是驱动名,mysql的是“com.mysql.jdbc.Driver”,加载一次即可,不需要重复加载。
3.加载后是连接数据库,每次使用数据库都需要连接。因为一般情况是每次使用完数据库后这个连接就会关闭,减少资源的占用。
数据库连接使用的函数是DriverManager中的static函数 static Connection getConnection(String url, String user, String password)。url是数据库的地址,本机的mysql一般是"jdbc:mysql://localhost:3306/数据库名"。在url中还可以设置字符的编码,加上参数useUnicode=true&characterEncoding=utf8,
如url="jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf8"。
4. 获取数据库的连接后就可以使用数据库了,使用Connection对象的PrepareStatment prepareStatment(String sql)函数来准备数据库语句,把sql语句变为prepareStatment对象。
5.有了preparestatment对象后就可以执行了,执行数据库的语句有boolean execute(),int executeUpdate(), ResultSet executeQuery().
execute()可以执行任何种类的 SQL 语句。
executeUpdate()执行的是数据操作语言(DML)如insert,delete,update,或者是无返回内容的数据定义语言(DDL)语句,如drop,create等。
executeQuery()执行的是数据库查询,查询结果放在ResultSet对象中。
6.使用完后关闭数据资源,包括数据库的连接,Preparestatment对象。使用executeQuery查询语句时不能立即关闭,需要使用完ResultSet中的结果后才能关闭,因为关闭数据库连接后ResultSet结果不能再使用。
class dbHelper{
private static dbHelper dbhelper;
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/dbtest";
private static final String USENAME = "root";
private static final String PASSWD = "passwd";
private PreparedStatement stmt = null;
private Connection con = null;
private ResultSet reset = null;
private dbHelper(){
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static dbHelper getDBHelper(){
if(dbhelper == null){
dbhelper = new dbHelper();
}
return dbhelper;
}
public Connection getConnection(){
con = null;
try {
con = DriverManager.getConnection(URL, USENAME, PASSWD);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}
//execute可以执行任何的sql语句 包括表的创建 删除,添加主键等。表的增删改查
public void execute(String sqlString){
con= getConnection();
try {
stmt = con.prepareStatement(sqlString);
stmt.execute();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
closeAll();
}
}
//executeUpdate执行sql的数据操作语言,基本的三种就是表的增删改
public int executeUpdate(String sqlString) {
con = getConnection();
int affectLine = 0;
try {
stmt = con.prepareStatement(sqlString);
affectLine = stmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return affectLine;
}
//加参数的update
public int executeUpdate(String sql,Object[] args) {
int affectLine = 0;
con = getConnection();
try {
stmt = con.prepareStatement(sql);
//这是给sql占位符?赋值。从语句的左向右。编号1开始。
if(args != null){
for(int i = 0;i<args.length;i++){
stmt.setObject(i+1, args[i]);
}
}
affectLine = stmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return affectLine;
}
//executeQuery执行SQl的查询 结果保存在resultSet中
//在这里不能关闭数据库连接,不能关闭ResultSet,否则外界不能访问。
//如果想关闭数据库资源,需要把结果写到java的collection中,如list,map等。
public ResultSet executeQuery(String sqlString){
con = getConnection();
try {
stmt = con.prepareStatement(sqlString);
reset = stmt.executeQuery();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return reset;
}
private void closeAll(){
if(con != null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(reset != null){
try {
reset.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class dbTest {
/**
* @param args
*/
public static void main(String[] args) {
TODO Auto-generated method stub
//创建一个新表是stuInfo。有name和age两个属性
String str1 = "create table stuInfo(name varchar(10),age int)" ;
dbHelper.getDBHelper().execute(str1);
//插入一条数据
String str2 = "insert into stuInfo(name,age) values('eeee',21) ";
dbHelper.getDBHelper().execute(str3);
//查找一个数据
String str3 = "select * from stuInfo where name='eeee'";
dbHelper.getDBHelper().executeQuery(str3)
// 使用带参数的函数删除数据。带参数使用的批量处理中会占据优势。
Object[] params = new Object[]{"eeee",21};
String str4 = "delete from stuInfo where name = ? and age = ?";
dbHelper.getDBHelper().executeUpdate(str4, params);
}
附1:PrepareStatment和Statment区别
使用方法
PreparedStatment pStat = con.prepareStatment(sql);
pStat.execute()
------------------------------------
Statament stat = con.createStatment();
stat.execute(sql)
Preparedstatment会预先编译sql语句。一般推荐使用preparestatment,在一条同类语句执行多次具有高效率
Preparestatment代码的可读性高和对参数支持
String sql = "delete from stuInfo where name = ? and age = ?";
Preparedstatment pStat = con.prepareStatment(sql);
pStat.setSting(1,strVar);
pStat.setInt(2,intVar);
pStat.executeUpdate();
安全性
Preparestatment支持参数,不知道参数的类型和个数,不能进行sql注入攻击
附2 : batch和批处理
Connection con = dbHelper.getDBHelper().getConnection();
String str1 = "insert into stuScore(id,score) values(?,?)";
int[] id = new int[]{1,2,3,4,5,6,7,8,9,10};
int[] score = new int[]{33,56,78,95,56,90,87,91,45,86};
//preparestatement 会提交sql语句到数据库进行预处理。可以使用占位符 ?,在使用的过程中动态更新值,实现批处理。
//statement不支持占位符? 每次数据库都需要重新编译sql语句。
try {
PreparedStatement pStmt = con.prepareStatement(str1);
for(int i = 0;i<id.length;i++){
pStmt.setInt(1, id[i]);
pStmt.setInt(2, score[i]);
pStmt.executeUpdate();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//使用batch 减少了与数据的连接通信次数。创建preparedstatement一次,执行executebatch一次,共2次。
//上面代码每一条语句都执行update时都需要和数据库通信,共有11次。
//把需要执行的语句放在batch中,当执行语句多时,效率明显提升
try {
PreparedStatement pStmt = con.prepareStatement(str1);
for(int i = 0;i<id.length;i++){
pStmt.setInt(1, id[i]);
pStmt.setInt(2, score[i]);
pStmt.addBatch();
}
pStmt.executeBatch();
pStmt.clearBatch();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}