ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JDBC-扩展

2020-09-05 22:31:38  阅读:164  来源: 互联网

标签:语句 ps JDBC sql 扩展 loginSuccess SQL 线程


一:用户登录实现:

  1.需求:模拟用户登录功能的实现

  2.业务描述:程序运行的时候,提供一个输入接口,可以让用户输入用户名和密码,并提交信息,JAVA连接数据库核实信息,合法,登录成功,不合法,登陆失败。

  3.数据准备:需要一个建模工具:PowerDesigner

 

  4.懒得写那么多,直接上代码:

package cc.bb.aa;
​
​
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
​
​
​
​
public class Ui_user {
    public static void main(String[] args) {
        //1.初始化界面:
        Map<String,String> userLogininfo=initUI();//需要返回一个给用户输入的对象,用来验证用户名和密码
        //2.验证用户名和密码
        boolean loginSuccess =Login(userLogininfo);
        //3.输出结果:
        System.out.println(loginSuccess?"登录成功":"登录失败");
    }
​
    
    /**
     * 用户登录
     * @param userLogininfo用户信息
     * @return false表示失败,true表示成功
     * */
    private static boolean Login(Map<String, String> userLogininfo) {
        //JDBC代码
        //打一个boolean的一个标记
        boolean loginSuccess=false;
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs=null;
        
        try {
            conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","");
            //statement专门执行SQL语句的
            stmt=conn.createStatement();//create statement对象
            //专门执行DML语句
            //注意:这里补充一个知识点:双引号里面添加两个加号意思是变量所代表的值的字符串:格式为:"+loginInfo.get("loginName")+";
            //返回值是“影响数据库中的记录条数”
            String sql="select * from user where name='"+userLogininfo.get("loginName")+"' and password='"+userLogininfo.get("loginPwd")+"'";
            rs=stmt.executeQuery(sql);
            //处理结果集:
            if(rs.next()) {
                //登录成功
                loginSuccess=true;
            }else {
                //登陆失败
                loginSuccess =false;
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {//这里关闭数据,释放资源
            try{
                if(stmt!=null){
                    stmt.close();
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
            try{
                if(conn!=null){
                    conn.close();
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
        return loginSuccess;
    }
    
    
    /**
     * 初始化界面
     * @return 用户输入的用户名和密码等登录信息
     * */
​
    private static Map<String, String> initUI() {
        // TODO Auto-generated method stub
        Scanner scanner=new Scanner(System.in);
        
        System.out.println("用户名:");
        String loginName=scanner.nextLine();
        
        System.out.println("密码:");
        String loginPwd=scanner.nextLine();
        
        Map<String,String> userLoginInfoMap=new HashMap<>();
        userLoginInfoMap.put("loginName", loginName);
        userLoginInfoMap.put("loginPwd", loginPwd);
        
    return userLoginInfoMap;
    }
}
​
fdsa

fdsa' or '1'='1

 

 

 

二:SQL注入:

1.导致注入的根本原因:

用户输入的信息中含有sql语句的关键字,并且这些关键字参与sql语句的编译过程,导致sql语句的原意被扭曲,进而达到sql注入

 

2.解决SQL注入:

/**
*只要用户提供的信息中不参与SQL语句的编译过程,问题就解决了
*及时用户提供的信息中含有SQL语句的关键字,但是没有参加编译,不起作用
*想要用户信息不参与SQL语句的编译,那么必须使用java.sql.PreparedStatement
*PreparedStatement接口继承了java.sql.Statement
*PreparedStatement是属于预编译的数据库操作对象
*PreparedStatement的原理是:与预先对SQL语句的框架进行编译,然后再给SQL语句传“值”
*
*解决SQL注入的关键是什么?
*   用户提供的信息中含有sql语句的关键字,,但是这些关键字并没有参与编译,不起作用
*/

注意:跟之前的使用statement相比较,还是有很大的区别的

//提前打标记:
    boolean loginSuccess=false;
//单独定义变量
    String loginName=userLogininfo.get("loginName");
    String loginPwd=userLogininfo.get("loginPwd");
​
//提前定义:
    Connection conn=null;
    PreparedStatement ps=null;
    ResultSet rs=null;
​
//1.注册驱动
    Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
    conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","");
//3.获取与预编译的数据库操作对象
//SQL语句的框架,其中一个?,表示以一个占位符,一个?将来接受一个“值”,注意:占位符不能使用单引号括起来
    String sql="select * from user where name=? and password=?";
//程序执行到此,会发送一个sql语句框子给DBMS,然后DBMS进行sql语句的预先编译
    ps=conn.prepareStatement(sql);
//给占位符?传值(第一个问好下标是1,第二个问好下标是2,JBDBC中所有的下标都是从1开始)
    ps.setString(1,loginName);
    ps.setString(2,loginPwd);
//4.执行sql
    rs=ps.executeQuery();
//5.处理结果集
    if(rs.next()){
    //登录成功
        loginSuccess=true;
}else{
    //登录失败
    loginSuccess=false;
}
    return loginSuccess;

 

注意:这里没有使用try,catch块,而且资源也没有finally释放,记得之后看代码的时候,对应前面的代码来看

 

 

 

三:使用preparedStatement进行增删查改:

//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取连接
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","");
//3.获取预编译的操作对象
String sql="insert into dept(deptno,dname,loc) values(?,?,?)";//这里写增删查改语句就好了,不会下去自己看看把
ps=conn.prepareStatement(sql);
ps.setInt(1,60);
ps.setString(2,"销售部");
ps.setString(3,"上海");
​
//4.执行SQL
int count=ps.executeUpdate();
System.out.println(count);

 

 

 

四:JDBC事务提交:

1.JDBC的事务时自动提交:只要执行任意一条DML语句,则自动提交一次,但是实际业务当中,通常都是N条DML语句共同联合才能完成

 

五:乐观锁和悲观锁:

乐观锁:事务不需要排队,支持并发

悲观锁:书屋排队执行,数据锁住了,不允许并发

一、悲观锁

顾名思义,悲观锁就是考虑事情发生的最坏情况。默认认为一定会有其它线程抢着修改当前线程正在使用的数据。分为,读锁和写锁。

  • 读锁,又称共享锁,可以被其它线程所共享,所有线程都可以添加该锁。当没有其它线程添加读锁时,本线程可以修改数据,否则将无法修改数据。

  • 写锁,也成排它锁,不能被共享。只要有线程添加该锁时,直到事务提交之前,其它线程都无法添加该锁。

如何实现(数据库提供实现方法):

\1. 读锁

select * from table lock in share mode

\2. 写锁

select * from table for update

二、乐观锁

乐观锁,认为没有其它线程和本线程同时修改数据。一般使用版本号来控制(类似于SVN版本控制器),在提交事务前,比较自身持有的版本号和数据库中存在的版本号,只有自身持有的版本号大于数据库中的版本号时才能修改数据,否则无法修改数据。

例如:

在hibernate中,提供了乐观锁的解决方案

首先,在实体类中,添加一个字段代表版本号,并添加get/set方法。

img

然后在实体的配置文件中添加version属性

img

结果:在测试代码中加入断点,当程序运行完该断点后,立即修改数据库t_customer表中version属性,使其加1,放行代码,结果将出现SatleObjectStateException异常。

img

img

 

标签:语句,ps,JDBC,sql,扩展,loginSuccess,SQL,线程
来源: https://www.cnblogs.com/instead-everyone/p/13620079.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有