JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
准备工作
1.先创建java 项目
2.导入对应数据库的驱动 .jar包
主要步骤有 :
1.加载驱动
Class.forName("com.mysql.jdbc.Driver") ;
2.与数据库建立连接
不同的数据库的连接字段是不同的,url的字段会点差别
String url = "jdbc:mysql://localhost:3306/数据库名" ;
String username = "数据库的名称" ;
String password = "数据库的密码" ;
Connection conn = DriverManager.getConnection(url,username,password) ;
3.创建Statement or PrepareStatement对象
1)执行静态SQL语句,通常通过Statement实例实现。
Statement st= conn.createStatement() ;
2)执行动态SQL语句,通常通过PreparedStatement实例实现。
PreparedStatement ps= conn.prepareStatement(sql) ;
3)执行数据库存储过程,通常通过CallableStatement实例实现。
CallableStatement csmt= conn.prepareCall("{CALL demoSp(? , ?)}") ;
4.执行sql语句
Statement提供了三种方法:
executeQuery(String sql) 用于查询,返回一个ResultSet结果集
executeUpdate(String sql) 用于增删改操作
execute(String sql) 用于执行返回多个结果集、多个更新计数或二者组合的
5.处理结果集
6.关闭jdbc连接,释放资源
增删改查操作的完整实现代码
1.写一个jdbc连接的工具类,提高代码的复用性
** JdbcUtil.java **
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcUtil {
/*
* 连接数据库的方法
* /
public static Connection getConn() {
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
try {
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/user?useUnicode=true&characterEncoding=UTF-8", "root", "123456");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return conn;
}
/**
* 释放资源
*
* @param conn
* @param st
* @param rs
*/
public static void release(Connection conn, Statement st, ResultSet rs) {
closeRs(rs);
closeSt(st);
closeConn(conn);
}
public static void release(Connection conn, Statement st) {
closeSt(st);
closeConn(conn);
}
public static void release(Connection conn, PreparedStatement pt) {
closeSt(pt);
closeConn(conn);
}
/*
* 关闭连接
*/
private static void closeRs(ResultSet rs) {
try {
if (rs != null)
rs.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
rs = null;
}
}
private static void closeSt(Statement st) {
try {
if (st != null)
st.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
st = null;
}
}
private static void closeConn(Connection conn) {
try {
if (conn != null)
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
conn = null;
}
}
}
2.定义一个接口类,把功能和实现分开
UserDao.java
public interface UserDao {
/**
* 查询所有的
*/
public void findAll();
/**
/**
* 添加
* @param Username
* @param password
*/
public void insert(String Username,String password);
/**
* 根据 id 删除
* @param id
*/
public void delete(int id ) ;
/**
* 根据 id 修改 username
* @param id
* @param username
*/
public void update(int id,String username) ;
}
3.功能的实现
UserDaoImpl.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.dao.UserDao;
import com.dao.util.JdbcUtil;
public class UserDaoImpl implements UserDao {
/*
* 查询所有的
*/
@Override
public void findAll() {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtil.getConn();
st = conn.createStatement();
String sql = "select * from t_user";
rs = st.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
System.out.println(id + "--" + username + "--" + password);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.release(conn, st, rs);
}
}
/**
* 添加功能
*/
@Override
public void insert(String Username, String password) {
Connection conn = null ;
PreparedStatement ps =null ;
String sql = "insert into t_user values(null,?,?)" ;
try {
conn = JdbcUtil.getConn() ;
ps = conn.prepareStatement(sql) ;
// 给占位符赋值
ps.setString(1, Username);
ps.setString(2, password);
int result = ps.executeUpdate();
if(result>0) {
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JdbcUtil.release(conn, ps);
}
}
@Override
public void delete(int id) {
Connection conn = null ;
PreparedStatement ps =null ;
String sql = "delete from t_user where id=?" ;
try {
conn = JdbcUtil.getConn() ;
ps = conn.prepareStatement(sql) ;
// 给占位符赋值
ps.setInt(1, id);
int result = ps.executeUpdate();
if(result>0) {
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JdbcUtil.release(conn, ps);
}
}
@Override
public void update(int id, String username) {
Connection conn = null ;
PreparedStatement ps =null ;
String sql = "update t_user set username=? where id=?" ;
try {
conn = JdbcUtil.getConn() ;
ps = conn.prepareStatement(sql) ;
// 给占位符赋值
// 赋值时从sql语句 的左边看起,索引值从 1开始
ps.setString(1, username);
ps.setInt(2, id);
int result = ps.executeUpdate();
if(result>0) {
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JdbcUtil.release(conn, ps);
}
}
}
4.最后就是对操作进行测试了
推荐使用 JUnit单元测试,一个一个的对功能的进行调试,就算有错误也好改
TestUserDaoImpl.java
import org.junit.Test;
import com.dao.UserDao;
import com.dao.impl.UserDaoImpl;
public class TestUserDaoImpl {
@Test
public void testFindAll() {
UserDao dao = new UserDaoImpl() ;
dao.findAll();
}
@Test
public void testlogin() {
UserDao dao = new UserDaoImpl() ;
//注意Statement安全问题
//为什么会登录成功呢,因为Statement sql 语句先是拼接的,在一起执行
//"123456'or'1=1" 因为sql语句有关键字 or 存在,会看为判断关系,只要有一个成立,则成立
// 解决这个问题,可以把Statement 换成PrepareStatement,它在执行sql语句前,是先把sql语句字符先进行拼接,然后在一起执行的
dao.login("张三", "123456"); // 结果为登录成功
//dao.login("张三", "123456'or'1=1"); // 结果一样为登录成功
}
@Test
public void testInsert() {
UserDao dao = new UserDaoImpl() ;
dao.insert("王五", "111111");
}
@Test
public void testDelete() {
UserDao dao = new UserDaoImpl() ;
dao.delete(4);
}
@Test
public void testUpdate() {
UserDao dao = new UserDaoImpl() ;
dao.update(1, "Tom");
}
}