JDBC: Java Database Connectivity Java连接数据库技术
通俗点说,在Java代码中,使用JDBC提供的方法,可以发送字符串类型的SQL语句到数据库管理软件(Mysql,Oracle等),并且获取语句执行结果!进而实现数据库数据CRUD操作的技术!
- jdbc 由 java 语言的规范(接口)和各个数据库厂商的实现驱动(jar)组成
- jdbc 是一种典型的面向接口编程
一、 java获取数据库信息步骤:
Statement :(静态sql)
- 注册驱动
- 获取连接
- 创建发送 sql 语句对象
- 发送 sql 语句,并获取返回结果
- 结果集解析
- 资源关闭
PreparedStatement :(防止sql注入)
- 注册驱动
- 获取连接
- 编写sql
- 创建PreparedStatement 并且传入sql语句结构
- 占位符赋值
- 发送sql语句,并且获取结果
- 结果集解析
- 关闭资源
import java.sql.*;public class StatementQueryPart {public static void main(String[] args) throws SQLException, ClassNotFoundException {//1.注册驱动Class.forName("con.mysql.jc.jdbc.Driver");//2.获取连接String url="jdbc:mysql://localhost:3306/atguigudb";String user="root";String psd="123456";Connection connection = DriverManager.getConnection(url,user,psd);//3.创建statementStatement statement = connection.createStatement();//4.发送SQL语句String sql = "select * from t_user;";ResultSet resultSet = statement.executeQuery(sql);//5.结果集解析while(resultSet.next()){int id = resultSet.getInt("id");String account = resultSet.getString("account");String password = resultSet.getString("password");String nickname = resultSet.getString("nickname");System.out.println(id+"::"+account+"::"+password+"::"+nickname);}//6.关闭资源resultSet.close();statement.close();connection.close();}
}
1、获取数据库连接
getConnection(url,user,password) 方法介绍:
核心参数:
1.数据库软件所在的主机的ip地址:localhost | 127.0.0.1
2.数据库软件所在的主机的端口号:3306
3.连接的具体的库:atguigudb
4.连接的账号:root
5.连接的密码:123456
6.可选的信息 没有
String url:语法:jdbc:数据库管理软件名称[mysql,oracle]://ip地址|主机名:port端口号/数据库名?key=value&key=value 可选信息具体:jdbc:mysql://127.0.0.1:3306/atguigudbjdbc:mysql://localhost:3306/atguigudb本机的省略写法:如果你的数据库软件安装到本机,可以进一步省略jdbc:mysql://127.0.0.1:3306/atguigudb = jdbc:mysql:///atguigudb省略了[本机地址]和[3306默认端口号]强调:必须是本机,并且端口号使用3306方可省略 使用 ///String user: 数据库的账号 root
String password:数据库的密码 123456
2、获取返回结果,并处理结果集
SQL分类: DDL(容器创建,修改,删除)DML(插入,修改,删除)DQL(查询)DCL(权限控制)TPL(事务控制语言)参数:sql 非DQL返回:intDML 返回影响的行数参数:sql DQL 返回:resultSet 结果集封装对象
查询结果集解析 ResultSet
1、游标移动问题resultSet内部包含一个游标,指定当前行数据!默认游标指定的是第一行数据之前!我们可以调用next方法向后移动一行游标如果我们有很多行数据,我们可以使用 while(next){获取每一行数据}boolean = next() true:有更多数据,并且向下移动一行2、获取列的数据问题(获取光标指定的行的列的数据)resultSet.get(String columnLabel | int columnIndex); columnLabel:列名 如果有别名 写别名columnIndex:列的下角标获取 从左向右 从1 开始
示例:
//5.结果集解析while(resultSet.next()){int id = resultSet.getInt(1);String account = resultSet.getString("account");String password = resultSet.getString(3);String nickname = resultSet.getString("nickname");System.out.println(id+"::"+account+"::"+password+"::"+nickname);}输出:
1::root::123456::经理
2::admin::666666::管理员
3、Statement 和 PrepareStatement
Statement 的缺点
不能防止SQL注入
PreparedStatement1、编写SQL语句结果 不包含动态值部分的语句,动态值部分使用占位符 ? 替代 注意:?只能替代动态值2、创建PreparedStatement,并且传入动态值3、动态值 占位符 赋值 ? 单独赋值即可4、发送SQL语句即可,并获取返回结果
//3、编写sqlString sql = "select * from t_user where account = ? and password = ?;";
//4、创建预备通道PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5、给预备通道 占位符赋值参数1:index 占位符的位置 从左向右数 从1开始参数2:Object 占位符的值 可以设置任何类型的数据,避免了我们拼接和类型更加丰富preparedStatement.setObject(1,user);preparedStatement.setObject(2,password);
//6.发送sqlResultSet resultSet = preparedStatement.executeQuery();
4、自动遍历结果集
//5、处理结果集List<Map> result = new ArrayList<>();while(resultSet.next()){Map map = new HashMap();map.put("id",resultSet.getInt("id"));map.put("account",resultSet.getString("account"));map.put("password",resultSet.getString("password"));map.put("nickname",resultSet.getString("nickname"));result.add(map);}
可以看出我们在获取数据库信息时,需要知道数据库表的列名,假如换了一张表呢?
有没有那种智能一点的获取方法呢。
//获取列的信息对象//TODO: metaData 装的当前结果集列的信息对象!(它可以获取列的名称根据下角标,可以获取列的数量)ResultSetMetaData metaData = resultSet.getMetaData();//有了它以后,我们可以水平遍历列int columnCount = metaData.getColumnCount();while(resultSet.next()){Map map = new HashMap();for (int i = 1; i <= columnCount; i++) {//获取指定列下角标的值!Object value = resultSet.getObject(i);//获取指定列下角标的名称!//getColumnLabel:会获取别名,如果没有写别名才是列的名称 //不要使用 getColumnName:只会获取列的名称String columnLabel = metaData.getColumnLabel(i);map.put(columnLabel,value);}result.add(map);}
5、自增长主键回显实现
功能需求:
1、java 程序获取插入数据时 mysql 自增长维护的主键 id 值,这就是主键回显
2、作用:在多表关联插入数据时,一般主表的主键是自动生成的,所以在插入数据之前无法知道这个条数据的主键,但是从表需要在插入数据之前就绑定主表的主键,这是可以使用主键回显技术
import org.junit.Test;import java.sql.*;public class PSOtherPart {/*** TODO:* t_user插入一条数据!并且获取数据库自增长的主键!* TODO:使用总结* 1、创建prepareStatement的时候,告知,携带回数据库自增长的主键(sql,Statement.RETURN_GENERATED_KEYS)* 2、获取司机(preparedstatement)装主键值的解果集对象,
一行一列,获取对应的数据即可* ResultSet resultSet = statement.getGenerateKeys();**/@Testpublic void returnPrimaryKey() throws Exception{//1、注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//2、获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///atguigudb", "root", "123456");//3、编写SQL语句String sql = "insert into t_user(account,password,nickname) values(?,?,?)";//4、创建statementPreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);//5、占位符赋值statement.setObject(1,"test3");statement.setObject(2,"123456");statement.setObject(3,"懒洋洋");//6、发送sql语句,并且获取结果int i = statement.executeUpdate();//7、结果解析if(i > 0){System.out.println("数据插入成功!");//可以获取回显主键//获取司机装主键的结果集对象,一行 一列 id = 值ResultSet resultSet = statement.getGeneratedKeys();resultSet.next();//移动一下光标int id = resultSet.getInt(1);System.out.println("id = " + id);}else{System.out.println("数据插入失败!");}}
}输出:
数据插入成功!
id = 1
使用总结
1、创建prepareStatement的时候,告知,携带回数据库自增长的主键(sql,Statement.RETURN_GENERATED_KEYS)
2、获取司机(preparedstatement)装主键值的解果集对象,一行一列,获取对应的数据即可
ResultSet resultSet = statement.getGenerateKeys();