文章目录
- 创建依赖
- 基本步骤
- 案例
- 1. statement案例(不常用):
- 2.prepared 案例(常用)
- 3.prepared curd 案例(获取列信息)
- 5.事务一致性(转账)
创建依赖
各个版本有各个的依赖包,想MySQL8.0 和MySQL5.0 应该下载对应的依赖包
在idea项目当中创建文件夹libs来放相关的依赖,将依赖放进去后,右击,增加到此项目当中(如图一),加载完成之后会有三角形的这个依赖包可以打开,如图二所示:
图一:
图二:
基本步骤
* TODO: 步骤总结 (6步)* 1. 注册驱动* 2. 获取连接* 3. 创建statement或者Prepared* 4. 发送SQL语句,并获取结果* 5. 结果集解析* 6. 关闭资源
1.注册驱动
// 方法1:
DriverManager.registerDriver(new Driver());// 这个驱动会创建两次
//方法2:利用反射机制-推荐
Class.forName("com.mysql.cj.jdbc.Driver");
2.获取链接
获取链接的有三个参数的,两个参数的,一个参数的。接下来一个一个介绍
// 三个参数
public static Connection getConnection(String url,String user, String password)
//两个参数
public static Connection getConnection(String url,java.util.Properties info)
// 一个参数
public static Connection getConnection(String url)
三个参数的:
/**
这里有三个参数,具体在这里详细描述【】——》带这个的是你需要里面需要填的东西。
第一个参数:(String URL: 连接数据库地址) 连接数据库地址模仿下列的写法 jbdc:【数据库名】://【域名或ip地址】:【端口号】/【数据库名】
其实还可以有其他的参数:
第二个参数:(String user: 连接数据库用户名)
第三个参数:连接数据库用户对应的密码
*/
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","root");
数据库URL语法:
(1)链接Oracle数据库 ip 127.0.0.1 端口号:3306 数据库名:db
jdbc:oracle :// 127.0.0.1 : 3306 / db(2)链接Mysql数据库 ip 本机 端口号:3306 数据库名:day01
jdbc:mysql://localhost:3306/day01(3) 当前电脑的省略写法! 注意:本机和端口3306jdbc:mysql://localhost:3306/day01相当于jdbc:mysql:///day01
两个参数的:
String URL : 写法还是jdbc的三个参数的写法!
Properties : 就是一个参数封装容器!至少要包含 user / password key!存储连接账号信息!(就是properties配置文件需要自己写)
一个参数的:
String URL: URl可以携带目标地址,可以通过?分割,在后面key=value&key=value形式传递参数
jdbc:mysql:///day01?user=root&password=123456
- 创建statement/prepared
他们的区别就在于statement,只能给字符串,可以形成SQL注入,而prepared可以给一个方法传入参数,则可以防止注入。
1.statement:
Statement statement = connection.createStatement();
2.prepared
//创建preparedStatement//TODO 需要传入SQL语句结构//TODO 要的是SQL语句结构,动态值的部分使用 ? , 占位符!//TODO ? 不能加 '?' ? 只能替代值,不能替代关键字和容器名
String sql = "select * from t_user where account = ? and password = ? ;";
PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符赋值//给占位符赋值! 从左到右,从1开始!/**
* int 占位符的下角标
* object 占位符的值
*/
preparedStatement.setObject(2,password);preparedStatement.setObject(1,account);
- 发送SQL语句,并获取结果
1.statement 获取
/**
这里举例:写了一个sql 语句
*/
String sql = "select id,account,password,nickname from t_user ;";ResultSet resultSet = statement.executeQuery(sql);
- prepared的获取(方法一样)
ResultSet resultSet = preparedStatement.executeQuery();
resultSet的返回值:
ResultSet 结果集对象 = executeQuery(DQL语句)
int 响应行数 = executeUpdate(非DQL语句)
5.结果集解析
/**** TODO:1.需要理解ResultSet的数据结构和mysql可视化工具查询出来的是一样,需要在脑子里构建结果表!* TODO:2.有一个光标指向的操作数据行,默认指向第一行的上边!我们需要移动光标,指向行,在获取列即可!* boolean = next()* false: 没有数据,也不移动了!* true: 有更多行,并且移动到下一行!* 推荐:推荐使用if 或者 while循环,嵌套next方法,循环和判断体内获取数据!* if(next()){获取列的数据!} || while(next()){获取列的数据!}**TODO:3.获取当前行列的数据!* get类型(int columnIndex | String columnLabel)* 列名获取 //lable 如果没有别名,等于列名, 有别名label就是别名,他就是查询结果的标识!* 列的角标 //从左到右 从1开始! 数据库全是从1开始!*/
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. statement案例(不常用):
public class test {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1.注册一次驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///my_project", "root", "Thm123456!");//3.创建statementStatement statement = connection.createStatement();//4.执行SQL语句 [动态SQL语句,需要字符串拼接]
// String sql = "select * from t_user where account = '"+account+"' and password = '"+password+"' ;";String sql = "SELECT * FROM my_work ;";ResultSet resultSet = statement.executeQuery(sql);// 5.使用数据while (resultSet.next()){System.out.println(resultSet.getString(1)); // 打印第一竖的数据}//关闭资源resultSet.close();statement.close();connection.close();}}
2.prepared 案例(常用)
public class testPrepared {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1.注册一次驱动Class.forName("com.mysql.cj.jdbc.Driver");//2.获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///my_project", "root", "Thm123456!");//3.创建preparedString sql = "SELECT * FROM my_work WHERE password = ?;"; //sql 语句PreparedStatement preparedStatement = connection.prepareStatement(sql); // 准备prepared解析SQL语句preparedStatement.setObject(1,"ccc"); // 第1个参数传入ccc//4.执行SQL语句 [动态SQL语句,需要字符串拼接]ResultSet resultSet = preparedStatement.executeQuery();// 5.使用数据while (resultSet.next()){System.out.println(resultSet.getString(1)); // 打印第一竖的数据System.out.println("name:" + resultSet.getString("name")); // 通过 名称查找 获取当前行的数据System.out.println("password:" + resultSet.getString("password")); }//关闭资源resultSet.close();preparedStatement.close();connection.close();}}
3.prepared curd 案例(获取列信息)
public class JdbcPreparedStatementCrudPart {/*** 插入一条用户数据!* 账号: test* 密码: test* 昵称: 测试*/@Testpublic void testInsert() throws Exception{//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///db", "root", "root");//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名String sql = "insert into t_user(account,password,nickname) values (?,?,?);";PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符赋值preparedStatement.setString(1, "test");preparedStatement.setString(2, "test");preparedStatement.setString(3, "测试");//发送SQL语句int rows = preparedStatement.executeUpdate();//输出结果System.out.println(rows);//关闭资源closepreparedStatement.close();connection.close();}/*** 修改一条用户数据!* 修改账号: test的用户,将nickname改为tomcat*/@Testpublic void testUpdate() throws Exception{//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///db", "root", "root");//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名String sql = "update t_user set nickname = ? where account = ? ;";PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符赋值preparedStatement.setString(1, "tomcat");preparedStatement.setString(2, "test");//发送SQL语句int rows = preparedStatement.executeUpdate();//输出结果System.out.println(rows);//关闭资源closepreparedStatement.close();connection.close();}/*** 删除一条用户数据!* 根据账号: test*/@Testpublic void testDelete() throws Exception{//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///db", "root", "root");//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名String sql = "delete from t_user where account = ? ;";PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符赋值preparedStatement.setString(1, "test");//发送SQL语句int rows = preparedStatement.executeUpdate();//输出结果System.out.println(rows);//关闭资源closepreparedStatement.close();connection.close();}/*** 查询全部数据!* 将数据存到List<Map>中* map -> 对应一行数据* map key -> 数据库列名或者别名* map value -> 数据库列的值* TODO: 思路分析* 1.先创建一个List<Map>集合* 2.遍历resultSet对象的行数据* 3.将每一行数据存储到一个map对象中!* 4.将对象存到List<Map>中* 5.最终返回** TODO:* 初体验,结果存储!* 学习获取结果表头信息(列名和数量等信息)*/@Testpublic void testQueryMap() throws Exception{//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///db", "root", "root");//TODO: 切记, ? 只能代替 值!!!!! 不能代替关键字 特殊符号 容器名String sql = "select id,account,password,nickname from t_user ;";PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符赋值 本次没有占位符,省略//发送查询语句ResultSet resultSet = preparedStatement.executeQuery();//创建一个集合List<Map> mapList = new ArrayList<>();//获取列信息对象ResultSetMetaData metaData = resultSet.getMetaData();int columnCount = metaData.getColumnCount();while (resultSet.next()) {Map map = new HashMap();for (int i = 1; i <= columnCount; i++) {map.put(metaData.getColumnLabel(i), resultSet.getObject(i));}mapList.add(map);}System.out.println(mapList);//关闭资源closepreparedStatement.close();connection.close();resultSet.close();}}
5.事务一致性(转账)
利用
try ...catch..finally
开启事务(关闭事务自动提交)
connection.setAutoCommit(false);
提交事务
connection.commit();
回滚事务
connection.rollback();
等操作,实现事务的一致性
BankDao 类(是用传入参数 用来加钱减钱的操作)
public class BankDao {/*** 加钱方法* @param account* @param money* @param connection 业务传递的connection和减钱是同一个! 才可以在一个事务中!* @return 影响行数*/public int addMoney(String account, int money,Connection connection) throws ClassNotFoundException, SQLException {String sql = "update t_bank set money = money + ? where account = ? ;";PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符赋值preparedStatement.setObject(1, money);preparedStatement.setString(2, account);//发送SQL语句int rows = preparedStatement.executeUpdate();//输出结果System.out.println("加钱执行完毕!");//关闭资源closepreparedStatement.close();return rows;}/*** 减钱方法* @param account* @param money* @param connection 业务传递的connection和加钱是同一个! 才可以在一个事务中!* @return 影响行数*/public int subMoney(String account, int money,Connection connection) throws ClassNotFoundException, SQLException {String sql = "update t_bank set money = money - ? where account = ? ;";PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符赋值preparedStatement.setObject(1, money);preparedStatement.setString(2, account);//发送SQL语句int rows = preparedStatement.executeUpdate();//输出结果System.out.println("减钱执行完毕!");//关闭资源closepreparedStatement.close();return rows;}
}
BankService类(这里注册了驱动,建立了数据库的链接,然后用了try catch 保持事务的一致性,在关闭了资源)
public class BankService {/*** 转账业务方法* @param addAccount 加钱账号* @param subAccount 减钱账号* @param money 金额*/public void transfer(String addAccount,String subAccount, int money) throws ClassNotFoundException, SQLException {System.out.println("addAccount = " + addAccount + ", subAccount = " + subAccount + ", money = " + money);//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接Connection connection = DriverManager.getConnection("jdbc:mysql:///db", "root", "root");int flag = 0;//利用try代码块,调用daotry {//开启事务(关闭事务自动提交)connection.setAutoCommit(false);BankDao bankDao = new BankDao();//调用加钱 和 减钱bankDao.addMoney(addAccount,money,connection);System.out.println("--------------");bankDao.subMoney(subAccount,money,connection);flag = 1;//不报错,提交事务connection.commit();}catch (Exception e){//报错回滚事务connection.rollback();throw e;}finally {connection.close();}if (flag == 1){System.out.println("转账成功!");}else{System.out.println("转账失败!");}}}