1、JDBC概述
一、什么是JDBC、为何要学习JDBC?java
JDBC(Java DataBase Connectivity)Java数据库链接 其实就是利用Java语言/Java程序链接并访问数据库的一门技术 虽然以前咱们能够经过 cmd或者navicat 链接数据库,也能够对数据库、表、表记录等进行操做。 可是,未来在开发中更多的是经过程序来链接数据库,若是是Java语言,经过Java程序链接数据库,就必需要学习JDBC这门技术。
二、如何经过Java程序链接mysql数据库?(快速入门)
建立一个测试类: com.tedu.JdbcTest01mysql
//1.注册数据库驱动 //2.获取数据库链接 //3.获取传输器 //4.发送SQL语句到服务器执行,并返回结果 //5.处理执行的结果 //6.释放资源
三、JDBC API总结正则表达式
1)Class.forName("com.mysql.cj.jdbc.Driver"); 将mysql驱动包中的"com.mysql.cj.jdbc.Driver"类加载到内存中,Driver类中的静态代码块就会执行,而在Driver类的静态代码块中有一行代码是用于注册驱动的,所以这行代码能够注册驱动! 注册驱动: 将mysql驱动交给JDBC程序管理,以便于使用其中的功能 在JDBC4.0之后的版本中,这一步能够省略,但仍是建议加上 2)DriverManager.getConnection(url,user,password) url:指定要链接的是哪个位置的哪个库 jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai 若是链接的数据库端口是3306,端口能够省略不写: jdbc:mysql://localhost/jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai 若是是链接本机上的数据库,主机名/IP地址能够省略不写: jdbc:mysql:///jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai getConnection方法返回一个Connection对象,用于表示Java程序和数据库服务器之间的链接。 3)Statement stat = conn.createStatement() conn.createStatement() -- 用于获取向数据库发送SQL语句的传输器对象 stat.executeQuery(sql) -- 用于执行查询类型的SQL语句,返回的是一个ResultSet对象 stat.executeUpdate(sql) -- 用于执行新增、删除、修改类型的SQL语句,返回一个int值,表示影响的记录行数 4)rs.next() -- 用于将指向数据行的箭头往下挪动一行,而且返回布尔值(true或false), true表示箭头往下挪动一行后,指向的行有数据;false表示箭头往下挪动一行后,指向的行没有数据; 5)在ResultSet结果集对象上提供了获取数据的方法,常见的有: rs.getInt( colName ); rs.getInt( colCount ); rs.getString( colName ); rs.getString( colCount ); rs.getDobule( colName ); rs.getDobule( colCount ); ... rs.getObject( colName ); rs.getObject( colCount );
2、JDBC的增删改查sql
一、新增:往account表中添加一条记录:名称为'lucy',金额是3500 二、修改:修改account表中名称为'lucy'的金额,将金额改成2000 三、删除:删除account表中名称为'lucy'的记录
3、junit单元测试框架数据库
junit(单元测试框架): 能够不用添加main函数,也不用建立类的实例就能够执行一个方法 可以用单元测试执行的方法必须知足以下条件: 1)方法必须是公共的(public) 2)方法必须是非静态的 3)方法必须是无返回值的(void) 4)方法必须是无参数的 若是执行的方法不知足以上任何一个条件,就会报以下错误: java.lang.Exception: No tests found matching... junit(单元测试框架)经常使用的三个注解: @Test、@Before、@After @Test:使用了该注解的方法,每次选中方法名,右键-->Run as-->junit test均可以执行该方法 @Before:使用了该注解的方法,每次会在@Test标记的方法以前执行。也就是说,每次在执行@Test标记的方法以前都会执行@Before标记的方法 @After:使用了该注解的方法,每次会在@Test标记的方法以后执行。也就是说,每次在执行@Test标记的方法以后都会执行@After标记的方法
4、PreparedStatement对象安全
Statement 传输器 PreparedStatement 传输器对象
一、模拟用户登陆案例服务器
PreparedStatement对象是Statement传输器对象的子对象 PreparedStatement对象比Statement对象更加安全,在某些方面执行的效率上也会更高一些! 下面以一个模拟登陆的案例来说解PreparedStatement对象 ---------------------------------------------------------- 请登陆: 请输入用户名: tom'#' 请输入密码: select * from user where username='tom'#'' and password='' 恭喜您登陆成功! ---------------------------------------------------------- 请登陆: 请输入用户名: 张飞' or '1=1 请输入密码: select * from user where username='张飞' or '1=1' and password='' select * from user where username='tom' or '1=1' and password='' 恭喜您登陆成功! ----------------------------------------------------------
二、SQL注入攻击框架
SQL注入攻击产生的缘由:因为SQL语句中的参数是拼接而来的,其中的参数值(username和password的值)是用户提交过来的,若是用户在提交参数时,在参数中掺杂一些SQL关键字或特殊字符(or、#、-- 、/* */等)就可能会致使SQL语句的语义被篡改,从而执行一些意外的操做(好比用户名或密码错误也能够登陆系统或网站) delete from user where id=1 or 1=1;
三、如何解决SQL注入攻击问题函数
1)能够对用户提交过来的参数进行校验(例如经过正则表达式对用户名和密码进行校验),若是用户名或密码中有相似于 or、#、-- 等符号,就再也不登陆,直接提示用户输入不合法,请从新登陆! 2)或者使用JDBC中提供的PreparedStatement对象,能够解决SQL注入攻击问题! PreparedStatement对象是如何解决SQL注入攻击的? 1)PreparedStatement对象是先将SQL语句的骨架(不包含参数)发送给服务器编译并肯定下来。 String sql = "select * from user where username=? and password=?"; PreparedStatement stat = conn.prepareStatement(sql); 2)再将SQL语句中的参数值传递给服务器 //设置SQL语句中的参数值 stat.setString( 1, user ); stat.setString( 2, psw ); //执行SQL语句,返回执行结果 ResultSet rs = stat.executeQuery(); 因为前面SQL语句的骨架已经被肯定了,所以SQL参数中即便再包含SQL关键字或者特殊符号,也不会影响SQL语句的骨架或语义,只会被当前普通的文原本处理,所以能够防止SQL注入!
5、数据库链接池
一、什么是链接池?单元测试
池:常量池、线程池、链接池等中的池都是一个容器。是指内存中的一片空间 链接池:就是将一批链接资源存入到一个容器中。目的是为了实现链接的复用,减小链接建立和关闭的次数,以此来提升程序执行的效率!
二、为何要使用链接池?
传统方式中,每次须要链接都是直接建立一个链接(对象/资源),再基于这个建立的链接去访问数据库,最后用完链接还要关闭! 而每次【建立链接】和【关闭链接】相比使用链接是要消耗大量的时间和资源,致使程序的执行效率很是低下! 为了提升程序执行的效率,咱们能够在程序一启动时,就建立一批链接放在一个链接池中,供整个程序共享。 当用户须要链接时,不用再去建立链接,而是直接从链接池中获取一个链接进行使用,在用完链接后,也不须要关闭,而是直接将链接还回到链接池中。这样一来,用来用去都是链接池中的这一批链接,必然能够实现链接的复用,减小链接建立和关闭的次数。提升程序执行的效率!
三、如何使用c3p0链接池?
dbcp/c3p0/druid/hikari 因为全部的链接池技术都实现了SUN公司所提供的DataSource接口 因此链接池也叫做"数据源" 第01步:在程序中建立一个c3p0链接池对象(存放链接的容器) ComboPooledDataSource pool = new ComboPooledDataSource(); 第02步:设置链接数据库的基本信息(四个参数) 方式一:将链接数据库的参数经过setXxx方法直接经过java代码写死在程序中 pool.setDriverClass("com.mysql.cj.jdbc.Driver"); pool.setJdbcUrl("jdbc:mysql:///jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai"); pool.setUser("root"); pool.setPassword("root"); 这种方式不推荐使用,由于这种方式将链接参数写死在程序中了,未来一旦参数发生变化,就须要咱们去改程序,改完以后须要对项目从新编译、打包、部署、运行等,会提升维护成本! 方式二:将链接数据库的参数提取到 c3p0.properties(文件名是固定的) 文件中 而且须要将这个文件放在源码根目录(src根目录)下,文件内容以下: ----------------------------------------- c3p0.driverClass=com.mysql.cj.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql:///jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai c3p0.user=root c3p0.password=root ----------------------------------------- 再次强调:这个文件的位置和名字都是固定的,由于底层c3p0会到指定的位置找指定名称的文件,若是没有按照要求去存放文件或者没有按照要求去指定文件名称,都会致使c3p0找不到这个文件,也就没法读取其中的配置信息,必然会致使连不上数据库! 方式三:将链接数据库的参数提取到 c3p0-config.xml(文件名也是固定的) 文件中 而且须要将这个文件放在源码根目录(src根目录)下,文件内容以下: ----------------------------------------- <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="driverClass"> com.mysql.cj.jdbc.Driver </property> <property name="jdbcUrl"> jdbc:mysql:///jt_db?characterEncoding=utf-8&serverTimezone=Asia/Shanghai </property> <property name="user">root</property> <property name="password">root</property> </default-config> </c3p0-config> ----------------------------------------- 再次强调:这个文件的位置和名字都是固定的,由于c3p0底层会到指定的位置找指定名称的文件,若是没有按照要求去存放文件或者没有按照要求去指定文件名称,都会致使c3p0找不到这个文件,也就没法读取其中的配置信息,必然会致使连不上数据库! 第04步:从链接池中获取一个链接对象进行使用 Connection conn = pool.getConnection(); 第05步:将用完的链接对象还回到链接池中 conn.close(); 若是在程序中没有使用任何链接池,须要链接就经过 DriverManager.getConnection获取(建立)一个链接,用完以后,调用conn.close()就是将链接资源关闭。 若是使用了链接池,经过 链接池对象调用 getConnection方法获取一个链接对象,此时获取的链接对象已经被改造了。用完以后,再调用conn.close()方法是将链接还回到链接池中。也就是说,从链接池中获取的链接对象上的close方法被改形成了还链接到链接池!
四、补充内容:xml文件和properties文件的区别
相同点:这两种文件在企业开发中均可以做为配置文件使用,并且用的特别多 不一样点:1)xml文件缺点:配置信息多,编写起来比较麻烦,若是须要经过java程序读取,代码也比较麻烦。 2)xml文件的优势:能够保存有结构的数据(例如在xml文件中保存中国全部的省份以及省份包含的市区) 3)properties文件缺点:配置信息结构是key/value,没法保存有结构的数据 4)properties文件优势:配置信息简洁,若是须要经过java程序读取,读取起来也比较方便。
==================================================
1、什么是事务?
事务:简单的说,事务是将一堆的SQL语句绑定在一块儿执行,结果是要么全都执行成功,要么全都执行失败。并且是都成功了才算成功,但凡是有一条执行失败,就按全失败来处理! 举例: 张三(1000)给李四(1000)转帐100元 -- 开启事务(start transaction) -- 给张三的帐户金额减去100元 update 帐户表 set money=money-100 where name='张三'; -- 1000 -- 给李四的帐户金额加上100元 update 帐户表 set money=money+100 where name='李四'; -- 1000 -- 提交事务(commit)/ 回滚事务(rollback) 举例: 网上购物 -- 开启事务 -- 往订单表中插入一条订单信息(用户、订单号、商品信息、商品数据量、单价、总金额等) insert into 订单表 value(....); -- 减去商品库存表中的库存数量 update 商品库存表 set count=count-2 where... -- 提交事务/回滚事务
2、事务的四大特性(重要)
一、原子性:表示事务中的全部操做(SQL)是一个总体,不能被分割,要么全都执行成功,要么全都执行失败! 二、一致性:在事务先后的业务数据之和是保持一致的。 在转帐操做以前,张三帐户金额(1000)和李四帐户金额(1000)之和为2000元 在转帐操做以后,不管事务提交了仍是回滚了,张三和李四的帐户金额之和仍是2000元。 三、隔离性:是指全部的事务都是隔离开来的,在一个事务中看不到另一个事务正在进行中的状态! 事务1: 查询A(1000)和B(1000)的帐户总金额 事务2: -- 开启事务 A帐户减去100元 -- A:900 B帐户加上100元 -- B:1100 -- 提交事务/回滚事务 四、持久性:在事务提交后,对数据的更新操做才会持久的保存到数据库中 -- 开启事务 A帐户(1000元)减去100元 -- A:900 B帐户(1000元)加上100元 -- B:1100 -- 提交事务/回滚事务
3、MySQL中的事务
在mysql中默认一条SQL语句就是一个事务。 若是但愿将多条SQL放在一个事务中执行,能够手动开启事务,并手动结束事务 开启事务: start transaction / begin; 结束事务:提交(commit) 和 回滚(rollback) 例子:使用转帐演示mysql中如何开启事务以及如何结束事务 -- 开启事务 start transaction; -- A帐户减去100元 update acc set money=money-100 where name='A'; -- B帐户加上100元 update acc set money=money+100 where name='B'; select * from acc; -- 回滚事务 | 提交事务 rollback; | commit; select * from acc;