JDBC

来源:互联网 发布:淘宝分流比例设置 编辑:程序博客网 时间:2024/06/06 18:58

1. JDBC

作用?

通过JDBC操作保存在数据库中的数据。

重要性

学得好,以后学数据库相关框架轻松;如果不精通,不是专业的研发。

1.1. JDBC使用步骤

1.1.1. 将驱动引入项目

方式1: 新建空白工程 ,选择工程  ,右击 properties -àjava build path-àLibrary-àadd external JARS ,在弹出的选择框中选中某一个硬盘上的 连接驱动包  mysql-connector-java.-5.1.7-bin.jar

方式2:(推荐)

在项目根目录新建文件夹lib,把数据库驱动mysql-connector-java-5.1.7-bin.jar放入该文件夹(拷贝到该文件夹中)。

l 右键点击项目名称->properties->Java Build Path->Libraries->Add JARs->找到驱动文件->搞定

什么是mysql-connector-java-5.1.7-bin.jar?

数据库驱动。

为什么要另外引入一个jar包,sun公司怎么没有实现这些功能?

因为市面上有很多数据库mysql oracle sqlserver,每个数据库内部实现不同,sun公司提供标准接口,数据库提供商负责实现接口,把所有实现类打包成.jar文件。有了这个jar包,java程序就可以驱动着数据库做事。

1.1.2. 测试数据库连通性

先确保java程序和数据库之间的连接正常再进行开发。

package com.njwb.connection;

import java.sql.DriverManager;

import java.sql.SQLException;

/**

 * sqlException Access denied  password use   @localost  yes...

 *  重置root的密码

 *  use  mysql;

 *  update user set password = password('root') where user = 'root';

 *  flush privileges;

 * @author Administrator

 *

 */

public class TestConn01 {

public static void main(String[] args) {

//加载驱动

try {

//固定的字符串

Class.forName("com.mysql.jdbc.Driver");

System.out.println("加载驱动成功");

} catch (ClassNotFoundException e1) {

e1.printStackTrace();

System.out.println("加载驱动失败");

}

//获取连接对象

try {

// jdbc:mysql://ip地址:3306/数据库名  ,数据库的登录用户名 ,登录的密码

//DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/njwangbo1", "root", "root");

DriverManager.getConnection("jdbc:mysql://localhost:3306/njwangbo1","root", "root");

System.out.println("获取连接对象成功");

} catch (SQLException e) {

e.printStackTrace();

System.out.println("获取连接对象失败");

}

}

}

1.1.3. 修改MySQL用户权限

如果连接失败,提示“is not allowed to connect to this MySQL server”,在服务器上执行:

GRANT ALL ON *.* TO root@'%' IDENTIFIED BY 'root';

GRANT ALL ON *.* TO root@'127.0.0.1' IDENTIFIED BY 'root';

允许任何IP可以使用root账户连接数据库。

1.2. 使用JDBC操作数据

1.2.1. 需求:实现用户注册功能

使用java代码在数据库中插入一条记录。

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

/**

 * 注册新用户

 * @author Administrator

 *

 */

