1.连接
JDBC---java database connection java数据库连接。 通过java代码来操作数据库表中的记录。
2. 增删改---这三个模式.
3. 步骤:
(1)加载驱动: Class.forName("com.mysql.cj.jdbc.Driver");
(2)获取连接对象: Connection conn=DriverManager.getConnection(url,u,p);
(3)获取执行sql语句的对象: Statement st=conn.createStatement();
(4)执行增删改的语句: st.executeUpdate(sql);
2.SQL注入安全问题
//演示sql注入的安全问题
public static void main(String [] args) throws Exception{
Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
System.out.print("请输入账号:");
String username = scanner.nextLine();
System.out.print("请输入密码:");
String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束 next()输入空格后认为输入结束。
boolean b = sqlSafe(username, password);
}
//根据name查询数据 abc 演示的根据账号和密码查询数据库表记录 如果能查询表示登录成功 否则登录失败
private static boolean sqlSafe(String name,String password) throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection
("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "PAssW0rd");
Statement statement = conn.createStatement();
//这里的admin 是不是一个死数据 123456 也是一个死数据
String sql="select * from user where username='"+name+"' and password='"+password+"'";
System.out.println(sql);
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.println("登录成功");
return true;
}
System.out.println("登录失败");
return false;
}
可以发现: 你的账号可以随便输入 你的密码也可以随便输入 但是 在输入密码时 or '4'='4 只要这个条件成立,那么你就能登录成功。 这个就是sql注入的安全问题。只要根据条件做sql。那么就会出现sql注入安全问题。
如何解决sql安全注入问题:
1. 前端做校验: --只防君子 防不了小人。
2. 后端也做校验:--难道以后每次写功能都进行校验吗? 代码变得复杂了。
3. 执行sql的类Statement出现了问题,后期PrepareStatement该类来解决sql注入安全问题。
Statement和PrepareStatement区别?
Statement会出现sql注入安全问题。Preparestatement不会出现sql注入安全问题。
Preparestatement是Statement的子类。就是因为早期使用Statement发现该类出现问题,后期维护人员创建Statement的子类来解决这个问题。注意:维护人员不会再原类上做维护
2.2使用prepareStatement来解决sql注入的问题
//演示sql注入的安全问题
public static void main(String [] args) throws Exception{
Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
System.out.print("请输入账号:");
String username = scanner.nextLine();
System.out.print("请输入密码:");
String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束 next()输入空格后认为输入结束。
boolean b = sqlSafe02(username, password);
}
private static boolean sqlSafe02(String name,String password) throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection
("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "pAssW0rd");
//使用PrepareStatement 这里的? 是占位符。
String sql="select * from user where username=? and password=?";
PreparedStatement ps = conn.prepareStatement(sql);//预编译sql
//为占位符赋值。根据占位符的类型使用不同的方法来赋值
ps.setString(1,name); //1表示第一个占位符 name:表示第一个占位符的值
ps.setString(2,password);
//执行sql语句
ResultSet rs = ps.executeQuery();
while (rs.next()){
System.out.println("登录成功");
return true;
}
System.out.println("登录失败");
return false;
}
3.对数据库增删改查
3.1增
@Test
public void test1()throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection
("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
"root","pAssW0rd");
String sql="insert into student values(?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,2);
ps.setString(2,"小浩");
ps.setInt(3,23);
ps.setString(4,"河南");
ps.executeUpdate();
}
3.2删
@Test
public void test3()throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection
("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
"root","pAssW0rd");
String sql="delete from student where id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,12);
ps.executeUpdate();
}
3.3改
@Test
public void test2()throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection
("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
"root","pAssW0rd");
String sql="update student set name=? where id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"李四");
ps.setInt(2,8);
ps.executeUpdate();
}
3.4查
@Test
public void test4()throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn= DriverManager.getConnection
("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai",
"root","pAssW0rd");
String sql="select * from student";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next()){
int id= rs.getInt("id");
String name=rs.getString("name");
String address =rs.getString("address");
int age =rs.getInt("age");
System.out.println(id+"\t"+name+"\t"+address+"\t"+age);
}
}
4.抽取一个dao的公共的父类
4.1抽取父类
因为我们对每一张表都封装了一个操作类,那么再数据库中有很多表,那么我们就会有很多操作类,这些操作类都有一些公共的代码,为了减少代码的冗余,我们就抽取了一个父类
private String driverName = "com.mysql.cj.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
private String user = "root";
private String password = "pAssW0rd";
protected PreparedStatement ps = null;
protected Connection conn = null;
protected ResultSet rs = null;
public Connection getConn()throws Exception{
Class.forName(driverName);
conn = DriverManager.getConnection(url,user,password);
return conn;
}
public void closeAll(){
try {
if(rs!=null){
rs.close();
}
if(ps!=null){
ps.close();
}
if(conn!=null){
conn.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public void edit(String sql,Object ... params){
try {
getConn();
ps = conn.prepareStatement(sql);
for(int i= 0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
closeAll();
}
}
4.2为添加 删除 修改抽取公共的方法
public Dept findOne(int id){
Dept d = new Dept();
try {
getConn();
String sql="select * from tb_emp where id=?";
ps =conn.prepareStatement(sql);
ps.setObject(1,id);
rs = ps.executeQuery();
while(rs.next()){
d.setId(rs.getInt("id"));
d.setName(rs.getString("name"));
d.setAge(rs.getInt("age"));
d.setJob(rs.getString("job"));
d.setSalary(rs.getInt("salary"));
d.setEntrydate(rs.getString("entrydate"));
d.setManagerid(rs.getInt("managerid"));
d.setDept_id(rs.getInt("dept_id"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll();
}
return d;
}
public List<Dept> findAll(){
List<Dept> list = new ArrayList<Dept>();
try {
getConn();
String sql="select * from tb_emp";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()){
Dept d = new Dept();
d.setId(rs.getInt("id"));
d.setName(rs.getString("name"));
d.setAge(rs.getInt("age"));
d.setJob(rs.getString("job"));
d.setSalary(rs.getInt("salary"));
d.setEntrydate(rs.getString("entrydate"));
d.setManagerid(rs.getInt("managerid"));
d.setDept_id(rs.getInt("dept_id"));
list.add(d);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
closeAll();
}
return list;
}
public void insertDpet(Dept dept){
String sql="insert into tb_emp values(null,?,?,?,?,?,?,?)";
edit(sql,dept.getName(),dept.getAge(),dept.getJob(),dept.getSalary(),
dept.getEntrydate(),dept.getManagerid(),dept.getDept_id());
}
public void updateDept(Dept dept){
String sql ="update tb_emp set name =? where id=?";
edit(sql,dept.getName(),dept.getId());
}
public void deleteDept(int id){
String sql = "delete from tb_emp where id=?";
edit(sql,id);
}
4.3测试
public class Test1 {
DeptDao deptDao = new DeptDao();
@Test
public void testFindOne(){
Dept d = deptDao.findOne(1);
System.out.println(d.getId()+"\t"+d.getName()+"\t"+d.getAge()+"\t"+
d.getJob()+"\t"+d.getSalary()+"\t"+d.getEntrydate()+"\t"+
d.getManagerid()+"\t"+d.getDept_id());
}
@Test
public void testFindAll(){
List<Dept> all= deptDao.findAll();
for(Dept d:all){
System.out.println(d.getId()+"\t"+d.getName()+"\t"+d.getAge()+"\t"+
d.getJob()+"\t"+d.getSalary()+"\t"+d.getEntrydate()+"\t"+
d.getManagerid()+"\t"+d.getDept_id());
}
}
@Test
public void testInsert(){
Dept d = new Dept();
d.setName("小杨");
d.setAge(24);
d.setJob("经理");
d.setSalary(20000);
d.setEntrydate("2022-05-07");
d.setManagerid(1);
d.setDept_id(2);
deptDao.insertDpet(d);
}
@Test
public void testUpdate(){
Dept d= new Dept();
d.setName("小刘");
d.setId(16);
deptDao.updateDept(d);
}
@Test
public void testDelete(){
deptDao.deleteDept(16);
}
}