【mysql】jdbc工具类封装

一、回顾


1.jdbc基本使用步骤!(代码表示)
	1.定义静态数据库链接信息
	2.加载驱动(mysql)
	3.创建链接对象
	4.创建执行sql的对象
		书写sql
		执行
	5.处理结果(结果集)
		int
		reslutset
	6.释放资源


2.写出jdbc设计的核心类和接口、并简单描述作用!
	1.driver
	2.connection
	3.statement
	4.resulteset
3.实现一个控制台登陆方式:
	- 创建一张用户表 User
	- id ,主键、自动增长。
	- 用户名,字符串类型,唯一、非空
	- 密码,字符串类型,非空
	- 手机号码,字符串类型
	- 插入 2 条测试语句

	CREATE TABLE `users` (
  `userId` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(11) NOT NULL,
  `address` varchar(255) DEFAULT NULL,
  `phone` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
	
	实现过程:
	- 通过控制台用户输入用户名和密码。   
		--实质:通过控制台接收两个变量  username   password
	- 用户输入的用户名和密码作为条件,编写查询 SQL 语句。 
    	登陆的实质就是查询  
		sql:select * from users where username=XXX and password=XXX;
	- 如果该用户存在,提示登录成功,反之提示失败。
		判断验证
	



1.1用户登陆的实现方式一

//        实例化控制台输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入用户名");
//        注意:控制台接收的所有数据全部是字符串类型
        String username = scanner.nextLine();
        System.out.println("输入密码");
        String password = scanner.nextLine();

//       开始链接数据库
//        1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
//        2.创建链接对象
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","root");
//        3.创建执行sql的对象
        Statement statement = connection.createStatement();
        String sql = "select * from users where username='"+username+"' and password='"+password+"';";
        ResultSet resultSet = statement.executeQuery(sql);
//        4.处理结果集
        if (resultSet.next()){
            System.out.println("登陆成功");
        }else{
            System.out.println("登陆失败");
        }

//        5.释放资源
        resultSet.close();
        statement.close();
        connection.close();

' or 1='1

1.2什么是sql注入

用户输入的数据中存在sql的关键字或者语法并且参与了sql语句的编译,导致sql语句编译之后条件的含义一直为true,不能得到正确的结果,这就是sql注入。

1.3如何避免sql注入

预编译

由于编写的sql语句是再用户输入数据,整合之后再进行的编译,所以为了避免sql的注入,我们需要将sql语句再用户整合执行之前进行sql编译,然后再填充数据。

1.4prepareStatement【重点】

prepareStatement接口继承了Statement,执行sql方式没有任何编译区别。

1.5prepareStatement的应用

作用:

​ 1.可与预编译sql,效率高

​ 2.安全,避免sql注入

​ 3.可以动态的填充数据。执行多个同构的sql语句

二、prepareStatement的预编译应用

2.1解决登陆注入问题

 String sql = "select * from users where username=? and password=?;";
//        预编译
        PreparedStatement pstm = connection.prepareStatement(sql);
//        参数1和参数2的类型
//        statement.setInt();
//        statmen.setString();
//        类似与添加变量
        pstm.setObject(1,username);
        pstm.setObject(2,password);
//        编译执行之后接收结果
        ResultSet resultSet = pstm.executeQuery();
//        statement.setString(1,username);

//        object和String为什么都不报错
//        string 根据我们设定的变量去分析使用哪些类型


占位符?的处理和赋值
 /*
        * 预编译sql:使用?代替参数值  一个问号代表一个
        * ?  占位
        * 解决问号:
        * 设置参数
        * 参数1 --->用户名
        * 参数2 ---->密码
        *
        * 根据参数为设置数字,从1开始
        * 参数的实际值
        */

总结:解决sql注入,我们可以选择预编译方式,仔细查看代码的执行顺序,我们会发现再结果出现之前我们已经执行了sql的编译,通过占位符?去处理编译的数据,可选择的类型建议使用object,最后对产生的结果集进行判断,实现登陆和登陆失败,并解决注入问题。

2.2完整实现登陆的注入解决代码

//        实例化控制台输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入用户名");
//        注意:控制台接收的所有数据全部是字符串类型
        String username = scanner.nextLine();
        System.out.println("输入密码");
        String password = scanner.nextLine();

//       开始链接数据库
//        1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
//        2.创建链接对象
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/companydb","root","root");
//        3.创建执行sql的对象
        String sql = "select * from users where username=? and password=?;";
//        预编译
        PreparedStatement pstm = connection.prepareStatement(sql);
//        参数1和参数2的类型
//        statement.setInt();
//        statmen.setString();
//        类似与添加变量
        pstm.setObject(1,username);
        pstm.setObject(2,password);
//        编译执行之后接收结果
        ResultSet resultSet = pstm.executeQuery();
//        statement.setString(1,username);

//        object和String为什么都不报错
//        string 根据我们设定的变量去分析使用哪些类型
        /*
        * 预编译sql:使用?代替参数值  一个问号代表一个
        * ?  占位
        * 解决问号:
        * 设置参数
        * 参数1 --->用户名
        * 参数2 ---->密码
        *
        * 根据参数为设置数字,从1开始
        * 参数的实际值
        *
        /
         */
//        4.处理结果集
        if (resultSet.next()){
            System.out.println("登陆成功");
        }else{
            System.out.println("登陆失败");
        }

//        5.释放资源
        resultSet.close();
        pstm.close();
        connection.close();

2.3使用preparement实现DDL和DML操作

@Test
    public void test1(){
//        初始化对象的
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(URL,USER,PASSWORD);
//            创建执行sql的对象
            String sql = "insert into stu(id,name,sex) values(?,?,?);";
            preparedStatement= connection.prepareStatement(sql);
//            处理?
            preparedStatement.setObject(1,5);
            preparedStatement.setObject(2,"打老虎");
            preparedStatement.setObject(3,"没打着");

            int count = preparedStatement.executeUpdate();

            System.out.println("你的打老虎影响了"+count+"行");

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            // 6.释放资源  判断当前链接是否还继续存在
            if (preparedStatement!=null){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
//          释放连接
            if (connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

三、JDBC的封装

刚开始接触的,全部是用原生

3.1类型的介绍(重点)

类类型

封装的工具类的类型

实体类(实体的对象是数据库中的表):承接数据,数据库中数据的一种体现,踏踏实实的按照数据库的格式和类型声明这个类

属性:对应数据表中列名

行为:get/set

持久化类

增、删、改、查

格式:XXX实体类

工具类:工具类可以帮助逻辑类形成一些简化的操作

XXX工具类

3.2工具类的编程思想

工具类本身没有任何的逻辑可言,就是为了简化其他的逻辑类,提供一些方法

学会自己封装工具类

3.3重用性(可以重复使用)

1.创建一个类(工具类)

2.进行JDBC部分重复使用的方法和代码

3.封装注册的驱动

4.封转简化的创建链接方式

5.封转释放资源的方法(可以进行方法重载)

6.封装简化的sql的语句

JDBC的封装工具类

public class DBunti {

    private static String URL = "jdbc:mysql://127.0.0.1:3306/companydb";   //数据库链接的url
    private static String USER = "root";   //数据库的用户名
    private static String PASSWORD = "root";   //数据库的密码

//    加载驱动
    static {   //类加载 只加载一次
    try {
        Class.forName("com.mysql.jdbc.Driver");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

//1.获取连接
    public static Connection getConnection(){
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(URL,USER,PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

//    2.释放资源
    public static void closeAll(Connection connection, Statement statement, ResultSet resultSet){

        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

3.4工具类的使用

//    删除
    @Test
    public void test1() throws SQLException {
//        注册驱动
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        int id =6;
        connection = DBunti.getConnection();
//        表名  字段名  must不能使用关键字
        String sql = "delete from stu where id=?;";
        preparedStatement = connection.prepareStatement(sql);
//        参数处理
        preparedStatement.setObject(1,id);
        int count = preparedStatement.executeUpdate();
        System.out.println("你的操作影响了"+count+"行");
        DBunti.close(connection);

    }

    @Test
    public void test2() throws SQLException {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        String name1 = "王%";
//        注册驱动
        connection = DBunti.getConnection();
//        表名  字段名  must不能使用关键字
        String sql = "select * from stu where name like ?";
        preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setObject(1,name1);
        ResultSet resultSet = preparedStatement.executeQuery();
//        迭代
        while (resultSet.next()){
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String sex = resultSet.getString("sex");
            System.out.println(id+"\t"+name+"\t"+sex+"\t");
        }
        DBunti.close(connection);
    }

总结:面试题:statement和preparement的区别

一、语法结构
	1.只可以执行静态的sql,并且sql可以进行拼接(“++”)
	2.preparement可以限制性预编译的sql,在执行sql语句中使用?进行占位,再进行占位符的处理(再赋值)
二、原理
	1.preparement执行效率比statement快
	2.statement不能进行sql缓存
三、安全性的不同
	1.statement不能有效的防止sql注入
	2.preparement可以防止sql注入
四、实际应用中,哪些地方使用preparement。。。


3.5跨平台性

XXX.properties
PropertiesJava.util.Properties),该类主要用于读取Java的配置文件,不同的编程语言有自己所支持的配置文件,配置文件中很多变量是经常改变的,为了方便用户的配置,能让用户够脱离程序本身去修改相关的变量设置。就像在Java中,其配置文件常为.properties文件,是以键值对的形式进行参数配置的。

Properties这个类里面  
public static final Properties pro = new Properties()  //配置文件的集合(map)


IDEA创建properties文件如何创建?
	创建模板
	file--->settings---->Editor---->file and code templates --->点击加号--->设置文件名字以及文件后缀名(Properties)---->点击enable live templates---->ok
	
	
	将模板进行保留,一边后续使用。
	
	


跨平台完整封装

public class DButils {

//    实例化
    private static final Properties PROPERTIES = new Properties();

    static {
//       通过流的作用将这个文件进行使用
        InputStream is = DButils.class.getResourceAsStream("/db.properties");

        try {
            PROPERTIES.load(is);
            Class.forName(PROPERTIES.getProperty("driver"));
//            如果报一下异常 说明我们文件输入出现问题
        } catch (IOException e) {
            e.printStackTrace();
//            说明文件中的属性出现异常
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    public static Connection getConnection(){

        Connection connection = null;
        try {
            connection = DriverManager.getConnection(PROPERTIES.getProperty("url"),PROPERTIES.getProperty("user"),PROPERTIES.getProperty("password"));
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return connection;
    }

//    2.释放资源
    public static void close(Connection connection){
        if (connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值