JDBC

2019-08-19  本文已影响0人  牛倩贱

JDBC总结:

1.jdbc入门

2.抽取工具类

3.jdbc与java代码联系的基本sql语句操作

4.JDBC JUnit  增删改查操作

5.Dao模式

6.PrepareStatement 的增删改查操作


1.JDBC入门程序

        先在SQLyog中创建数据库student,然后创建表,最后再和java程序进行连接。在项目目录下创建lib文件夹,找到mysql-connector-java-5.1.7-bin.jar文件粘贴进去。

        步骤分析:1.注册驱动  DriverManager.registerDriver(new com.mysql.jdbc.Driver());

                          2.建立连接 2.建立连接,将代码和student数据库连接起来。参数一:协议+数据库名字;参数二:                                用户名;参数三:密码;

                        Connection conn =DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");

                            3.创建statement对象;Statement st = conn.createStatement();

                            4.执行查询,得到结果集

                              //先写sql语句,在写查询函数

                              String sql = "select * from t_student";

                              //查询一个数据库,肯定会返回一个东西回来,用其接收一下就OK

                              ResultSet rs = st.executeQuery(sql);

                            5.遍历查询到的每一条数据记录

                            6.释放对象资源

初步代码如下:

package com.jdbc.two;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class JDBCtest {

public static void main(String[] args) {

try {

//1.注册驱动

DriverManager.registerDriver(new com.mysql.jdbc.Driver());

//2.建立连接,将代码和student数据库连接起来

//参数一:协议+数据库名字;参数二:用户名;参数三:密码

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");

//3.创建statement对象

Statement st = conn.createStatement();

//4.执行查询,得到结果集

//先写sql语句,在写查询函数

String sql = "select * from t_student";

//查询一个数据库,肯定会返回一个东西回来,用其接收一下就OK

ResultSet rs = st.executeQuery(sql);

//要接受每一条数据,要遍历ResultSet

//5.遍历查询每一条数据,ResultSet里有个方法next()方法

while(rs.next()){

int id = rs.getInt("id");

String name = rs.getString("name");

int age = rs.getInt("age");

System.out.println("id="+id+"==name=="+name+"==age=="+age);

}

//释放对象,要反顺序释放

rs.close();

st.close();

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}


2.JDBC程序优化改动

a.首先将释放资源那部分,按照文档要求写进finally里面,当然写在finally里面之后那三个对象就得放在外面了,否则找不到声明,然后抓三个释放资源的异常,最好在写一个判空操作,防止执行到后面空指针。由于释放资源的过程比较繁琐且重复较多,所以可以写一个工具类来帮助我们更好的提高代码的可读性。

工具类代码如下:package com.jdbc.two;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

//jdbc工具类

public class JDBCUtil {

public static void relese(Connection conn,Statement st,ResultSet rs){

closeRs(rs);

closeSt(st);

closeConn(conn);

}

//释放资源,按相反的顺序释放rs,st,conn

private static void closeRs(ResultSet rs){

try {

if(rs != null){

rs.close();

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

rs = null;

}

}

private static void closeSt(Statement st){

try {

if(st != null){

st.close();

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

st=null;

}

}

private static void closeConn(Connection conn){

try {

if(conn != null){

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

conn = null;

}

}

}


3.JDBC工具类注册驱动,因为Driver这个类中有静态代码块,只要类加载了就会执行,所以等同于注册了两次,所以要修改为下面的那种

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());

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

4.JDBC工具类连接对象整合

5.JDBC工具类创建properties配置文件,因为修改数据库或者协议等等,如果每次在代码中修改容易出错,所以创建一个配置文件,用于辅助,配置文件代码如下:

driverClass = com.mysql.jdbc.Driver

url = jdbc:mysql://localhost/student

name = root

password = root

6.JDBC工具类读取配置文件

        在读取配置文件时,需要注意的是,如果文件在src目录下就要用类加载器的方式来读取:

InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("JDBC.properties");

        如果配置文件在项目根目录下,代码如下:

InputStream is = new FileInputStream("JDBC.properties")


7.工具类代码改善完成版

package com.jdbc.two;

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;

//jdbc工具类

public class JDBCUtil {

static String driverClass = null;

static String url = null;

static String name = null;

static String password = null;

//配置文件properties要求在类加载时,所以写在静态代码块里

static{

try {

//创建一个属性配置对象

Properties properties = new Properties();

//使用类加载器,去读取src底下的资源文件,对应文件位于src目录下

InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("JDBC.properties");

//导入输入流

properties.load(is);

//读取属性

driverClass = properties.getProperty("driverClass");

url = properties.getProperty("url");

name = properties.getProperty("name");

password = properties.getProperty("password");

} catch (Exception e) {

e.printStackTrace();

}

}

//调用释放各个对象资源的方法,做一整合,统一调用

public static void relese(Connection conn,Statement st,ResultSet rs){

closeRs(rs);

closeSt(st);

closeConn(conn);

}

//方法重载以下,以便进行添加或其他数据库操作时使用 

public static void relese(Connection conn,Statement st){

closeSt(st); closeConn(conn);

}

//连接对象整合

//获取连接对象

public static Connection getconn(){

Connection conn = null;

try {

/*//1.注册驱动,因为Driver这个类中有静态代码块,只要类加载了就会执行,所以等同于注册了两次,所以要修改为下面的那种

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());

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

//2.建立连接,将代码和student数据库连接起来

//参数一:协议+数据库名字;参数二:用户名;参数三:密码

conn = DriverManager.getConnection("jdbc:mysql://localhost/student", "root", "root");*/

//注册驱动

Class.forName(driverClass);

//建立连接

conn = DriverManager.getConnection(url, name, password);

} catch (Exception e) {

}

return conn;

}

//释放资源,按相反的顺序释放rs,st,conn

private static void closeRs(ResultSet rs){

try {

if(rs != null){

rs.close();

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

rs = null;

}

}

private static void closeSt(Statement st){

try {

if(st != null){

st.close();

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

st=null;

}

}

private static void closeConn(Connection conn){

try {

if(conn != null){

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}finally{

conn = null;

}

}

}


8.JDBC与java代码的关联基本操作(sql语句)

练习1:查询表中数据,代码如下:

package com.jdbc.CRUD.test;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.Statement;

import com.jdbc.CRUD.util.JDBCUtil;

public class CRUDtest {

public static void main(String[] args) {

Connection conn = null;

Statement st = null;

ResultSet rs = null;

try {

//1.驱动注册建立连接(获取连接对象)

conn = JDBCUtil.getconn();

//2.根据连接对象,得到Statement

st = conn.createStatement();

//3.执行sql语句,返回ResultSet结果集

String sql = "select * from t_student";

    rs = st.executeQuery(sql);

//4.遍历结果集,接收数据

while(rs.next()){

String name = rs.getString("name");

int age = rs.getInt("age");

System.out.println(name+"    "+age);

}

} catch (Exception e) {

e.printStackTrace();

//5.释放资源

}finally{

JDBCUtil.relese(conn, st, rs);

}

}

}


9.使用JUnit执行单元测试(测试查询)

例:测试上面的代码跑不跑的下去

package com.jdbc.CRUD.test;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.Statement;

import org.junit.Test;

import com.jdbc.CRUD.util.JDBCUtil;

/*使用junit执行单元测试

* 1.定义一个类,Testxxx,类里面的方法一般也写testxxx

* 2.添加JUnit支持

* (右键工程,Build Path,Add Libraries,JUnit,next)

* 这时工程目录下就已经有JUnit了

* 3.使用测试,在所写方法的上面写上@Test

*  @Test

*  public void testQuery(){

*  .............

*  }

* */

public class TestDemo {

@Test

public void testQuery(){

//将要测试的代码放进来

Connection conn = null;

Statement st = null;

ResultSet rs = null;

try {

//1.驱动注册建立连接(获取连接对象)

conn = JDBCUtil.getconn();

//2.根据连接对象,得到Statement

st = conn.createStatement();

//3.执行sql语句,返回ResultSet结果集

String sql = "select * from t_student";

    rs = st.executeQuery(sql);

//4.遍历结果集,接收数据

while(rs.next()){

String name = rs.getString("name");

int age = rs.getInt("age");

System.out.println(name+"    "+age);

}

} catch (Exception e) {

e.printStackTrace();

//5.释放资源

}finally{

JDBCUtil.relese(conn, st, rs);

}

}

}

10.JUnit添加

执行添加时Statement对象st的方法就不能是查询时候的excuteQuery了,要变为excuteUpdate;excuteUpdate(sql)返回的是添加了多少行的行数,所以用int来接收,就也不是以前的ResultSet对象了。

代码如下:

@Test

public void testInsert(){

Connection conn = null;

Statement st = null;              //这里没有ResultSet了所以下面释放资源的时候也就不能继续调用哪个以前                                                  的方法了,需要在工具类里,重载一个Relese方法,public static void                                                        relese(Connection conn,Statement st){ closeSt(st); closeConn(conn); }

try {

//1.驱动注册建立连接(获取连接对象)

conn = JDBCUtil.getconn();

//2.根据连接对象,得到Statement

st = conn.createStatement();

//3.执行添加

String sql = "insert into t_student values(null,'fanhaolan',20)";

//因为executeUpdate方法返回的是添加的行数,所以如果大于0则添加成功,否则失败,用int接收

int result = st.executeUpdate(sql);

//4.查看结果,是否成功

if(result>0){

System.out.println("添加成功");

}else{

System.out.println("添加失败");

}

} catch (Exception e) {

e.printStackTrace();

}finally{

JDBCUtil.relese(conn, st);

}

11.Junit,删除&更新

删除:方法也是excuteUpdate(sql)

sql语句,String sql  = delete from t_student where name='fanhaolan';

int result = st.executeUpdate(sql);

//4.查看结果,是否成功

if(result>0){

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

}else{

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

}

更新://Junit修改

//String sql = "update t_student set age = 26 where name = 'fanhaolan'";

12.JDBC    Dao模式

以查询为例:

新创建一个数据库User,创建表t_user,所以在等会写代码的时候一定要修改配置文件中的数据库名字

a.先写一个接口,里面写增删改查的大方法,

package com.jdbc.Dao;

public interface UserDao {

/*查询所有 * */

void findAll();

}

b.在写一个类去实现这个接口,将里面的方法区重写,使其赋予你想赋予的功能(查询)

package com.jdbc.Dao.impl;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.Statement;

import com.jdbc.Dao.UserDao;

import com.jdbc.util.JDBCUtil;

public class UserDaoImpl implements UserDao{

Connection conn = null;

Statement st = null;

ResultSet rs = null;

@Override

public void findAll() {

try {

//1.获取连接对象

conn = JDBCUtil.getconn();

//2.创建Statement对象

st = conn.createStatement();

//3.sql语句,得到结果集

String sql = "select * from t_user";    //记得修改配置文件内数据库的名字,因为这里是新创建的数据库

rs = st.executeQuery(sql);

while(rs.next()){

String username = rs.getString("username");

String password = rs.getString("password");

System.out.println(username+"  "+password);

}

} catch (Exception e) {

e.printStackTrace();

}finally{

JDBCUtil.relese(conn, st, rs);

}

}

}

c.最后在写一个测试类,父类的对象指向子类的引用,用Junit完成测试

package com.jdbc.test;

import org.junit.Test;

import com.jdbc.Dao.UserDao;

import com.jdbc.Dao.impl.UserDaoImpl;

public class TestUserDaoImpl {

@Test

public void testfindAll(){

UserDao dao = new UserDaoImpl();

dao.findAll();

}

}

13.JDBC Statement安全问题引出PrepareStatement

        登录问题里,一定要先去查询数据库,然后匹配给定的用户名和密码等等,才能登录成功,但是Statement对象的执行,是先拼接sql语句,然后在一起执行,如果传入的参数变量中带有了数据库的关键字如or,那么他会一并的认为是关键字而不是字符串,假如写了String sql = "select * from t_user where username = '"+ username +"'and password = '"+ password +"'";目的是为了匹配登录的,但如果最后将传入的参数写成dao.login("admin",'1234567' or '1=1');这样写虽然我们自己知道这肯定是错误的,但是数据库会把这句话最终翻译成select * from t_user where username = 'admin' and password = '1234567' or '1=1';所以上述代码password的意思是1234567或1=1成立都可登录成功,也正是因为这样,才有了PrepareStatement。

        PrepareStatement,该对象就是替换前面的Statement对象,String sql = "select * from t_user where username = ? and password = ?";

预先对sql语句执行语法的校验,?对应的内容,不管以后传什么参数进来,都会把它看成字符串

还是以登录为例,代码书写为:

                            a.获取连接对象

                            b.创建PrepareStatement对象

                                ..........

//1.获取连接对象

conn = JDBCUtil.getconn();

//2.创建PrepareStatement对象

String sql = "select * from t_user where username = ? and password = ?";

//预先对sql语句执行语法的校验,?对应的内容,不管以后传什么参数进来,都会把它看成字符串

PreparedStatement ps = conn.prepareStatement(sql);

ps.setString(1, username);

ps.setString(2, password);

rs = ps.executeQuery();

if(rs.next()){

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

}else{

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

}

14.JDBC PrepareStatement增删改查的所有写法代码

package com.jdbc.Dao.impl;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.Statement;

import com.jdbc.Dao.UserDao;

import com.jdbc.util.JDBCUtil;

public class UserDaoImpl implements UserDao{

Connection conn = null;

Statement st = null;

ResultSet rs = null;

@Override

public void findAll() {

try {

//1.获取连接对象

conn = JDBCUtil.getconn();

//2.创建Statement对象

st = conn.createStatement();

//3.sql语句,得到结果集

String sql = "select * from t_user";

rs = st.executeQuery(sql);

while(rs.next()){

String username = rs.getString("username");

String password = rs.getString("password");

System.out.println(username+"  "+password);

}

} catch (Exception e) {

e.printStackTrace();

}finally{

JDBCUtil.relese(conn, st, rs);

}

}

@Override

public void login(String username, String password) {

Connection conn = null;

Statement st = null;

ResultSet rs = null;

try {

//1.获取连接对象

conn = JDBCUtil.getconn();

//2.创建PrepareStatement对象

String sql = "select * from t_user where username = ? and password = ?";

//预先对sql语句执行语法的校验,?对应的内容,不管以后传什么参数进来,都会把它看成字符串

PreparedStatement ps = conn.prepareStatement(sql);

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.relese(conn, st, rs);

}

}

@Override

public void insert(String username, String password) {

Connection conn = null;

PreparedStatement ps = null;

try {

conn = JDBCUtil.getconn();

String sql = "insert into t_user values(null,?,?)";

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 (Exception e) {

e.printStackTrace();

}finally{

JDBCUtil.relese(conn, st);

}

}

@Override

public void delete(int id) {

Connection conn = null;

PreparedStatement ps = null;

try {

conn = JDBCUtil.getconn();

String sql = "delete from t_user where id = ? ";

ps = conn.prepareStatement(sql);

ps.setInt(1, id);

int result = ps.executeUpdate();

if(result>0){

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

}else{

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

}

} catch (Exception e) {

e.printStackTrace();

}finally{

JDBCUtil.relese(conn, ps);

}

}

@Override

public void update(int id, String username) {

Connection conn = null;

PreparedStatement ps = null;

try {

conn = JDBCUtil.getconn();

String sql = "update t_user set username = ? where id = ? ";

ps = conn.prepareStatement(sql);

ps.setString(1, username);

ps.setInt(2, id);

int result = ps.executeUpdate();

if(result>0){

System.out.println("修改成功");

}else{

System.out.println("修改失败");

}

} catch (Exception e) {

e.printStackTrace();

}finally{

JDBCUtil.relese(conn, ps);

}

}

}

上一篇下一篇

猜你喜欢

热点阅读