JDBC
- idea第一次使用过程中会出现使用时区错误,设置时区后解决问题
概念:JAVA DataBase Connectivity -java 数据库连接,java语言操作数据库
JDBC本质:sun公司定义的一套JAVA连接各种关系型数据库的规则(接口),并没有进行实现,而是由每个数据库厂商实现了这个接口,并且提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行代码的是驱动jar包中的实现类。
-
JDBC 快速入门
package cn.learn.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class JdbcDemo01 { public static void main(String[] args) { //1.导入厂商jar包,复制包到新建文件夹lib,再add as Library /* mysql厂商的jar包在5版本后里的META-INF中已经注册驱动,可 以不写 Class.forName("com.mysql.jdbc.Driver"); */ Statement statement = null; Connection conn = null; try { //2.注册驱动,加载进内存 Class.forName("com.mysql.jdbc.Driver"); //3.获取数据库连接对象 conn = DriverManager.getConnection("jdbc:mysql:// localhost:3306/db1","root","123"); //4.定义SQL语句,语句不加分号 String sql = " insert into student(id,name) values (8,'小白白') "; //5.获取执行sql的对象,Statement statement = conn.createStatement(); //6.执行SQL int count = statement.executeUpdate(sql); //7.处理结果, if(count == 1){ System.out.println("处理成功"); } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); }finally { //8.释放资源,如果在第5步之前出现异常,执行进来statement 为空,则会出现空指针异常 if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
详解JDBC中的对象
Connection -数据库连接对象
java.sql 接口 Connection
- 功能
- 获取执行sql的对象,其中方法:
- Statement createStatement()
创建一个 Statement 对象来将 SQL 语句发送到数据库 - PreparedStatement prepareStatement(String sql)
创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
- Statement createStatement()
- 管理事务:
开启事务方法:
void setAutoCommit(boolean autoCommit)
将此连接的自动提交模式设置为给定状态,参数false即为手动提交,开启事务提交事务:void commit()
回滚事务:void rollback()
- 最后资源需要关闭,以免造成内存泄漏。
- 获取执行sql的对象,其中方法:
DriverManager - 驱动管理对象
java.sql 类 DriverManager
- 功能:
- 注册驱动
-
方法:
static void registerDriver(Driver driver) 向 DriverManager 注册给定驱动程序
而Class.forName("com.mysql.jdbc.Driver");
通过查看源码,在com.mysql.jdbc.Driver类中存在静态代码块public class Driver extends NonRegisteringDriver implements java.sql.Driver { // // Register ourselves with the DriverManager // static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
-
- 获取数据库连接:
-
静态方法:
static Connection getConnection(String url,String user,String password) 试图建立到给定数据库 URL 的连接。
- 参数:
- URL:指定连接的路径
- 语法:
url:jdbc:mysql://ip地址(域名):端口号/数据库名称(本机默认端口是3306可简写为///数据库名称)
user:用户名
password: 密码
- 语法:
- URL:指定连接的路径
-
- 注册驱动
Statement -执行sql对象
- public interface Statement extends Wrapper
用于执行静态 SQL 语句并返回它所生成结果的对象。
- 执行sql
- int executeUpdate(String sql)
执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。
注意:返回值int是影响的行数,可由此来判断是否执行成功 - ResultSet executeQuery(String sql)
执行给定的DQL语句,返回ResultSet结果集对象。 - 资源需要关闭
package cn.learn.jdbc; import java.sql.*; public class JdbcDemo01 { public static void main(String[] args) { //1.导入厂商jar包,复制包到新建文件夹lib,再add as Library /* mysql厂商的jar包在5版本后里的META-INF中已经注册驱动,可 以不写 Class.forName("com.mysql.jdbc.Driver"); */ Statement statement = null; Connection conn = null; ResultSet count = null; try { //2.注册驱动,加载进内存 Class.forName("com.mysql.jdbc.Driver"); //3.获取数据库连接对象 conn = DriverManager.getConnection("jdbc:mysql:/// db1","root","123"); //4.定义SQL语句,语句不加分号 String sql = " select * from student "; //5.获取执行sql的对象,Statement statement = conn.createStatement(); //6.执行SQL count = statement.executeQuery(sql); //7.处理结果,打印在控制台 //7.1 先让光标移动一行,进入数据区域 while(count.next()){ System.out.print(count.getInt(1) "-----"); System.out.print(count.getString(2) "-----"); System.out.print(count.getInt(3) "-----"); System.out.print(count.getDouble(4) "-----"); System.out.println(count.getDate(5)); } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); }finally { //8.释放资源,如果在第5步之前出现异常,执行进来statement 为空,则会出现空指针异常 if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if(count != null){ try { count.close(); } catch (SQLException e) { e.printStackTrace(); } } } } } /* 1-----小白-----15-----85.6-----1996-02-03 2-----小王-----13-----88.2-----null 3-----as-----88-----89.2-----null 8-----小白白-----0-----0.0-----null 9-----小白-----15-----75.6-----1996-02-03 */
- int executeUpdate(String sql)
抽取JDBC工具类 : JDBCUtils
- 目的:简化书写
- 分析:
- 注册驱动也抽取
- 抽取一个方法获取连接对象
- 需求:不想传递参数(麻烦),还得保证工具类的通用性。
- 解决:配置文件
jdbc.properties
url=
user=
password=
- 抽取一个方法释放资源
- 代码实现:
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/**
* 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
*/
static{
//读取资源文件,获取值。
try {
//1. 创建Properties集合类。
Properties pro = new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();
System.out.println(path);
pro.load(new FileReader(path));
//3. 获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4. 注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接
* @return 连接对象
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
/**
* 释放资源
* @param stmt
* @param conn
*/
public static void close(Statement stmt,Connection conn){
if( stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if( conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 释放资源
* @param stmt
* @param conn
*/
public static void close(ResultSet rs,Statement stmt, Connection conn){
if( rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if( stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if( conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
- 练习:
- 需求:
- 通过键盘录入用户名和密码
- 判断用户是否登录成功
- select * from user where username = "" and password = "";
- 如果这个sql有查询结果,则成功,反之,则失败
- 步骤:
- 创建数据库用户表 user
CREATE TABLE USER( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32), PASSWORD VARCHAR(32) ); INSERT INTO USER VALUES(NULL,'zhangsan','123'); INSERT INTO USER VALUES(NULL,'lisi','234');
- 代码实现:
public class JDBCDemo9 { public static void main(String[] args) { //1.键盘录入,接受用户名和密码 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.nextLine(); System.out.println("请输入密码:"); String password = sc.nextLine(); //2.调用方法 boolean flag = new JDBCDemo9().login(username, password); //3.判断结果,输出不同语句 if(flag){ //登录成功 System.out.println("登录成功!"); }else{ System.out.println("用户名或密码错误!"); } } /** * 登录方法 */ public boolean login(String username ,String password){ if(username == null || password == null){ return false; } //连接数据库判断是否登录成功 Connection conn = null; prepareStatement pstmt = null; ResultSet rs = null; //1.获取连接 try { conn = JDBCUtils.getConnection(); //2.定义sql String sql = "select * from user where username = ? and password = ?"; //3.获取执行sql的对象 pstmt = conn.prepareStatement(sql); //设置通配符传给需要的对象 pstmt.setString(1,username); pstmt.setString(2,password); //4.执行查询,不需要传参 rs = pstmt.executeQuery(); //5.判断 /* if(rs.next()){//如果有下一行,则返回true return true; }else{ return false; }*/ return rs.next();//如果有下一行,则返回true } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.close(rs,pstmt,conn); } return false; } }
- 需求:
ResulSet -结果集对象
- public interface ResultSet extends Wrapper
- ResultSet:用来封装查询的结果集(表),内有以下方法获取查询结果的数据
- next(): 游标向下移动一行
- getXXX(参数):获取数据
- XXX:为数据类型,如int,String...
- 参数:
- 接收是Int型:代表列编号,从1开始
- 接收是String型:代表列名称
- 结果集是一个资源,需要关闭
PreparedStatemnet -动态传参
- PreparedStatement:执行sql的对象
- SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题,如下:
- 输入用户随便,输入密码:a‘ or ‘a‘ = ‘a
- sql:select * from user where username = ‘fhdsjkf‘ and password = ‘a‘ or ‘a‘ = ‘a‘
- 解决sql注入问题:使用PreparedStatement对象来解决
- 预编译的SQL:参数使用?作为占位符
- 步骤:
- 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
- 注册驱动
- 获取数据库连接对象 Connection
- 定义sql
- 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;
- 获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)
- 给?赋值:
- 方法: setXxx(参数1,参数2)
- 参数1:?的位置,编号 从1 开始
- 参数2:?的值
- 方法: setXxx(参数1,参数2)
- 执行sql,接受返回结果,不需要传递sql语句
- 处理结果
- 释放资源
- 后期都会使用PreparedStatement来完成增删改查的所有操作
- 可以防止SQL注入
- 效率更高
- SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题,如下:
JDBC控制事务:
- 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理则这多个步骤要么同时成功,要么同时失败。
- 操作:
- 开启事务
- 提交事务
- 回滚事务
- 使用Connection对象来管理事务
- 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
- 在执行sql之前开启事务
- 提交事务:commit()
- 当所有sql都执行完提交事务
- 回滚事务:rollback()
- 在catch中回滚事务
- 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
- 代码:
public class JDBCDemo10 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
//1.获取连接
conn = JDBCUtils.getConnection();
//开启事务(若代码中有错则会进行回滚)
conn.setAutoCommit(false);
//2.定义sql
//2.1 张三 - 500
String sql1 = "update account set balance = balance - ? where id = ?";
//2.2 李四 500
String sql2 = "update account set balance = balance ? where id = ?";
//3.获取执行sql对象
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//4. 设置参数
pstmt1.setDouble(1,500);
pstmt1.setInt(2,1);
pstmt2.setDouble(1,500);
pstmt2.setInt(2,2);
//5.执行sql
pstmt1.executeUpdate();
pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception e) {
//事务回滚
try {
if(conn != null) {
conn.rollback();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.close(pstmt1,conn);
JDBCUtils.close(pstmt2,null);
}
}
}
JDBC实验
- Java实验四 JDBC
使用SQL Server数据库或者MySQL数据库各自的客户端工具,完成如下任务:- 创建数据库students;
- 在数据students中创建表scores,包括如下字段:学号、姓名、性别、得分,字段类型自行定义。学号为主键。
- 接着使用JDBC编写Java程序,完成如下任务:
- 在表格scores插入5条记录,代表5个学生,三位男生二位女生,各字段内容自定(“得分”字段填入自定分数);
- 显示5位学生的所有信息;
- 将三位男生的得分减去5分,将两位女生的成绩加上3分;
- 从键盘输入不同学号,根据学号显示相应学生的所有信息。
sql语句
CREATE DATABASE students;
CREATE TABLE scores(
id INT PRIMARY KEY,
NAME VARCHAR(32) NOT NULL,
sex VARCHAR(1),
score DOUBLE(5,2)
);
INSERT INTO scores VALUES(201826501,'老王','男',88.2),(201826502,'老胡','男',99.3),(201826503,'老薛','男',100),(201826504,'老巴','女',89.3),(201826505,'老谢','女',95.6);
UPDATE scores SET score = score-5 WHERE sex='男';
SELECT * FROM scores WHERE id = 201826501;
main方法
package cn.work.demo.Jdbc;
import java.sql.*;
public class JdbcDemo01 {
public static void main(String[] args) {
//导入厂商jar包,复制包到新建文件夹lib,再add as Library
/*
mysql厂商的jar包在5版本后里的META-INF中已经注册驱动,可以不写
Class.forName("com.mysql.jdbc.Driver");
*/
Connection conn = null;
//获取数据库连接对象
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/students", "root", "123");
} catch (SQLException e) {
e.printStackTrace();
}
//查询全部
Query query = new Query(conn);
//修改分数
UpdateScores update = new UpdateScores(conn);
//查询单一人员信息
QueryOne onePerson = new QueryOne(conn);
//主菜单
Menu menu = new Menu(query,update,onePerson);
//关闭连接
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
主界面
package cn.work.demo.Jdbc;
import java.util.Scanner;
public class Menu {
private boolean flag = true;
private Scanner scanner =null;
public Menu(Query query, UpdateScores update, QueryOne onePerson) {
System.out.println("nntttJDBC实验nn");
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" );
System.out.println("tttt1.查询全部人员信息n");
System.out.println("tttt2.修改分数男生-5女生 3n");
System.out.println("tttt3.查询某人信息n");
System.out.println("tttt4.退出n");
System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" );
scanner = new Scanner(System.in);
//菜单
do{
System.out.println("请输入要选择的数字:");
int command = scanner.nextInt();
switch (command){
case 1:
query.execute();
break;
case 2:
update.execute();
break;
case 3:
onePerson.execute();
break;
case 4:
flag=false;
break;
default:
System.out.println("输入错误请重新输入");
break;
}
}while (flag);
}
}
查询全部信息并打印在控制台
package cn.work.demo.Jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Query {
private Statement statement=null;
private Connection conn;
private ResultSet count=null;
public Query( Connection conn) {
this.conn = conn;
}
public void execute() {
try {
//定义查询SQL语句,语句不加分号
String sql = " select * from scores ";
//获取执行sql的对象,Connection里的方法返回Statement
statement = conn.createStatement();
//执行SQL,返回ResultSet
count = statement.executeQuery(sql);
//处理结果,打印在控制台
//先让光标移动一行,进入数据区域进行打印输出
while (count.next()) {
System.out.print(count.getInt(1) "-----");
System.out.print(count.getString(2) "-----");
System.out.print(count.getString(3) "-----");
System.out.println(count.getDouble(4));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放资源
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (count != null) {
try {
count.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
修改表中数据
package cn.work.demo.Jdbc;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class UpdateScores {
private Statement statement=null;
private Connection conn;
public UpdateScores(Connection conn) {
this.conn = conn;
}
public void execute() {
try {
//定义查询SQL语句
String sqlMen = "UPDATE scores SET score = score-5 WHERE sex='男'";
String sqlWonmen = "UPDATE scores SET score = score 3 WHERE sex='女'";
//创建一个 Statement 对象来将 SQL 语句发送到数据库
statement = conn.createStatement();
//执行SQL
statement.executeUpdate(sqlMen);
statement.executeUpdate(sqlWonmen);
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放资源
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
prepareStatement动态查询
package cn.work.demo.Jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class QueryOne {
//PreparedStatement动态参数
private PreparedStatement pstatement=null;
private Connection conn;
private ResultSet count=null;
private Scanner scanner;
public QueryOne(Connection conn) {
scanner = new Scanner(System.in);
this.conn = conn;
}
public void execute() {
try {
System.out.println("请输入要查询学号:");
int id = Integer.parseInt(scanner.next());
String sql = "SELECT * FROM scores WHERE id = ?";
//获取SQL执行的对象
pstatement = conn.prepareStatement(sql);
//传递动态参数
pstatement.setInt(1,id);
//执行SQL
count = pstatement.executeQuery();
if (count.next()){
System.out.print(count.getInt(1) "-----");
System.out.print(count.getString(2) "-----");
System.out.print(count.getString(3) "-----");
System.out.println(count.getDouble(4));
} else
System.out.println("学号未找到!!!");
} catch (SQLException e) {
e.printStackTrace();
} finally {
//释放资源
if (pstatement != null) {
try {
pstatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
数据库连接池
- 概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。 - 好处:
- 节约资源
- 用户访问高效
- 实现:
- 标准接口:DataSource javax.sql包下的
- 方法:
- 获取连接:getConnection()
- 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
- 方法:
- 一般我们不去实现它,有数据库厂商来实现
- C3P0:数据库连接池技术
- Druid:数据库连接池实现技术,由阿里巴巴提供的
- 标准接口:DataSource javax.sql包下的
- C3P0:数据库连接池技术
- 步骤:
- 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
- 不要忘记导入数据库驱动jar包
- 定义配置文件:
- 名称: c3p0.properties 或者 c3p0-config.xml
- 路径:直接将文件放在src目录下即可。
- 创建核心对象 数据库连接池对象 ComboPooledDataSource
- 获取连接: getConnection
- 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
- 代码:
//1.创建数据库连接池对象,不传参数则使用默认配置 DataSource ds = new ComboPooledDataSource(); //2. 获取连接对象 Connection conn = ds.getConnection();
- 步骤:
- Druid:数据库连接池实现技术,由阿里巴巴提供的
- 步骤:
- 导入jar包 druid-1.0.9.jar
- 定义配置文件:
- 是properties形式的
- 可以叫任意名称,可以放在任意目录下
- 加载配置文件。Properties
- 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
- 获取连接:getConnection
- 代码:
//3.加载配置文件 Properties pro = new Properties(); //当前类的资源路径,找到配置文件,返回字节输入流 InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); //加载 pro.load(is); //4.获取连接池对象 DataSource ds = DruidDataSourceFactory.createDataSource(pro); //5.获取连接 Connection conn = ds.getConnection();
- 定义工具类
- 定义一个类 JDBCUtils
- 提供静态代码块加载配置文件,初始化连接池对象
- 提供方法
- 获取连接方法:通过数据库连接池获取连接
- 释放资源
- 获取连接池的方法
- 代码:
```java
public class JDBCUtils { //1.定义成员变量 DataSource private static DataSource ds ; //静态代码块初始化 static{ try { //1.加载配置文件 Properties pro = new Properties(); pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); //2.获取DataSource ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接 */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } /** * 释放资源 */ public static void close(Statement stmt,Connection conn){ /* if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); } }*/ //调用下面方法,简化书写 close(null,stmt,conn); } public static void close(ResultSet rs , Statement stmt, Connection conn){ if(rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); } } } /** * 获取连接池方法 */ public static DataSource getDataSource(){ return ds; } } ```
- 步骤:
Spring JDBC
Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
- 步骤:
- 导入jar包
- 创建JdbcTemplate对象。依赖于数据源DataSource
- JdbcTemplate template = new JdbcTemplate(ds);
- 调用JdbcTemplate的方法来完成CRUD的操作
- update():执行DML语句。增、删、改语句
- queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
- 注意:这个方法查询的结果集长度只能是1
- queryForList():查询结果将结果集封装为list集合
- 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
- query():查询结果,将结果封装为JavaBean对象
- query的参数:RowMapper
- 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
- new BeanPropertyRowMapper (类型.class)
- query的参数:RowMapper
- queryForObject:查询结果,将结果封装为对象
- 一般用于聚合函数的查询
- 练习:
- 需求:
- 修改1号数据的 salary 为 10000
- 添加一条记录
- 删除刚才添加的记录
- 查询id为1的记录,将其封装为Map集合
- 查询所有记录,将其封装为List
- 查询所有记录,将其封装为Emp对象的List集合
- 查询总记录数
-
代码:
import cn.itcast.domain.Emp; import cn.itcast.utils.JDBCUtils; import org.junit.Test; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; public class JdbcTemplateDemo2 { //Junit单元测试,可以让方法独立执行 //1. 获取JDBCTemplate对象 private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); /** * 1. 修改1号数据的 salary 为 10000 */ @Test public void test1(){ //2. 定义sql String sql = "update emp set salary = 10000 where id = 1001"; //3. 执行sql int count = template.update(sql); System.out.println(count); } /** * 2. 添加一条记录 */ @Test public void test2(){ String sql = "insert into emp(id,ename,dept_id) values(?,?,?)"; int count = template.update(sql, 1015, "郭靖", 10); System.out.println(count); } /** * 3.删除刚才添加的记录 */ @Test public void test3(){ String sql = "delete from emp where id = ?"; int count = template.update(sql, 1015); System.out.println(count); } /** * 4.查询id为1001的记录,将其封装为Map集合 * 注意:这个方法查询的结果集长度只能是1 */ @Test public void test4(){ String sql = "select * from emp where id = ? or id = ?"; Map<String, Object> map = template.queryForMap(sql, 1001,1002); System.out.println(map); //{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20} } /** * 5. 查询所有记录,将其封装为List */ @Test public void test5(){ String sql = "select * from emp"; List<Map<String, Object>> list = template.queryForList(sql); for (Map<String, Object> stringObjectMap : list) { System.out.println(stringObjectMap); } } /** * 6. 查询所有记录,将其封装为Emp对象的List集合 */ @Test public void test6(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new RowMapper<Emp>() { @Override public Emp mapRow(ResultSet rs, int i) throws SQLException { Emp emp = new Emp(); int id = rs.getInt("id"); String ename = rs.getString("ename"); int job_id = rs.getInt("job_id"); int mgr = rs.getInt("mgr"); Date joindate = rs.getDate("joindate"); double salary = rs.getDouble("salary"); double bonus = rs.getDouble("bonus"); int dept_id = rs.getInt("dept_id"); emp.setId(id); emp.setEname(ename); emp.setJob_id(job_id); emp.setMgr(mgr); emp.setJoindate(joindate); emp.setSalary(salary); emp.setBonus(bonus); emp.setDept_id(dept_id); return emp; } }); for (Emp emp : list) { System.out.println(emp); } } /** * 6. 查询所有记录,将其封装为Emp对象的List集合 */ @Test public void test6_2(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class)); for (Emp emp : list) { System.out.println(emp); } } /** * 7. 查询总记录数 */ @Test public void test7(){ String sql = "select count(id) from emp"; Long total = template.queryForObject(sql, Long.class); System.out.println(total); } }
- 需求: