| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> JavaSE基础复习巩固 -> 正文阅读 |
|
[Java知识库]JavaSE基础复习巩固 |
第十一天:JDBC 连接池 1.JDBC(JAVA DATA BASE Connection):Java数据库连接 为什么会有JDBC的存在?是一种规范标准 1. 概念:Java DataBase Connectivity ?Java 数据库连接, Java语言操作数据库 JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。 以前在DOS窗口可视化工具操作数据库,现在想用JAVA程序去操作数据库。 2.使用JDBC操作数据库步骤: 1.导入依赖Jar包 2.注册驱动 Class.forName("com.mysql.jdbc.Driver") 3.获取数据库连接对象 DriverManager.getConnection() 4.通过数据连接对象获取执行sql语句的对象--获取sql语句执行平台 connection.createStatemen() 5.定义sql语句 String sql=" sql语句"; 6.执行sql语句 statement.execute(sql); 7.释放连接资源 con.close(); statement.close() 例子: //使用JDBC操作数据库步骤 /* * 1.导入JDBC的相关Jar包(添加依赖关系) * 2.加载驱动(注册驱动)因为操作数据库的具体实现类是Driver类,目的是把Driver类加载进内存,加载字节码文件加载进内存 * 3.建立连接(获取操作数据库的连接对象)----DriverManager 通过DriverManager.getConnection() * 4.通过数据库连接对象获取能够操作数据库的对象(获取能够执行sql语句的对象)--获取执行sql语句平台 * 5.定义sql语句 * 6。执行sql语句 * 7.释放资源 * */ // 1.导入JDBC的相关Jar包(添加依赖关系) // 2.(注册驱动) Class.forName("com.mysql.jdbc.Driver"); // 3.建立连接(获取操作数据库的连接对象)----DriverManager 通过DriverManager.getConnection() Connection con = DriverManager.getConnection("Jdbc:mysql://localhost:3306/db5", "root", "root"); //4.通过数据库连接对象获取能够操作数据库的对象(获取能够执行sql语句的对象)--获取执行sql语句平台 Statement statement = con.createStatement(); // 5.定义sql语句 // 添加一条数据 String sql="INSERT INTO `emp1`(`id`,`NAME`) VALUES(NULL,'王五');";//双引号里面不能放双引号,可以放单引号 // 6.执行sql语句 statement.execute(sql); 优化之后: 代码: ArrayList<Stu> stu = getStu(); for (Stu stu1 : stu) { System.out.println(stu1); } } private static ArrayList<Stu> getStu() { //把stu对象放到ArrayList集合中去 ArrayList<Stu> stus = new ArrayList<>(); Connection con=null; Statement stat=null; ResultSet resultSet=null; try { // 1.获取数据连接 con = JDBCUtilDemo1.getConnection(); // 2.获取执行sql语句的平台(对象) stat = con.createStatement(); //3定义sql语句 String sql="SELECT * FROM stu1;"; //4.执行sql语句 返回的是结果集 查询数据中的数据返回成一个结果集 resultSet = stat.executeQuery(sql); //判断是否有下一个数据 // boolean next = resultSet.next(); 当next为true时证明有下一条数据 //得到下一个数据 while(resultSet.next()) { int id = resultSet.getInt("id");//得到id字段 String name = resultSet.getString("name"); System.out.println(id+" "+name); //创建对象 Stu stu = new Stu(); stu.setId(id); stu.setName(name); //把对象添加到集合中去 stus.add(stu); } } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtilDemo1.close(con,stat,resultSet); } return stus; } JDBC的工具类: 代码: public class JDBCUtilDemo1 { //提供一个获取连接对象的方法 public static Connection getConnection() throws Exception { Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root"); return con; } //关闭资源---有结果集(查询) public static void close(Connection con, Statement stat, ResultSet res) { //释放资源 if(con!=null){ try { con.close(); } catch (Exception e) { e.printStackTrace(); } } if(stat!=null) { try { stat.close(); } catch (Exception e) { e.printStackTrace(); } } if(res!=null){ try { res.close(); } catch (Exception e) { e.printStackTrace(); } } } //关闭资源---没有结果集(增删改) public static void close(Connection con, Statement stat) { //释放资源 if (con != null) { try { con.close(); con=null; } catch (Exception e) { e.printStackTrace(); } } if (stat != null) { try { stat.close(); stat=null; } catch (Exception e) { e.printStackTrace(); } } } } 结合实体类使用JDBC: 代码: public static void main(String[] args) { ArrayList<Student> student = getStudent(); //遍历集合 for (Student student1 : student) { System.out.println(student); } } private static ArrayList<Student> getStudent() { ArrayList<Student> students = new ArrayList<>(); try { Connection con = JDBCUtilDemo1.getConnection(); Statement stat = con.createStatement(); String sql="SELECT * FROM student WHERE NAME LIKE'%三%';"; ResultSet resultSet = stat.executeQuery(sql); while (resultSet.next()){ //得到数据表中的每一个字段 int id = resultSet.getInt("id"); String name = resultSet.getString("name"); int age = resultSet.getInt("age"); int math = resultSet.getInt("math"); int english = resultSet.getInt("english"); Student student = new Student(); student.setId(id); student.setName(name); student.setAge(age); student.setMath(math); student.setEnglish(english); //把对象添加到集合中去 students.add(student); } } catch (Exception e) { e.printStackTrace(); } return students; } 细节: static:静态的 被这个关键字修饰的会随着类的加载而加载 sql注入产生原因: 因为sql语句中存在字符串的拼接,只要给予特定的sql语句,会导致用户名与密码失效,这样的问题我们称之为sql注入 如何解决这个问题? 不使用字符串拼接,而是使用占位符 ? 进行赋值 占位符----占用位置 PreparedStatement:执行sql的对象 1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题 1. 输入用户随便,输入密码:a' or 'a' = 'a 2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 2. 解决sql注入问题:使用PreparedStatement对象来解决 3. 预编译的SQL:参数使用?作为占位符 4. 步骤: 1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar 2. 注册驱动 3. 获取数据库连接对象 Connection 4. 定义sql 代码如下: public static void main(String[] args) { /*提供一个用户表 user * 登录案列 * 键盘录入用户名与密码与数据中已存在的用户名与密码进行校验 * 如果输入的用户名与密码存在,提示“登录成功” * 否则 提示 “登录失败” * * */ Scanner sc = new Scanner(System.in); System.out.println("请输入 用户名:"); String username=sc.nextLine(); System.out.println("请输入密码:"); String password=sc.nextLine(); boolean flag = login(username, password); if(flag) System.out.println("登录成功"); else System.out.println("登录失败"); } /** * 登录验证的方法 * @return */ public static boolean login(String username,String password){ try { //获取数据库连接对象 Connection con = JDBCUtil.getConnection(); //获取执行sql语句对象 // Statement stat = con.createStatement(); //定义sql语句 // String sql="select * from user where username='"+username+"' and password='"+password+"'"; /*sql注入产生原因: * 因为sql语句中存在字符串的拼接,只要给予特定的sql语句,会导致用户名与密码失效,这样的问题我们称之为sql注入 * 如何解决这个问题? * 不使用字符串拼接,而是使用占位符 ? 进行赋值 * 占位符----占用位置 * */ // String sql="select * from user where username='"+username+"' and password='88' or '1'='1'"; String sql="select * from user where username=? and password=? "; System.out.println(2); //获取预编译对象 ---预编译sql语句,并对占位符进行赋值 // 预编译---把sql语句执行一次,让sql不能再随意更改(防止字符串拼接) PreparedStatement pst =con.prepareStatement(sql); System.out.println(1); //给占位符赋值 pst.setString(1,username); pst.setString(2,password); System.out.println(3); //再次真正执行sql ResultSet resultSet = pst.executeQuery(); //执行sql语句 // ResultSet resultSet = stat.executeQuery(sql); //进行判断 如果存在下一个元素,证明我们输入的用户名与密码与数据库中用户名和密码匹配 // resultSet.next()的返回值是boolean,如果 resultSet.next()结果为true, // 代表存在下一个元素,意味着我们输入的用户名与密码与数据库中用户名和密码匹配 if(resultSet.next()){ return true; } } catch (Exception e) { e.printStackTrace(); } return false; } JDBC控制事务: 1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。 2. 操作: 1. 开启事务 2. 提交事务 3. 回滚事务 3. 使用Connection对象来管理事务 * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务 * 在执行sql之前开启事务 * 提交事务:commit() * 当所有sql都执行完提交事务 * 回滚事务:rollback() * 在catch中回滚事务 2.连接池:是一个容器,用来存放数据库连接的容器 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,访问数据库,用户访问玩之后,会将连接对象归还给容器。 为什么要学连接池? 连接池的好处(作用)是? 1. 节约资源 2. 用户访问高效(提高用户访问效率) 常见的连接池有:c3p0 Druid dbcp 实现: 1. 标准接口:DataSource ??javax.sql包下的 1. 方法: * 获取连接:getConnection() * 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接 2. 一般我们不去实现它,有数据库厂商来实现 1. C3P0:数据库连接池技术 2. Druid:数据库连接池实现技术,由阿里巴巴提供的 c3p0的使用: 1.导入依赖Jar包 2.导入配置文件(建议放在src下面) 3.创建连接对象(DateSource) C3P0:数据库连接池技术 * 步骤: 1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar , * 不要忘记导入数据库驱动jar包 2. 定义配置文件: * 名称: c3p0.properties 或者 c3p0-config.xml * 路径:直接将文件放在src目录下即可。 3. 创建核心对象 数据库连接池对象 ComboPooledDataSource 4. 获取连接: getConnection * 代码: ?//1.创建数据库连接池对象 ????????DataSource ds ?= new ComboPooledDataSource(); ????????//2. 获取连接对象 ????????Connection conn = ds.getConnection(); 例子: /*使用c3p0连接池操作数据库的步骤: * 1.要导入连接池jar包 * 注意:使用连接池技术操作数据库也需要jdbc的jar * 2.导入配置文件 * 配置文件要放在src下面(会自动加载配置文件中的内容) * * 3.创建连接池对象 * DateSource(接口)----ComboPooledDataSource * * 4.获取连接对象 * * */ //默认使用配置文件中的 <default-config> DataSource ds=new ComboPooledDataSource(); //获取连接对象 Connection con = ds.getConnection(); //操作数据库 //定义sql语句 String sql="select * from account where id=? or id=?"; PreparedStatement pst = con.prepareStatement(sql); pst.setInt(1,1); pst.setInt(2,2); ResultSet res = pst.executeQuery(); //遍历结果集 while(res.next()){ int id = res.getInt("id"); String name = res.getString("name"); double balance = res.getDouble("balance"); System.out.println(id+"\t"+name+"\t"+balance); } ?Druid:数据库连接池实现技术,由阿里巴巴提供的 1. 步骤: 1. 导入jar包 2. 定义配置文件: * 是properties形式的 * 可以叫任意名称,可以放在任意目录下 3. 加载配置文件。Properties 4. 获取数据库连接池对象:通过工厂来来获取 ?DruidDataSourceFactory 5. 获取连接:getConnection 例子: /*使用Druid连接池操作数据库步骤 1.导入jar包 2.导入配置文件(可以放在项目的任意位置,但是建议放在src下面) 3.创建连接池对象 使用DataSource的工厂类 DruidDataSourceFactory 调用createDataSource创建连接池对象 4.获取连接对象 * * * */ //创建流对象 /* InputStream is=new FileInputStream ("druid.properties");*/ InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties"); //创建Properties对象 Properties pt=new Properties(); //加载配置文件 pt.load(is); // 3.创建连接池对象 DataSource ds = DruidDataSourceFactory.createDataSource(pt); // 4.获取连接对象 Connection con = ds.getConnection(); System.out.println(con); //执行sql语句 } Spring JDBC * Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发 * 步骤: 1. 导入jar包 2. 创建JdbcTemplate对象。依赖于数据源DataSource * JdbcTemplate template = new JdbcTemplate(ds); 3. 调用JdbcTemplate的方法来完成CRUD的操作 * update():执行DML语句。增、删、改语句 * queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合 * 注意:这个方法查询的结果集长度只能是1 * queryForList():查询结果将结果集封装为list集合 * 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中 * query():查询结果,将结果封装为JavaBean对象 * query的参数:RowMapper * 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装 * new BeanPropertyRowMapper<类型>(类型.class) * queryForObject:查询结果,将结果封装为对象 * 一般用于聚合函数的查询 代码: public static void main(String[] args) { /*JDBCTemplate: * Spring对jdbc的一个封装,Spring为操作JDBC提供的一个小的框架 * 目的:简化执行sql语句的代码书写。 * 框架是什么?相当于一个半成品软件。 * Spring1框架----用来做数据库的添加操作---小的软件 * 对数据库做 具体的添加操作时,基于 前面已经封装好的一个小的软件进行二次开发。 * 使用JDBCTemplate的步骤: * 1.导入jar包。 * 2.创建JDBCTemplate对象 ,依赖于连接池 * JDBCTemplate提供了很多方法,用来简化执行sql语句的书写 * update()----执行增删改语句 * Query()---将查询的结果封装成实体类(JAVABean)对象 * QueryForMap()---将查询的结果封装成map集合(只能查询一条数据) * QueryForList()---将查询的结果封装成list集合(查询一条数据或多条数据) * QueryForObject()----一般用于聚合函数的查询 * */ //先要获取连接池对象 DataSource ds = DruidUtil.getDs(); // 2.创建JDBCTemplate对象 ,依赖于连接池 JdbcTemplate jdbcTemplate = new JdbcTemplate(ds); String sql="insert into account values(?,?,?)"; // 操作sql语句 jdbcTemplate.update(sql,3,"老王",9000); //使用JDBCTemplate 往account 表中添加一条数据 } 今日学习感受:学习java的路上虽然很长,但是累并快乐着,学习的东西虽然很多,但是大部分只要自己认真去学,还是可以学好的,希望自己继续坚持下去。最后一句话:生于忧患,死于安乐. |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 5:17:33- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |