目录
1.JDBC
1.1 基本概念
- 概念: JDBC(Java DataBase Connectivity),Java数据库连接,Java语言操作数据库,Java访问数据库的标准规范。
- 本质: 是sun公司定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。
- 好处: 程序员只需要会调用JDBC接口中的方法就行,不用关注类是如何实现的;使用同一套Java代码,进行少量的修改就可以访问其他JDBC支持的数据库。
数据库驱动下载:直达链接
JDBC开发使用到的包:
java.sql: 所有与JDBC访问数据库相关的接口和类
javax.sql: 数据库扩展包,提供数据库额外的功能。如:连接池
1.2 基本实现步骤
- 导入驱动jar包:复制mysql-connector-java-5.1.48.jar到项目的libs目录下;然后右键jar包→Add as Library。
mysql-connector-java-5.1.48.jar与 mysql-connector-java-5.1.48-bin.jar的区别:
使用上是没区别的一样的,都可以用,带-bin的文件里在编译的的时候里面多了几个编译用的校验文件而已
- 注册驱动:
///抛出找不到的异常(ClassNotFoundException),注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
注意:从JDBC3开始,可以不用注册驱动而直接使用。Class.forName这句话可以省略。
- 获取数据库连接对象:
///抛出SQLException异常,数据库访问错误
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test" +
"数据库名"+"数据库密码");
- 定义sql语句:
///如:
String sql = "update t_user set salary = 2200 where id = 1";
- 获取执行sql的对象Statement,并执行sql语句:
///获取执行sql的对象Statement()
Statement stmt = conn.createStatement();
///执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容
int count = stmt.executeUpdate(sql);
System.out.println(count);
- 释放资源:
stmt.close();
conn.close();
2.详解JDBC的核心API
2.1 DriverManager类(驱动管理对象)与Connection接口(数据库连接对象)
可以用参数设置指定字符编码。
如果是本地服务器且端口号为3306的话,可以写为:
jdbc:mysql:///数据库名
- 创建数据库的连接:
1.通过连接字符串,用户名,密码来得到数据库的连接对象
Connection getConnection(String url,String user,String password);
String url = "jdbc:mysql://localhost:3306/test";
Connection conn = DriverMananger.getConnection(url,"root","123456");
System.out.println(conn);
2.通过连接字符串,属性对象来得到连接对象
Connection getConnection(String url,Properties info);
String url = "jdbc:mysql://localhost:3306/test"
Properties info = new Properties();
info.setProperty("user","root");
info.setProperty("password","123456");
Connection conn = DriverMananger.getConnection(url,info);
System.out.println(conn);
- 使用Connection对象来管理事务,如转账案例:通过设置事务的先后顺序,以免转账错误。
1.开启事务:setAutoCommit(boolean autoCommit),在执行sql之前开启事务
2.提交事务:commit(),当所有sql都执行完提交事务
3.回滚事务:rollback(),在catch中回滚事务
2.2 Statement接口与PreparedStatement接口(执行sql的对象)
PreparedStatement是Statement接口的子接口,它是一个预编译的SQL语句
- Statement的执行原理:Statement对象每执行一条SQL语句都会先将SQL语句发送给数据库,数据库先编译SQL,在执行。
State stmt = conn.createStatement();
stmt.executeUpdate("insert into t_user values (id,'项羽','31',3100)");///id已经在navicat中设置为自动递增了,所以不需要确定的值
stmt.executeUpdate("insert into t_user values (id,'廉颇','56',5600)");
如果有一万条类似的SQL语句,数据库需要编译1万次,执行1万次,效率低。
- PreparedStatement的执行原理:PreparedStatement对象回先将SQL语句发送给数据库预编译。PreparedStatement会引用着预编译后的结果,可以多次传入不同的参数给PreparedStatement对象并执行。
String sql = "insert into t_user values (?,?,?,?)";///?为占位符
//得到语句对象
PreparedStatement ps = conn.prepareStatement(sql);
//设置参数
ps.setInt(1, id);
ps.setString(2,'项羽');
ps.setInt(3,31);
ps.setInt(4,3100);
ps.executeUpdate();
///再次设置参数
ps.setInt(1, id);
ps.setString(2,'廉颇');
ps.setInt(3,56);
ps.setInt(4,5600);
ps.executeUpdate();
如果有1万条类似的插入数据的语句。数据库只需要预编译一次。传入1万次不同的参数并执行。减少了SQL语句的编译次数。提高了执行效率。
- 接口相关的方法
boolean execute(String sql)
///可以执行任意的sql 了解
int executeUpdate(String sql)
///执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
executeUpdate函数的返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
///抛出找不到的异常,注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test" ,
"root","123456");
String sql = "insert into t_user values (id,'项羽','31',3100)";
Statement stmt = conn.createStatement();
int count = stmt.executeUpdate(sql);
///执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容
if(count>0) System.out.println("添加成功!");
else System.out.println("添失败!");
stmt.close();
conn.close();
2.3 ResultSet(结果集,封装查询对象)
ResultSet executeQuery(String sql)///用于发送 DQL 语句,执行查询的操作
- 作用:封装数据库查询的结果集,对结果进行遍历,取出每一条记录。
- 接口中的方法:
1.boolean next(): 游标向下移动1行,判断当前记录是否还有下一条记录,如果返回true,表示还有下一条,否则没有。
2.数据类型 getXxx(),有两种实现方法:
返回指定列名的结果:getInt(“id”)、getString(“name”)、…;
返回指定列号的结果:getInt(1)、getString(2)、…。
import java.sql.*;
public class Demo {
static Connection conn = null;
static Statement stmt = null;
static ResultSet rs = null;
public static void main(String [] args) throws Exception {
///抛出找不到的异常,注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test" ,
"root","123456");
String sql = "insert into t_user values (id,'项羽','31',3100)";
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from t_user");
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
int salary = rs.getInt("salary");
System.out.println("编号:"+id+" 姓名:"+name+" 年龄:"+age+" 工资:"+salary);
}
rs.close();
stmt.close();
conn.close();
}
}
3.设计工具类JdbcUtils
为了简化代码,提高代码的可读性。下面以一个从控制台输出登录案例的例子:
JdbcUtils.java:
import javax.swing.plaf.nimbus.State;
import java.sql.*;
public class JdbcUtils {
private static final String USER = "root";
private static final String PWD = "123456";
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String DRIVER = "com.mysql.jdbc.Driver";
static{
try{
Class.forName(DRIVER);
}catch (ClassNotFoundException e){
e.printStackTrace();
}
}///注册驱动
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(URL,USER,PWD);
}///得到数据库连接
public static void close(Connection conn, Statement stmt){
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
public static void close(Connection conn ,Statement stmt,ResultSet rs){
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
}
}
close(conn,stmt);
}
}
通过调用工具类,运行login.java,实现登录事件:
import java.sql.*;
import java.util.Scanner;
public class login {
public static void main(String [] args)throws SQLException{
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String name = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
login(name,password);
}
public static void login(String name,String password) throws SQLException{
/*
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
stmt = conn.createStatement();
String sql = "select * from user where name = '" + name + "'and password = '" + password + "'";
System.out.println(sql);
rs = stmt.executeQuery(sql);
if (rs.next()) {
System.out.println("登录成功,欢迎你:" + name);
} else {
System.out.println("登录失败!");
}
}catch(SQLException e){
e.printStackTrace();
}finally {
JdbcUtils.close(conn,stmt,rs);
}
*/
Connection conn = JdbcUtils.getConnection();
//写成登录SQL语句,没有单引号
String sql = "select * from user where name=? and password=?";
//得到语句对象
PreparedStatement ps = conn.prepareStatement(sql);
//设置参数
ps.setString(1, name);
ps.setString(2,password);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
System.out.println("登录成功:" + name);
}else {
System.out.println("登录失败");
} //释放资源,子接口直接给父接口
JdbcUtils.close(conn,ps,rs);
}
}