JAVA Database Connectivity java 数据库连接
SUN公司提供的一种数据库访问规则、规范, 由于数据库种类较多,并且java语言使用比较广泛,sun公司就提供了一种规范,让其 他的数据库提供商去实现底层的访问规则。 我们的java程序只要使用sun公司提供的jdbc驱动即可。
使用JDBC的基本步骤 :
1.注册驱动:
2. 建立连接
3. 创建statement
4. 执行sql ,得到ResultSet
5. 遍历结果集
6. 释放资源
实例:JDBCDemo1
package it.cast.jdbc.demo1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.jdbc.Driver;
/*
jdbc的基本使用方法
*/
public class JdbcDemo1 {
public static void main(String[] args) {
ResultSet rs =null;
Connection conn =null;
Statement st =null;
try {
//1.添加jar文件,注册驱动
DriverManager.registerDriver(new Driver());
//DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
//2. 建立连接 参数一: 协议 + 访问的数据库 , 参数二: 用户名 , 参数三: 密码。
conn = DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "19930903");
//3.创建statement
st = conn.createStatement();
//4.执行sql,得到结果
String sql="select * from student";
rs = st.executeQuery(sql);
//5.遍历结果集
while (rs.next()) {
int sid = rs.getInt("sid");
String name = rs.getString("name");
String age = rs.getString("age");
//打印数据
System.out.println("sid="+sid+"name="+name+"age="+age);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//6.释放资源
try {
if(rs!=null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(st!=null) {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
JDBC 工具类构建
1. 资源释放工作的整合
2. 驱动防二次注册
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Driver 这个类里面有静态代码块,一上来就执行了,所以等同于我们注册了两次驱动。 其实没这个必要的。
//静态代码块 ---> 类加载了,就执行。 java.sql.DriverManager.registerDriver(new Driver());
最后形成以下代码即可。
Class.forName("com.mysql.jdbc.Driver");
3. 使用properties配置文件
1. 在src底下声明一个文件 xxx.properties ,里面的内容吐下:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/student
name=用户名
password=密码
2. 在工具类里面,使用静态代码块,读取属性
实例工程:JDBCDemo2
工具类:JDBCDemo02/src/it/cast/jdbc/util/JDBCUtil.java
package it.cast.jdbc.util;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtil {
static String driverClass=null;
static String url=null;
static String usename=null;
static String password=null;
static {
try {
//1.创建一个属性配置文件对象
Properties properties = new Properties();
//InputStream is=new FileInputStream("jdbc.properties")//配置文件在工程根目录下
//使用类加载器加载src地下的配置文件
InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
properties.load(is);
//读取属性
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
usename = properties.getProperty("usename");
password = properties.getProperty("password");
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* jabc的连接
*/
public static Connection jdbcConn() {
Connection conn=null;
try {
//1.注册驱动,4.0以后可以不用注册
Class.forName("com.mysql.jdbc.Driver");//里面是Driver的全路径
//因为Driver有静态代码块,类加载就执行,相当于注册了两回,没有必要。java.sql.DriverManager.registerDriver(new Driver());
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.建立连接 参数一:协议+访问的数据库,参数二:用户名 ,参数三:密码;
conn = DriverManager.getConnection(url, usename, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/*
* 关闭数据库的方法,释放资源
*/
public static void resease(ResultSet rs,Statement st,Connection conn) {
rsclose(rs);
stclose(st);
connclose(conn);
}
public static void resease(Statement st,Connection conn) {
stclose(st);
connclose(conn);
}
private static void rsclose(ResultSet rs) {
try {
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void stclose(Statement st) {
try {
if(st!=null)
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void connclose(Connection conn) {
try {
if(conn!=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
使用工具类查询:JDBCDemo02/src/it/cast/jdbc/demo/MainTest.java
package it.cast.jdbc.demo;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import it.cast.jdbc.util.JDBCUtil;
public class MainTest {
/*
* JDBC入门
*/
public static void main(String[] args) {
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
conn=JDBCUtil.jdbcConn();
//3.创建statement,跟数据库交互,一定要创建这个对象
st = conn.createStatement();
//4.执行查询,得到结果集
String sql="select * from product";
rs = st.executeQuery(sql);
//5.遍历查询到每一条记录
while (rs.next()) {
int pid=rs.getInt("pid");
String pname=rs.getString("pname");
double price=rs.getDouble("price");
int cno=rs.getInt("cno");
System.out.println(pid+":"+pname+":"+price+":"+cno);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(rs,st,conn);
}
}
}
使用单元测试,测试代码
1. 定义一个类, TestXXX , 里面定义方法 testXXX.
2. 添加junit的支持。
在项目工程右击,选择Build Path-> addlibraries ->junit4->junite4
3. 在测试的方法上面加上注解 , 其实就是一个标记。@Test(每个测试的方法都要加)
@Test
public void testQuery() {
...
}
4. 光标选中方法名字,然后右键执行单元测试。 或者是打开outline视图, 然后选择方法右键执行。
实例:JDBC的CRUD操作
工程:JDBC_CRUD
JDBC_CRUD/src/it/cast/jdbc/crud/TestDemo.java
package it.cast.jdbc.crud;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import org.junit.Test;
import it.cast.jdbc.util.JDBCUtil;
/**
* 使用jUnite进行单元测试步骤
* 1.新建一个类,把测试代码放进去
* 2.在项目工程右击,选择Build Path-> addlibraries ->junit4->junite4
* 3.在测试的方法上加注解,其实就是一个标记。@Test(每个测试的方法都要加)
* 4.光标放在方法上,直接执行。
* Ctrl+T:显示类的情况
* */
public class TestDemo {
//查询
@Test
public void testQuery() {
Connection conn=null;
Statement st=null;
ResultSet rs=null;
try {
//1.连接数据库
conn=JDBCUtil.jdbcConn();
//2.创建statement,
st=conn.createStatement();
//3.执行查询
String sql="select * from product";
rs=st.executeQuery(sql);
//遍历结果,打印出来
while(rs.next()) {
int pid=rs.getInt("pid");
String pname=rs.getString("pname");
double price=rs.getDouble("price");
int cno=rs.getInt("cno");
System.out.println(pid+":"+pname+":"+price+":"+cno);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(rs, st, conn);
}
}
//插入
@Test
public void testInsert() {
Connection conn=null;
Statement st=null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.创建statement,
st = conn.createStatement();
//3.插入数据
String sql = "insert into product values(null,'贝因美',66,5)";
int resault = st.executeUpdate(sql);
if (resault > 0) {
System.out.println("插入成功");
} else {
System.out.println("插入失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(st,conn);
}
}
//删除
@Test
public void testDelete() {
Connection conn=null;
Statement st=null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.创建statement,
st = conn.createStatement();
//3.删除数据
String sql = "delete from product where pid=11";
int resault = st.executeUpdate(sql);
if (resault > 0) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(st,conn);
}
}
//更改
@Test
public void testUpdate() {
Connection conn=null;
Statement st=null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.创建statement,
st = conn.createStatement();
//3.更改数据
String sql = "update product set price=20 where pid=10";
int resault = st.executeUpdate(sql);
if (resault > 0) {
System.out.println("更改成功");
} else {
System.out.println("更改失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(st,conn);
}
}
}
Dao模式
Data Access Object 数据访问对象
1. 新建一个dao的接口, 里面声明数据库访问规则
2. 新建一个dao的实现类,具体实现早前定义的规则
3. 直接使用实现
实例工程:JDBC_Dao
>dao接口:JDBC_Dao/src/it/cast/jdbc/dao/UserDao.java
package it.cast.jdbc.dao;
public interface UserDao {
/*DAO模式:Data Access Object数据访问对象
1.新建一个dao的接口,里面声明数据库的访问规则
2.新建一个dao的实现类,具体实现早先定义的规则
3.直接使用实现*/
//更新数据,根据id更新数据
void update(int id,String username);
//删除数据
void delete(int id);
//插入数据的方法
void insert(String username,String password);
//查询的方法
void findAll();
//登录方法
void login(String username,String password);
}
实现接口的类:JDBC_Dao/src/it/cast/jdbc/dao/impl/UserDaoImpl.java
package it.cast.jdbc.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.swing.text.Utilities;
import org.junit.Test;
import it.cast.jdbc.dao.UserDao;
import it.cast.jdbc.util.JDBCUtil;
public class UserDaoImpl implements UserDao {
public void findAll() {
Connection conn=null;
Statement st =null;
ResultSet rs =null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.创建ststement对象
st = conn.createStatement();
//3.执行查询
String sql = "select * from user_p";
rs = st.executeQuery(sql);
while (rs.next()) {
int uid=rs.getInt("uid");
String username=rs.getString("username");
int password=rs.getInt("password");
System.out.println(uid+":"+username+":"+password);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(rs, st, conn);
}
}
//登录密码校验
/*
public void login(String username, String password) {
Connection conn=null;
Statement st =null;
ResultSet rs =null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.创建ststement对象
st = conn.createStatement();
//3.执行查询
String sql = "select * from user_p where username='"+username+"' and password='"+password+"'";
rs = st.executeQuery(sql);
if (rs.next()) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(rs, st, conn);
}
}
*/
public void login(String username, String password) {
Connection conn=null;
Statement st =null;
ResultSet rs =null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.sql查询语句
String sql = "select * from user_p where username=? and password=?";
//3.预先对sql语句执行语法的校验,?对应的内容,后面不管传递什么进来,都把他看成字符串。or,select
PreparedStatement ps = conn.prepareStatement(sql);
//?对应的索引从1开始
ps.setString(1, username);
ps.setString(2, password);
rs=ps.executeQuery();
if (rs.next()) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(rs, st, conn);
}
}
//插入数据的方法
public void insert(String username, String password) {
Connection conn = null;
PreparedStatement ps =null;
try {
conn = JDBCUtil.jdbcConn();
String sql = "insert into user_p values(null,?,?)";
ps = conn.prepareStatement(sql);
//给占位符赋值,从左到右数过来,从1开始
ps.setString(1, username);
ps.setString(2, password);
int rs = ps.executeUpdate();
if (rs > 0) {
System.out.println("插入数据成功");
} else {
System.out.println("插入数据失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(ps, conn);
}
}
//删除数据失败
public void delete(int id) {
Connection conn = null;
PreparedStatement ps =null;
try {
conn = JDBCUtil.jdbcConn();
String sql = "delete from user_p where uid=?";
ps = conn.prepareStatement(sql);
//给占位符赋值,从左到右数过来,从1开始
ps.setInt(1, id);
int rs = ps.executeUpdate();
if (rs > 0) {
System.out.println("删除数据成功");
} else {
System.out.println("删除数据失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(ps, conn);
}
}
// 更新数据
public void update(int id, String username) {
Connection conn = null;
PreparedStatement ps =null;
try {
conn = JDBCUtil.jdbcConn();
String sql = "update user_p set username=? where uid=?";
ps = conn.prepareStatement(sql);
//给占位符赋值,从左到右数过来,从1开始
ps.setString(1, username);
ps.setInt(2, id);
int rs = ps.executeUpdate();
if (rs > 0) {
System.out.println("更新数据成功");
} else {
System.out.println("更新数据失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(ps, conn);
}
}
}
测试类:JDBC_Dao/src/it/cast/jdbc/test/TestUserDaoImpl.java
package it.cast.jdbc.test;
import org.junit.Test;
import it.cast.jdbc.dao.UserDao;
import it.cast.jdbc.dao.impl.UserDaoImpl;
public class TestUserDaoImpl {
@Test
public void testUpdate() {
UserDaoImpl dao = new UserDaoImpl();
dao.update(1, "王五");
}
@Test
public void testDelett() {
UserDaoImpl dao = new UserDaoImpl();
dao.delete(3);;
}
@Test
public void testInsert() {
UserDaoImpl dao = new UserDaoImpl();
dao.insert("王五","1003");
}
@Test
public void testFindAll() {
UserDao dao=new UserDaoImpl();
dao.findAll();
}
@Test
public void testlogin() {
UserDao dao=new UserDaoImpl();
dao.login("张三", "1001265sad' or '1=1");
}
}
jdbc工具类和配置文件
Statement安全问题
1. Statement执行 ,其实是拼接sql语句的。 先拼接sql语句,然后在一起执行。
public void login(String username, String password) {
Connection conn=null;
Statement st =null;
ResultSet rs =null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.创建ststement对象
st = conn.createStatement();
//3.执行查询
String sql = "select * from user_p where username='"+username+"' and password='"+password+"'";
rs = st.executeQuery(sql);
if (rs.next()) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(rs, st, conn);
}
}
测试实现时:
public void testlogin() {
UserDao dao=new UserDaoImpl();
dao.login("张三", "1001265sad' or '1=1");
}
前面先拼接sql语句, 如果变量里面带有了 数据库的关键字,那么一并认为是关键字。 不认为是普通的字符串。
PrepareStatement
该对象就是替换前面的statement对象。
1. 相比较以前的statement, 预先处理给定的sql语句,对其执行语法检查。 在sql语句里面使用 ? 占位符来替代后续要传递进来的变量。 后面进来的变量值,将会被看成是字符串,不会产生任何的关键字。
String sql = "insert into t_user values(null , ? , ?)";
ps = conn.prepareStatement(sql);
给占位符赋值 从左到右数过来,1 代表第一个问号, 永远你是1开始。
ps.setString(1, userName);
ps.setString(2, password);
上面的例子:
public void login(String username, String password) {
Connection conn=null;
Statement st =null;
ResultSet rs =null;
try {
//1.连接数据库
conn = JDBCUtil.jdbcConn();
//2.sql查询语句
String sql = "select * from user_p where username=? and password=?";
//3.预先对sql语句执行语法的校验,?对应的内容,后面不管传递什么进来,都把他看成字符串。or,select
PreparedStatement ps = conn.prepareStatement(sql);
//?对应的索引从1开始
ps.setString(1, username);
ps.setString(2, password);
rs=ps.executeQuery();
if (rs.next()) {
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.resease(rs, st, conn);
}
}