java通过dbcp操作数据库Crud(增删改查);

1、话不多说,直接看代码

首先准备一个数据库表                     源码获取百度云链接:链接: https://pan.baidu.com/s/1iY0NNAHgdkOywr1G7rTZ6Q 密码: b29b

:

第二准备:域对象类:用于传输数据使用的

package cn.jdbcpractice.domain;
/**
 * 
 * @author Administrator
 *domain域-->一个对象
 */
public class Student {
	private int id; //id
	private String username;//用户名
	private String passwrod;//用户密码
	private int age;//用户年龄
	private boolean sex;//用户性别
	private String intro;//用户简介
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPasswrod() {
		return passwrod;
	}

	public void setPasswrod(String passwrod) {
		this.passwrod = passwrod;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	

	public String getintro() {
		return intro;
	}

	public void setintro(String intro) {
		this.intro = intro;
	}

	public Student() {
		super();
	}



	public boolean isSex() {
		return sex;
	}

	public void setSex(boolean sex) {
		this.sex = sex;
	}

	public Student(String username, String passwrod, int age, boolean sex, String intro) {
		super();
		this.username = username;
		this.passwrod = passwrod;
		this.age = age;
		this.sex = sex;
		this.intro = intro;
	}


	public Student(int id, String username, String passwrod, int age, boolean sex, String intro) {
		super();
		this.id = id;
		this.username = username;
		this.passwrod = passwrod;
		this.age = age;
		this.sex = sex;
		this.intro = intro;
	}

	@Override //用于显示文字,不然只是地址值
	public String toString() {
		return "JdbcWork [id=" + id + ", username=" + username + ", passwrod=" + passwrod + ", age=" + age + ", sex="
				+ sex + ", intro=" + intro + "]";
	}
	
	
}

需要分层建一个dao包在下面建一个IStudentDao接口类:    login和login2用于验证登陆是否成功,并比较优缺点安全等问题...

package cn.jdbcpractice.dao;
import java.util.List;
import cn.jdbcpractice.domain.Student;

/*
 * @author Administrator
 *业务层 :定义crud
 */
public interface IStudentDao {
	public void save(Student stu); //添加用户
	public void delete(int sid);//删除用户
	public void update(Student stu);//修改用户信息
	public Student queryIdSingle(int sid);//查询单个用户信息
	public List<Student> queryIdAll();//查询多个用户信息
	public Student login(String username,String passwrod);//用户登陆preparestatement发送
	public Student login2(String username,String passwrod);//用户登陆statement发送
	
}

在dao包下再建一个impl包并建立IStudentDao的实现类StudentDaoImpl:

package cn.jdbcpractice.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import cn.jdbc.utils.*;
import cn.jdbcpractice.dao.IStudentDao;
import cn.jdbcpractice.domain.Student;
/**
*通过抽取类优化了增删改
*/
public class StudentDaoImpl implements IStudentDao {
	Connection conn = null; //定义连接对象用于连接数据库
	Statement st;//定义语句对象用于向数据库发送sql语句
	ResultSet rs;//用于保存查询返回的信息;结果集ResultSet 
	List<Student> studentlist = new ArrayList<>();//用于保存多条信息的学生类集合
	PreparedStatement prepare; //预编译语句对象,用于参数传值
	@Override //通过抽取后的代码:同级下抽取类为-->BaseDAOImpl
	public void save(Student stu) {// 添加
		String sql = "insert into student2(username,passwrod,age,sex,in 
          tro)values(?,?,?,?,?)";
        //调用BaseDAOImpl的executeUpdate(sql,values)方法,该类已经完成增删改,关闭资源
		new BaseDAOImpl().executeUpdate(sql, stu.getUsername(), stu.getPasswrod(), 
        stu.getAge(), stu.isSex(),stu.getintro());
	}
	@Override //通过抽取后的代码:同级下抽取类为-->BaseDAOImpl
	public void delete(int sid) { // 根據索引刪除
		String sql = "delete from student2 where id=? ";
		new BaseDAOImpl().executeUpdate(sql, sid);
	}

	@Override //通过抽取后的代码:同级下抽取类为-->BaseDAOImpl
	public void update(Student stu) {// 根據索引修改整行信息
		String sql = "update student2  set username=?,passwrod=?,age=?,sex=?,intro=? where id=?";
		new BaseDAOImpl().executeUpdate(sql, stu.getUsername(), stu.getPasswrod(), stu.getAge(), stu.isSex(),
				stu.getintro(), stu.getId());
	}

	@Override //查询单条数据(single单的)
	public Student queryIdSingle(int sid) {
		try {
			conn = DbcpUtils.getJdbcUtils().getConnDb();
			String sql = "select *from student2 where id=?";
			prepare = conn.prepareStatement(sql);
			prepare.setInt(1, sid);
			prepare.executeQuery();
			Student s = null;
			while (rs.next()) {
				s = new Student();
				s.setId(rs.getInt("id"));
				s.setUsername(rs.getString("username"));
				s.setPasswrod(rs.getString("passwrod"));
				s.setId(rs.getInt("age"));
				s.setSex(rs.getBoolean("sex"));
				s.setintro(rs.getString("intro"));
				System.out.println(s);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbcpUtils.getJdbcUtils().close(conn, st, rs);
		}
		return null;
	}

	@Override
	public List<Student> queryIdAll() {// 查看多條數據
		try {
			conn = DbcpUtils.getJdbcUtils().getConnDb();
			st = conn.createStatement();
			String sql = "select *from student2";
			rs = st.executeQuery(sql);
			while (rs.next()) {
				Student s2 = new Student();// 查詢到的保存在域對象
				s2.setId(rs.getInt("id"));
				s2.setUsername(rs.getString("username"));
				s2.setPasswrod(rs.getString("passwrod"));
				s2.setId(rs.getInt("age"));
				s2.setSex(rs.getBoolean("sex"));
				s2.setintro(rs.getString("intro"));
				studentlist.add(s2);// 多條數據添加到集合裏
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbcpUtils.getJdbcUtils().close(conn, st, rs);
		}
		return studentlist;
	}
/*----------------------------登陆使用发送sql语句安全问题----------*/
	@Override
	/**
	 * PreparedStatement比較安全,这种方式比较完善,可以判断用户名密码错误信息;通过界面比较 无需拼接,无注入漏洞;
	 */
//登陆方式一
	public Student login(String username, String passwrod) {
		Student stu = null;
		try {
			conn = DbcpUtils.getJdbcUtils().getConnDb();
			String sql = "select *from student2 where username=?";
			PreparedStatement pst = conn.prepareStatement(sql);
			pst.setString(1, username);
			ResultSet rs = pst.executeQuery();
			while (rs.next()) {
				stu = new Student();
				stu.setId(rs.getInt("id"));
				stu.setUsername(rs.getString("username"));
				stu.setPasswrod(rs.getString("passwrod"));
				stu.setId(rs.getInt("age"));
				stu.setSex(rs.getBoolean("sex"));
				stu.setintro(rs.getString("intro"));
				studentlist.add(stu);// 多條數據添加到集合裏
			}
			// 判断传入进来是否匹配数据库代码
			if (stu != null && username.equals(stu.getUsername())) {
				if (passwrod.equals(stu.getPasswrod())) {
					System.out.println("登陆成功");
				} else {
					System.out.println("用户名密码错误");
				}
			} else {
				System.out.println("用户不存在");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			cn.jdbc.utils.DbcpUtils.getJdbcUtils().close(conn, st, rs);
		}
		return stu;
	}
//登陆方式二
	@Override
	/**
	 * stataement拼接存在注入问题不安全;
	 */
	public Student login2(String username, String passwrod) {
		try {
			conn = DbcpUtils.getJdbcUtils().getConnDb();
			st = conn.createStatement();
			String sql = "select *from student2 where username='" + username + "'and passwrod='" + passwrod + "'";
			System.out.println(sql);
			ResultSet rs = st.executeQuery(sql);
			Student s = null;
			while (rs.next()) {
				s = new Student();
				s.setId(rs.getInt("id"));
				s.setUsername(rs.getString("username"));
				s.setPasswrod(rs.getString("passwrod"));
				s.setId(rs.getInt("age"));
				s.setSex(rs.getBoolean("sex"));
				s.setintro(rs.getString("intro"));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			DbcpUtils.getJdbcUtils().close(conn, st, rs);
		}
		return null;
	}

}

建一个同等级下的测试类TestJdbcWork:测试crud

public class TestJdbcWork {
	@Test //测试添加用户信息
	public void testSave() throws Exception {
		IStudentDao dao = new StudentDaoImpl();// 面向接口过程,实现类可以任意修改,但接口是固定的
		for (int i = 0; i <2; i++) {
			Student jk = new Student("架构师2", "666666", 18, true, "生当作人杰,死亦为鬼雄");
			dao.save(jk);
		}
	}
	@Test //测试删除功能
	public void testDelete() throws Exception {
		IStudentDao dao = new StudentDaoImpl();
		dao.delete(28);
	}
	@Test //测试修改用户信息功能
	public void testUpdate() throws Exception {
		IStudentDao dao = new StudentDaoImpl();// 面向接口过程,实现类可以任意修改,但接口是固定的
		Student s = new Student(27, "架构师大佬", "888888", 15, false, "很帅");
		dao.update(s);
	}

	@Test //测试查询单个用户信息
	public void testquery() throws Exception {
		IStudentDao dao = new StudentDaoImpl();
		dao.queryIdSingle(1);//查询id等于1的用户信息
	}
	@Test //用于测试多条用户信息
	public void testqueryAll() throws Exception {
		IStudentDao dao = new StudentDaoImpl();
		List<Student> studentList = dao.queryIdAll();
		if (studentList.size() != 0) { //判断下,加快效率
            //迭代遍历出所有查询到的信息
			for (Student student : studentList) {
				System.out.println(student);
			}
		} else {
			System.out.println("没有数据");
		}
	}
	@Test //登陆方式一:可以查看用户其他信息,可以查询用户名还是密码错误
	public void testlogin() throws Exception {
		/**
		 * 安全不存在注入危险,因为它不拼接字符串
		 */
		IStudentDao dao = new StudentDaoImpl();
		String username = "高级架构师2";
		String passwrod = "000000";
		Student login = dao.login(username, passwrod);
	}

	@Test //登陆方式二:不能清楚用户名还是密码错误,但可以查看其他信息;
	public void testlogin2() throws Exception {
		/**
		 * 存在注入危险,拼接可以'or 1=1 or'恒成立为true忽略后面附加限制
		 */
		IStudentDao dao = new StudentDaoImpl();
		String username2 = "'or 1=1 or'";
		String passwrod2 = "000000";
		Student stu = dao.login2(username2, passwrod2);
		if (username2 != null) {
			System.out.println(stu);
			System.out.println("登陆成功");
		} else {
			System.out.println("登录失败");
		}
	}
}

我封装的工具类DbcpUtils:用于加载驱动连接数据库;

首先解决的硬编码问题:创建一个资源文件-->写你自己的配置信息

配置信息

package cn.jdbc.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DbcpUtils { //单利模式:工具类不需要创建太多对象
	private static DbcpUtils instance = null;
	private DbcpUtils() {
	}
	// 用于读取资源文件
	private static Properties p;
	//创建一个变量用于保存连接池对象
	private static BasicDataSource database;
	static {//调用方法时就加载驱动
		try {
			p = new Properties();
			// 通过当前类加载器获取资源
			p.load(Thread.currentThread().getContextClassLoader().
					getResourceAsStream("jdbc.properties"));
			//创建一个连接池对象
			database=new BasicDataSource();
			//连接池对象去获取连接数据库信息
		    //通过BasicDataSourceFactory工厂拿到连接(内部已实现获取url、username、              password..等)
			database=(BasicDataSource) BasicDataSourceFactory.createDataSource(p);
			//连接池启动时的初始值
			database.setInitialSize(1);
			//创建对象
			instance = new DbcpUtils();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//获取连接 直接从连接池里面拿
	public Connection getConnDb() {
		try {
			return database.getConnection();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public static DbcpUtils getJdbcUtils() {
		return instance;
	}
	//关闭方法 用来之后,自动还给连接池
	public void close(Connection conn, Statement st, ResultSet rs) {
		// 关闭资源
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (Exception e2) {
			e2.printStackTrace();
		} finally {
			try {
				if (st != null) {
					st.close();
				}
			} catch (Exception e3) {
				e3.printStackTrace();
			} finally {
				try {
					if (conn != null) {
						conn.close();
					}
				} catch (Exception e3) {
					e3.printStackTrace();
				}
			}
		}

	}
}

最后优化增删改类BaseDAOImpl :抽取重复代码

package cn.jdbcpractice.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import cn.jdbc.utils.DbcpUtils;

public class BaseDAOImpl {
	Connection conn=null;
	PreparedStatement pst=null;
		/**
		 *  抽取 (增,删,改方法)
		 *  Object ...params:各种类型字段,解决硬编码问题
		 *  String sql:需要传入的sql执行语句
		 */
	public void executeUpdate(String sql,Object ...params){
			
		try {
			conn = DbcpUtils.getJdbcUtils().getConnDb();
			 pst = conn.prepareStatement(sql);
			 //传入的字段参数,长度为传入参数的长度
			 for(int i=1;i<=params.length;i++){
				 pst.setObject(i, params[i-1]);//填充值
			 }
			 pst.executeUpdate();//执行sql语句
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{//关闭资源;节约内存
			DbcpUtils.getJdbcUtils().close(conn, pst, null);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/Yangyg_0818/article/details/81255555