public class TestRegist {

public static void main(String[] args) {

regist("helen","123abc");

}

/**

 * 根据指定的的用户名,密码注册

 * @param userName

 * @param pwd

 */

public static void regist(String userName,String pwd){

try {

//1.加载驱动

Class.forName("com.mysql.jdbc.Driver");

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

Connection conn = null;

Statement st = null;

try {

//2.获取连接对象

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/njwangbo1","root", "root");

//3.准备sql语句,获取sql执行器对象

String sql =  "insert into t_user(t_userName,t_pwd)  values('"+userName+"','"+pwd+"')";

st = conn.createStatement();

//4.执行,丙返回处理结果

int rowCount = st.executeUpdate(sql);

if(rowCount>0){

System.out.println("注册成功");

}else{

System.out.println("注册失败");

}

} catch (Exception e) {

System.out.println("conn="+conn+",st="+st);

e.printStackTrace();

}finally{

//5.关闭资源

if(null!=st){

try {

st.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if(null!=conn){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

}

1.2.2. 设计一张用户表

create table t_user(

t_id int  auto_increment primary key,

t_userName varchar(30),

t_pwd int

)engine=InnoDB;

insert into t_user (t_userName,t_pwd)

values('tom','123456'),

('jack','123456');

1.2.3. 使用java插入数据

1.2.4. 使用完必须关闭连接

先打开的后关闭   ResultSet--> Statement/PreparedStatement-->  Connection

1.2.5. 封装成增删改方法

注意:在JAVA代码中调用SQL语句SQL末尾不需要加分号。

编写一个注册方法reg,传入两个参数用户名和密码。

main中调用一次该方法,向数据库中写入一条记录。

编写一个方法updateById,传入两个参数用户名和id。

使用executeUpdate执行SQL语句,根据id修改用户名。

update t_user set userName = '' where id=''

main中调用一次该方法,修改一条记录。

public static void  updateById(String userName,int id)

编写一个方法delById,传入一个参数id。

使用executeUpdate执行SQL语句,根据id删除该条记录。

delete from t_user where id =

main中调用一次该方法,修改一个用户。

public static void delById(int id);

1.2.6. 需求:实现用户登录功能

/**

 * 登录的方式1

 * 根据指定的用户名, 密码 查询用户,如果能够查询到数据,则提示登录成功 ,否则登录失败

 * @author Administrator

 *

 */

public class TestLogin01 {

public static void main(String[] args) {

login("tom","123456");

}

/**

 * 将登录封装成方法

 * @param userName

 * @param pwd

 */

public static void login(StringuserName,String pwd){

//1.加载驱动

……..

//在这边声明,方便在finally里关闭

Connection conn=null;

Statement st=null;

ResultSet rs=null;

try {

//2.获取数据库连接

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/njwangbo1","root", "root");

//3.准备sql语句,获取sql执行器对象

String sql = "select   *   from t_user where t_userName='"+userName+"' and t_pwd = '"+pwd+"' ";

st= conn.createStatement();

//4.执行,并返回处理结果  执行器对象stsql语句发送到数据库,返回处理结果(返回的是ResultSet结果集对象)

rs= st.executeQuery(sql);

//判断能否查询到数据

if(rs.next()){

//System.out.println(rs.getInt("t_id")+"\t"+rs.getString("t_userName")+"\t"+rs.getString("t_pwd"));

System.out.println("登录成功");

}else{

System.out.println("登录失败");

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

//5.关闭资源

………

}

}

}

/**

 * 登录的方式2

 * --根据指定的用户名,密码,查询在数据库表中出现的记录数(出现的行数),如果记录数=1,显示登录成功,否则登录失败  

 * @author Administrator

 *

 */

public class TestLogin02 {

public static void main(String[] args) {

login("tom","123456");

}

/**

 * 将登录封装成方法

 * @param userName

 * @param pwd

 */

public static void login(String userName,String pwd){

//1.加载驱动

……..

//在这边声明,方便在finally里关闭

Connection conn=null;

Statement st=null;

ResultSet rs=null;

try {

//2.获取数据库连接

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/njwangbo1","root", "root");

//3.准备sql语句,获取sql执行器对象

//Stringsql = "select   count(*)   from t_user where t_userName='"+userName+"' and t_pwd = '"+pwd+"' ";

String sql = "select   count(*) as c   from t_user where t_userName='"+userName+"' and t_pwd = '"+pwd+"' ";

st= conn.createStatement();

//4.执行,并返回处理结果  执行器对象stsql语句发送到数据库,返回处理结果(返回的是ResultSet结果集对象)

rs= st.executeQuery(sql);

//判断能否查询到数据  (假设都不重名,只有用户名,密码正确的时候,才能返回1 )

if(rs.next() && rs.getInt("c")==1){

//System.out.println("符合条件的记录数(几行):"+rs.getInt(1));

//System.out.println("符合条件的记录数(几行):"+rs.getInt("c"));

System.out.println("登录成功");

}else{

System.out.println("登录失败");

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

//5.关闭资源

…….

}

}

}

总结

l excuteUpdate执行insert、update、delete返回影响的行数

l excuteQuery执行select返回结果集ResultSet

1.2.7. 查询用户表中所有用户

package com.njwb.connection;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

 

/**

 * 查询数据库中njwangbo1t_user表中的所有的数据,输出在console控制台中

 * 1.加载驱动

 * 2.获取数据库连接  

 * 3.准备sql语句,获取sql执行器对象(Statement PreparedStatement

 * 4.执行,并返回处理结果

 * 5.关闭资源

 * 注意:A. Connection导包 java.sql.Connection ,Statementst 

 * B.查询  executeQuery()  返回的ResultSet结果集对象

 * 增,删,改  executeUpdate()返回的受影响的行数  int

 * C.先打开的后关闭   ResultSet--> Statement/PreparedStatement-->  Connection

 * @author Administrator

 *

 */

public class TestQueryAll {

public static void main(String[] args) {

//1.加载驱动

try {

Class.forName("com.mysql.jdbc.Driver");

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

//在这边声明,方便在finally里关闭

Connection conn=null;

Statement st=null;

ResultSet rs=null;

try {

//2.获取数据库连接

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/njwangbo1","root", "root");

//3.准备sql语句,获取sql执行器对象

//Stringsql = "select   *   from t_user";

String sql = "select t_id as 'bianhao',t_userName as 'name', t_pwd as 'pwd' from t_user";

st= conn.createStatement();

//4.执行,并返回处理结果  执行器对象stsql语句发送到数据库,返回处理结果(返回的是ResultSet结果集对象)

rs= st.executeQuery(sql);

//取出数据遍历结果集

System.out.println("用户编号\t用户名\t登录密码");

//next()判断下一个是否有值,如果有值返回true,否则返回false作用和Iterator迭代器的hasNext()类似

while(rs.next()){

//方式1: 推荐(列名)

//System.out.println(rs.getInt("t_id")+"\t"+rs.getString("t_userName")+"\t"+rs.getString("t_pwd"));

//方式2:(索引 从1开始)

//System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));

//方式3:(别名)

System.out.println(rs.getInt("bianhao")+"\t"+rs.getString("name")+"\t"+rs.getString("pwd"));

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

//5.关闭资源

if(null!=rs){

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if(null!=st){

try {

st.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if(null!=conn){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

}

1.2.8. prepareStatement

public class TestLogin012 {

public static void main(String[] args) {

//select   *   from t_user where t_userName='afafar23waq323' and t_pwd = ' 455gfafa' or '1' = '1'

login("afafar23waq323"," 455gfafa' or '1' = '1");

}

/**

 * 将登录封装成方法

 * @param userName

 * @param pwd

 */

public static void login(String userName,Stringpwd){

//1.加载驱动

……..

//在这边声明,方便在finally里关闭

Connection conn=null;

PreparedStatement pst=null;

ResultSet rs=null;

try {

//2.获取数据库连接

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/njwangbo1","root", "root");

//3.准备sql语句,获取sql执行器对象

String sql = "select   *   from t_user where t_userName= ? and t_pwd=?";

System.out.println("sql="+sql);

pst= conn.prepareStatement(sql);

//在执行之前,需要设置占位符

pst.setString(1, userName);

pst.setString(2, pwd);

//4.执行,并返回处理结果  执行器对象stsql语句发送到数据库,返回处理结果(返回的是ResultSet结果集对象)

rs= pst.executeQuery();

//判断能否查询到数据

if(rs.next()){

System.out.println(rs.getInt("t_id")+"\t"+rs.getString("t_userName")+"\t"+rs.getString("t_pwd"));

System.out.println("登录成功");

}else{

System.out.println("登录失败");

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

//5.关闭资源

…….

}

}

}

 

1.2.9. Statement和prepareStatement的区别

关系: Statement是PreparedStatement的超级接口(父接口)

statement的用法

Connection conn =DriverManager.getConnection(url,userName,pwd);

String sql = "......";

Statement st = conn.createStatement();

//增,删,改

int count = st.executeUpdate(sql);

//查询

ResultSet rs = st.execuQuery(sql);

statement代码可读性差

insert into table1(col1,col2,col3,col4,.......)  values ('+v1+"','"+v2+"','"+v3+"','"+v4+......+"')"  

拼串,容易造成错误,单引号多的时候

PrepareStatement的用法

insert into table1(col1,col2,col3,col4,.......)  values (?,?,?,?)

Connection conn =DriverManager.getConnection(url,userName,pwd);

String sql = "......";

//获取执行器对象

PreparedStatement pst = conn.preparedStatement(sql);

//设置占位符

pst.setObject(1,v1);

pst.setObject(2,V2);

pst.setObject(3,V3);

pst.setObject(4,V4);

......

//执行,并返回处理结果

//增,删,改

int count = st.executeUpdate();

//查询

ResultSet rs = st.executeQuery();

l PrepareStatement代码可读性高

insert into table1(col1,col2,col3,col4,.......)  values (?,?,?,?) ,占位符的方式,可读性高

l Statement拼串造成sql注入安全性问题

select   *   from t_user where t_userName='afafar23waq323' and t_pwd = ' 455gfafa' or '1' = '1'

如果 这样写 ,那么整张表的数据都会被删除。

select   *   from t_user where t_userName='afafar23waq323' and t_pwd = ' 455gfafa' or '1' = '1';drop table t_user;

l PrepareStatement预编译语句,传入任何内容不会和原来的语句发生任何匹配的关系,只要全使用预编译语句,就用不着对传入的数据做任何过虑。

/**

 * sql注入  ’1‘=’1‘恒等,永远成立的

 * 用错误的用户名,密码登陆,会将整张表的数据获取到

 * @author Administrator

 *

 */

public class TestLogin012 {

public static void main(String[] args) {

//select   *   from t_user where t_userName='afafar23waq323' and t_pwd = ' 455gfafa' or '1' = '1'

login("afafar23waq323"," 455gfafa' or '1' = '1");

}

/**

 * 将登录封装成方法

 * @param userName

 * @param pwd

 */

public static void login(String userName,String pwd){

//1.加载驱动

…….

Connection conn=null;

Statement st=null;

ResultSet rs=null;

try {

//2.获取数据库连接

conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/njwangbo1","root", "root");

//3.准备sql语句,获取sql执行器对象

String sql = "select   *   from t_user where t_userName='"+userName+"' and t_pwd = '"+pwd+"' ";

System.out.println("sql="+sql);

st= conn.createStatement();

//4.执行,并返回处理结果  执行器对象stsql语句发送到数据库,返回处理结果(返回的是ResultSet结果集对象)

rs= st.executeQuery(sql);

//判断能否查询到数据

if(rs.next()){

System.out.println(rs.getInt("t_id")+"\t"+rs.getString("t_userName")+"\t"+rs.getString("t_pwd"));

System.out.println("登录成功");

sql = "drop table t_user";

int count = st.executeUpdate(sql);  

  //注意此处虽然显示的删除失败,count=0,但是仍旧会将数据库的整张表结构删除掉

System.out.println("#####count="+count);

if(count>0){

System.out.println("删除成功");

}else{

System.out.println("删除失败");

}

}else{

System.out.println("登录失败");

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

//5.关闭资源

}

}

}