SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范(接口),称之为JDBC。这套接口由数据库厂商去实现,这样,开拓职员只须要学习jdbc接口,并通过jdbc加载详细的驱动,就可以操作数据库。如下图所示:
JDBC全称为:Java Data Base Connectivity(java数据库连接),它紧张由接口组成。组成JDBC的2个包:java.sql、javax.sql开拓JDBC运用须要以上2个包的支持外,还须要导入相应JDBC的数据库实现(即数据库驱动)。

搭建实验环境
CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;USE jdbcStudy;CREATE TABLE users(id INT PRIMARY KEY,NAME VARCHAR(40),PASSWORD VARCHAR(40),email VARCHAR(60),birthday DATE);INSERT INTO users(id,NAME,PASSWORD,email,birthday)VALUES(1,'zhansan','123456','zs@sina.com','1980-12-04'),(2,'lisi','123456','lisi@sina.com','1981-12-04'),(3,'wangwu','123456','wangwu@sina.com','1979-12-04');
新建一个Java工程,并导入数据驱动
编写程序从user表中读取数据,并打印在命令行窗口中。
package com.kuang.lesson01;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;public class JdbcFirstDemo {public static void main(String[] args) throws Exception {//要连接的数据库URLString url = "jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true";//连接的数据库时利用的用户名String username = "root";//连接的数据库时利用的密码String password = "123456";//1.加载驱动//DriverManager.registerDriver(new com.mysql.jdbc.Driver());不推举利用这种办法来加载驱动Class.forName("com.mysql.jdbc.Driver");//推举利用这种办法来加载驱动//2.获取与数据库的链接Connection conn = DriverManager.getConnection(url, username,password);//3.获取用于向数据库发送sql语句的statementStatement st = conn.createStatement();String sql = "select id,name,password,email,birthday from users";//4.向数据库发sql,并获取代表结果集的resultsetResultSet rs = st.executeQuery(sql);//5.取出结果集的数据while(rs.next()){System.out.println("id=" + rs.getObject("id"));System.out.println("name=" + rs.getObject("name"));System.out.println("password=" + rs.getObject("password"));System.out.println("email=" + rs.getObject("email"));System.out.println("birthday=" + rs.getObject("birthday"));}//6.关闭链接,开释资源rs.close();st.close();conn.close();}}
1.5、工具解释
DriverManager类讲解
Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接,这个API的常用方法:
DriverManager.registerDriver(new Driver())DriverManager.getConnection(url, user, password)
把稳:在实际开拓中并不推举采取registerDriver方法注册驱动。缘故原由有二:
查看Driver的源代码可以看到,如果采取此种办法,会导致驱动程序注册两次,也便是在内存中会有两个Driver工具。程序依赖mysql的api,分开mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。推举办法:Class.forName(“com.mysql.jdbc.Driver”);采取此种办法不会导致驱动工具在内存中重复涌现,并且采取此种办法,程序仅仅只须要一个字符串,不须要依赖详细的驱动,使程序的灵巧性更高。
数据库URL讲解
URL用于标识数据库的位置,通过URL地址见告JDBC程序连接哪个数据库,URL的写法为:
常用数据库URL地址的写法:
Oracle写法:jdbc:oracle:thin:@localhost:1521:sidSqlServer写法:jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=sidMySql写法:jdbc:mysql://localhost:3306/sid如果连接的是本地的Mysql数据库,并且连接利用的端口是3306,那么的url地址可以简写为:jdbc:mysql:///数据
Connection类讲解
Jdbc程序中的Connection,它用于代表数据库的链接,Collection是数据库编程中最主要的一个工具,客户端与数据库所有交互都是通过connection工具完成的,这个工具的常用方法:
createStatement():创建向数据库发送sql的statement工具。prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement工具。setAutoCommit(boolean autoCommit):设置事务是否自动提交。commit() :在链接上提交事务。rollback() :在此链接上回滚事务。Statement类讲解
Jdbc程序中的Statement工具用于向数据库发送SQL语句, Statement工具常用方法:
executeQuery(String sql) :用于向数据发送查询语句。executeUpdate(String sql):用于向数据库发送insert、update或delete语句execute(String sql):用于向数据库发送任意sql语句addBatch(String sql) :把多条sql语句放到一个批处理中。executeBatch():向数据库发送一批sql语句实行。ResultSet类讲解
Jdbc程序中的ResultSet用于代表Sql语句的实行结果。Resultset封装实行结果时,采取的类似于表格的办法。ResultSet 工具掩护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向详细的数据行,进行调用方法获取该行的数据。
ResultSet既然用于封装实行结果的,以是该工具供应的都是用于获取数据的get方法:
获取任意类型的数据getObject(int index)getObject(string columnName)获取指定类型的数据,例如:getString(int index)getString(String columnName)ResultSet还供应了对结果集进行滚动的方法:
next():移动到下一行Previous():移动到前一行absolute(int row):移动到指定行beforeFirst():移动resultSet的最前面。afterLast() :移动到resultSet的末了面。开释资源
Jdbc程序运行完后,牢记要开释程序在运行过程中,创建的那些与数据库进行交互的工具,这些工具常日是ResultSet, Statement和Connection工具,特殊是Connection工具,它是非常罕有的资源,用完后必须立时开释,如果Connection不能及时、精确的关闭,极易导致系统宕机。Connection的利用原则是只管即便晚创建,只管即便早的开释。
为确保资源开释代码能运行,资源开释代码也一定要放在finally语句中。
1.6、statement工具Jdbc中的statement工具用于向数据库发送SQL语句,想完成对数据库的增编削查,只须要通过这个工具向数据库发送增编削查语句即可。
Statement工具的executeUpdate方法,用于向数据库发送增、删、改的sql语句,executeUpdate实行完后,将会返回一个整数(即增编削语句导致了数据库几行数据发生了变革)。
Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet工具。
CRUD操作-create
利用executeUpdate(String sql)方法完成数据添加操作,示例操作:
Statement st = conn.createStatement();String sql = "insert into user(….) values(…..) ";int num = st.executeUpdate(sql);if(num>0){System.out.println("插入成功!
!
!
");}
CRUD操作-delete
利用executeUpdate(String sql)方法完成数据删除操作,示例操作:
Statement st = conn.createStatement();String sql = "delete from user where id=1";int num = st.executeUpdate(sql);if(num>0){System.out.println(“删除成功!
!
!
");}
CRUD操作-update
利用executeUpdate(String sql)方法完成数据修正操作,示例操作:
Statement st = conn.createStatement();String sql = "update user set name='' where name=''";int num = st.executeUpdate(sql);if(num>0){System.out.println(“修正成功!
!
!
");}
CRUD操作-read
利用executeQuery(String sql)方法完成数据查询操作,示例操作:
Statement st = conn.createStatement();String sql = "select from user where id=1";ResultSet rs = st.executeUpdate(sql);while(rs.next()){//根据获取列的数据类型,分别调用rs的相应方法映射到java工具中}
利用jdbc对数据库增编削查1、新建一个 lesson02 的包2、在src目录下创建一个db.properties文件,如下图所示:
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=trueusername=rootpassword=123456
3、在lesson02 下新建一个 utils 包,新建一个类 JdbcUtils
package com.kuang.lesson02.utils;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;public class JdbcUtils {private static String driver = null;private static String url = null;private static String username = null;private static String password = null;static{try{//读取db.properties文件中的数据库连接信息InputStream in =JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");Properties prop = new Properties();prop.load(in);//获取数据库连接驱动driver = prop.getProperty("driver");//获取数据库连接URL地址url = prop.getProperty("url");//获取数据库连接用户名username = prop.getProperty("username");/获取数据库连接密码password = prop.getProperty("password");//加载数据库驱动Class.forName(driver);}catch (Exception e) {throw new ExceptionInInitializerError(e);}}// 获取数据库连接工具public static Connection getConnection() throws SQLException{return DriverManager.getConnection(url, username,password);}// 开释资源,要开释的资源包括Connection数据库连接工具,卖力实行SQL命令的Statement工具,存储查询结果的ResultSet工具public static void release(Connection conn,Statement st,ResultSet rs){if(rs!=null){try{//关闭存储查询结果的ResultSet工具rs.close();}catch (Exception e) {e.printStackTrace();}rs = null;}if(st!=null){try{//关闭卖力实行SQL命令的Statement工具st.close();}catch (Exception e) {e.printStackTrace();}}if(conn!=null){try{//关闭Connection数据库连接工具conn.close();}catch (Exception e) {e.printStackTrace();}}}}
利用statement工具完成对数据库的CRUD操作
1、插入一条数据
package com.kuang.lesson02;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.Statement;public class TestInsert {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try{//获取一个数据库连接conn = JdbcUtils.getConnection();//通过conn工具获取卖力实行SQL命令的Statement工具st = conn.createStatement();//要实行的SQL命令String sql = "insert into users(id,name,password,email,birthday)" +"values(4,'kuangshen','123','24736743@qq.com','2020-01-01')";//实行插入操作,executeUpdate方法返回成功的条数int num = st.executeUpdate(sql);if(num>0){System.out.println("插入成功!
!
");}}catch (Exception e) {e.printStackTrace();}finally{//SQL实行完成之后开释干系资源JdbcUtils.release(conn, st, rs);}}}
2、删除一条数据
package com.kuang.lesson02;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.Statement;public class TestDelete {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();String sql = "delete from users where id=4";st = conn.createStatement();int num = st.executeUpdate(sql);if(num>0){System.out.println("删除成功!
!
");}catch (Exception e) {e.printStackTrace();}finally{JdbcUtils.release(conn, st, rs);}}}
3、更新一条数据
package com.kuang.lesson02;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.Statement;public class TestUpdate {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();String sql = "update users setname='kuangshen',email='24736743@qq.com' where id=3";st = conn.createStatement();int num = st.executeUpdate(sql);if(num>0){System.out.println("更新成功!
!
");}}catch (Exception e) {e.printStackTrace();}finally{JdbcUtils.release(conn, st, rs);}}}
4、查询数据
package com.kuang.lesson02;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.Statement;public class TestSelect {public static void main(String[] args) {Connection conn = null;Statement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();String sql = "select from users where id=3";st = conn.createStatement();rs = st.executeQuery(sql);if(rs.next()){System.out.println(rs.getString("name"));}}catch (Exception e) {e.printStackTrace();}finally{JdbcUtils.release(conn, st, rs);}}
SQL 注入问题
通过奥妙的技巧来拼接字符串,造成SQL短路,从而获取数据库数据
package com.kuang.lesson02;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.ResultSet;import java.sql.Statement;public class SQL注入 {public static void main(String[] args) {// login("zhangsan","123456"); // 正常上岸login("'or '1=1","123456"); // SQL 注入}public static void login(String username,String password){Connection conn = null;Statement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();// select from users where name='' or '1=1' and password ='123456'String sql = "select from users where name='"+username+"' andpassword='"+password+"'";st = conn.createStatement();rs = st.executeQuery(sql);while(rs.next()){System.out.println(rs.getString("name"));System.out.println(rs.getString("password"));System.out.println("==============");}}catch (Exception e) {e.printStackTrace();}finally{JdbcUtils.release(conn, st, rs);}}}
1.7 、PreparedStatement工具
PreperedStatement是Statement的子类,它的实例工具可以通过调用Connection.preparedStatement()方法得到,相对付Statement工具而言:PreperedStatement可以避免SQL注入的问题。
Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。
PreparedStatement可对SQL进行预编译,从而提高数据库的实行效率。并且PreperedStatement对付sql中的参数,许可利用占位符的形式进行更换,简化sql语句的编写。
利用PreparedStatement工具完成对数据库的CRUD操作
1、插入数据
package com.kuang.lesson03;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.util.Date;import java.sql.PreparedStatement;import java.sql.ResultSet;public class TestInsert {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try{//获取一个数据库连接conn = JdbcUtils.getConnection();//要实行的SQL命令,SQL中的参数利用?作为占位符String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";//通过conn工具获取卖力实行SQL命令的prepareStatement工具st = conn.prepareStatement(sql);//为SQL语句中的参数赋值,把稳,索引是从1开始的st.setInt(1, 4);//id是int类型的st.setString(2, "kuangshen");//name是varchar(字符串类型)st.setString(3, "123");//password是varchar(字符串类型)st.setString(4, "24736743@qq.com");//email是varchar(字符串类型)st.setDate(5, new java.sql.Date(newDate().getTime()));//birthday是date类型//实行插入操作,executeUpdate方法返回成功的条数int num = st.executeUpdate();if(num>0){System.out.println("插入成功!
!
");}}catch (Exception e) {e.printStackTrace();}finally{//SQL实行完成之后开释干系资源JdbcUtils.release(conn, st, rs);}}}
2、删除一条数据
package com.kuang.lesson03;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;public class TestDelete {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();String sql = "delete from users where id=?";st = conn.prepareStatement(sql);st.setInt(1, 4);int num = st.executeUpdate();if(num>0){System.out.println("删除成功!
!
");}}catch (Exception e) {e.printStackTrace();}finally{JdbcUtils.release(conn, st, rs);}}}
3、更新一条数据
package com.kuang.lesson03;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;public class TestUpdate {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();String sql = "update users set name=?,email=? where id=?";st = conn.prepareStatement(sql);st.setString(1, "kuangshen");st.setString(2, "24736743@qq.com");st.setInt(3, 2);int num = st.executeUpdate();if(num>0){System.out.println("更新成功!
!
");}}catch (Exception e) {e.printStackTrace();}finally{JdbcUtils.release(conn, st, rs);}}}
4、查询一条数据
package com.kuang.lesson03;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;public class TestSelect {public static void main(String[] args) {Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();String sql = "select from users where id=?";st = conn.prepareStatement(sql);st.setInt(1, 1);rs = st.executeQuery();if(rs.next()){System.out.println(rs.getString("name"));}}catch (Exception e) {}finally{JdbcUtils.release(conn, st, rs);}}}
避免SQL 注入
package com.kuang.lesson03;import com.kuang.lesson02.utils.JdbcUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.Statement;public class SQL注入 {public static void main(String[] args) {// login("zhangsan","123456"); // 正常上岸login("'or '1=1","123456"); // SQL 注入}public static void login(String username,String password){Connection conn = null;PreparedStatement st = null;ResultSet rs = null;try{conn = JdbcUtils.getConnection();// select from users where name='' or '1=1' and password ='123456'String sql = "select from users where name=? and password=?";st = conn.prepareStatement(sql);st.setString(1,username);st.setString(2,password);rs = st.executeQuery();while(rs.next()){System.out.println(rs.getString("name"));System.out.println(rs.getString("password"));System.out.println("==============");}}catch (Exception e) {e.printStackTrace();}finally{JdbcUtils.release(conn, st, rs);}}}
事理:实行的时候参数会用引号包起来,并把参数中的引号作为转义字符,从而避免了参数也作为条件的一部分
2、javaweb-jdbc什么是JDBC : Java连接数据库!
须要jar包的支持:
java.sqljavax.sqlmysql-conneter-java… 连接驱动(必须要导入)实验环境搭建
CREATE TABLE users(id INT PRIMARY KEY,`name` VARCHAR(40),`password` VARCHAR(40),email VARCHAR(60),birthday DATE);INSERT INTO users(id,`name`,`password`,email,birthday)VALUES(1,'张三','123456','zs@qq.com','2000-01-01');INSERT INTO users(id,`name`,`password`,email,birthday)VALUES(2,'李四','123456','ls@qq.com','2000-01-01');INSERT INTO users(id,`name`,`password`,email,birthday)VALUES(3,'王五','123456','ww@qq.com','2000-01-01');SELECT FROM users
导入数据库依赖
<!--mysql的驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency>
IDEA中连接数据库:
JDBC 固定步骤:
加载驱动连接数据库,代表数据库向数据库发送SQL的工具Statement : CRUD编写SQL (根据业务,不同的SQL)实行SQL关闭连接public class TestJdbc {public static void main(String[] args) throws ClassNotFoundException,SQLException {//配置信息//useUnicode=true&characterEncoding=utf-8 办理中文乱码String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";String username = "root";String password = "123456";//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.连接数据库,代表数据库Connection connection = DriverManager.getConnection(url, username,password);//3.向数据库发送SQL的工具Statement,PreparedStatement : CRUDStatement statement = connection.createStatement();//4.编写SQLString sql = "select from users";//5.实行查询SQL,返回一个 ResultSet : 结果集ResultSet rs = statement.executeQuery(sql);while (rs.next()){System.out.println("id="+rs.getObject("id"));System.out.println("name="+rs.getObject("name"));System.out.println("password="+rs.getObject("password"));System.out.println("email="+rs.getObject("email"));System.out.println("birthday="+rs.getObject("birthday"));}//6.关闭连接,开释资源(一定要做) 先开后关rs.close();statement.close();connection.close();}}
预编译SQL
public class TestJDBC2 {public static void main(String[] args) throws Exception {//配置信息//useUnicode=true&characterEncoding=utf-8 办理中文乱码String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";String username = "root";String password = "123456";//1.加载驱动Class.forName("com.mysql.jdbc.Driver");//2.连接数据库,代表数据库Connection connection = DriverManager.getConnection(url, username,password);//3.编写SQLString sql = "insert into users(id, name, password, email,birthday) values (?,?,?,?,?);";//4.预编译PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,2);//给第一个占位符? 的值赋值为1;preparedStatement.setString(2,"狂神说Java");//给第二个占位符? 的值赋值为狂神说Java;preparedStatement.setString(3,"123456");//给第三个占位符? 的值赋值为123456;preparedStatement.setString(4,"24736743@qq.com");//给第四个占位符? 的 值赋值为1;preparedStatement.setDate(5,new Date(newjava.util.Date().getTime()));//给第五个占位符? 的值赋值为new Date(newjava.util.Date().getTime());//5.实行SQLint i = preparedStatement.executeUpdate();if (i>0){System.out.println("插入成功@");}//6.关闭连接,开释资源(一定要做) 先开后关preparedStatement.close();connection.close();}}
事务要么都成功,要么都失落败!
ACID原则:担保数据的安全。
开缘由务事务提交 commit()事务回滚 rollback()关闭事务转账:A:1000B:1000A(900) --100--> B(1100)
Junit单元测试依赖
<!--单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
大略利用@Test表明只有在方法上有效,只要加了这个表明的方法,就可以直接运行!
@Testpublic void test(){System.out.println("Hello");}
失落败的时候是赤色: