本文重在展示jdbc、druid、jdbcTemplate三种方式操作数据库(Mysql)。
搭配其他文章与自己实际操作为佳。如有错误还请指正
jdbc是java语言操作数据库,即对数据库数据做增删查改操作,事务操作等。
1. 导入jar包
mysql-connector-java-5.1.37-bin.jar
2. 注册驱动
3. 获取数据库连接对象 Connection
4. 定义sql
5. 获取执行sql语句的对象 Statement
6. 执行sql,接收返回结果
7. 释放资源
//1. 导入驱动jar包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/One", "root", "pass");
//4.定义sql语句
String sql = "update account set balance = 500 where id = 1";
//5.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//6.执行sql
int count = stmt.executeUpdate(sql);
//7.处理结果
System.out.println(count);
//8.释放资源
stmt.close();
conn.close();
1. DriverManager:驱动管理对象
* 功能:
1. 注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManager 。
写代码使用: Class.forName("com.mysql.jdbc.Driver");
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
2. 获取数据库连接:
* 方法:static Connection getConnection(String url, String user, String password)
* 参数:
url:指定连接的路径
* 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
* 例子:jdbc:mysql://localhost:3306/db3
* 细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称
user:用户名
password:密码
2. Connection:数据库连接对象
1. 功能:
1. 获取执行sql 的对象
* Statement createStatement()
* PreparedStatement prepareStatement(String sql)
2. 管理事务:
* 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
* 提交事务:commit()
* 回滚事务:rollback()
3. Statement:执行sql的对象
1. 执行sql
1. boolean execute(String sql) :可以执行任意的sql 了解
2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
* 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
3. ResultSet executeQuery(String sql) :执行DQL(select)语句
4. ResultSet:结果集对象,封装查询结果
* boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
* getXxx(参数):获取数据
* Xxx:代表数据类型 如: int getInt() , String getString()
* 参数:
1. int:代表列的编号,从1开始 如: getString(1)
2. String:代表列名称。 如: getDouble("balance")
* 注意:
* 使用步骤:
1. 游标向下移动一行
2. 判断是否有数据
3. 获取数据
5. PreparedStatement:执行sql的对象
1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
1. 输入用户随便,输入密码:a' or 'a' = 'a
2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
2. 解决sql注入问题:使用PreparedStatement对象来解决
3. 预编译的SQL:参数使用?作为占位符
4. 步骤:
1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
2. 注册驱动
3. 获取数据库连接对象 Connection
4. 定义sql
* 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;
5. 获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)
6. 给?赋值:
* 方法: setXxx(参数1,参数2)
* 参数1:?的位置编号 从1 开始
* 参数2:?的值
如:pstmt.setString(1,"username");
7. 执行sql,接受返回结果,不需要传递sql语句
8. 处理结果
9. 释放资源
5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
1. 可以防止SQL注入
2. 效率更高
查看jdbc库中的user表数据:
//导包
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC","root","pass");
//定义sql
String sql = "select id,name from user";
//获取sql的执行对象Statement
Statement stmt = conn.createStatement();
//执行sql
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
String id = rs.getString("id");
String name = rs.getString("name");
System.out.println(id + " - " + name);
}
//关闭连接
rs.close();
stmt.close();
conn.close();
往jdbc库中的user表插入数据如“XXX”,“123”:
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
//插入数据
String sql = "insert into user values('XXX','123')";
//更新数据
//String sql = "update user set name = '456' where id = 'XXX'";
//删除数据
//String sql = "delete from user where id = 'XXX'";
Statement stmt = conn.createStatement();
int i = stmt.executeUpdate(sql);
System.out.println(i);
stmt.close();
conn.close();
修改jdbc库中user表的id = “XXX”对应的name为“456”:增删改的执行操作都是executeUpdate(),区别在sql语句而已,返回的是修改行数;
而查的执行操作是executeQuery(),返回的是一个结果集resultSet
使用Connection对象来管理事务
开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
在执行sql之前开启事务
提交事务:commit() 当所有sql都执行完提交事务
回滚事务:rollback() 在catch中回滚事务
/**
* aaa向bbb转账
*/
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
//开启事务
conn.setAutoCommit(false);
String sql1 = "update balance set balance = ? where username = ?";
String sql2 = "update balance set balance = ? where username = ?";
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
pstmt1.setInt(1,500);
pstmt1.setString(2,"aaa");
pstmt2.setInt(1,1500);
pstmt2.setString(2,"bbb");
pstmt1.executeUpdate();
pstmt2.executeUpdate();
} catch (ClassNotFoundException | SQLException e) {
try {
//回滚事务
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
try {
//提交事务
conn.commit();
pstmt1.close();
pstmt2.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
druid数据库连接池,避免了jdbc频繁创建关闭连接的过程。
//导包:druid-1.2.5.jar 、mysql-connector-java-8.0.22.jar
//定义配置
//加载配置
Properties properties = new Properties();
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//获取数据库连接池
dataSource = DruidDataSourceFactory.createDataSource(properties);
//获取连接
conn = dataSource.getConnection();
//往下与jdbc一样
读取jdbc库中balance表的数据:
public static DataSource dataSource;
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
//定义配置
Properties properties = new Properties();
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
//加载配置
properties.load(is);
//创建数据库连接池
dataSource = DruidDataSourceFactory.createDataSource(properties);
//获取连接
conn = dataSource.getConnection();
//定义sql
String sql = "select username,balance from balance";
//获取执行对象
pstmt = conn.prepareStatement(sql);
//获取结果集
rs = pstmt.executeQuery();
while(rs.next()){
String username = rs.getString("username");
String balance = rs.getString("balance");
System.out.println(username + " " + balance);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
往jdbc库中的balance表插入数据行”ddd“,1000:
private static DataSource dataSource;
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
try{
Properties pro = new Properties();
InputStream is = DruidDemo2.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
dataSource = DruidDataSourceFactory.createDataSource(pro);
conn = dataSource.getConnection();
String sql = "insert into balance values(?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1,"ddd");
ps.setInt(2,1000);
int i = ps.executeUpdate();
System.out.println(i);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
ps.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
增删查改跟jdbc大同小异,其思想就是对数据库连接的池化。
跟jdbc操作事务基本相似。
//导包
commons-logging-1.2.jar
spring-beans-5.0.0.RELEASE.jar
spring-core-5.0.0.RELEASE.jar
spring-jdbc-5.0.0.RELEASE.jar
spring-tx-5.0.0.RELEASE.jar
使用jdbcTemplate查询数据库数据:
private static DataSource dataSource;
public static void main(String[] args) {
try{
//定义配置
Properties pro = new Properties();
InputStream is = JdbcTemplate1.class.getClassLoader().getResourceAsStream("druid.properties");
//加载配置
pro.load(is);
//创建数据池连接
dataSource = DruidDataSourceFactory.createDataSource(pro);
//创建jdbcTemplate实例对象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "select * from balance";
//获取结果集
List
使用jdbcTemplate增删改数据:
private static DataSource dataSource;
public static void main(String[] args) {
try{
Properties pro = new Properties();
InputStream is = JdbcTemplate2.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
dataSource = DruidDataSourceFactory.createDataSource(pro);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "insert into balance values(?,?)";
int update = jdbcTemplate.update(sql,"eee",1000);
//String sql = "update balance set balance = ? where username = ?";
//int update = jdbcTemplate.update(sql, 100, "eee");
//String sql = "delete from balance where username = ?";
//int update = jdbcTemplate.update(sql, "eee");
System.out.println(update);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
不需要手动关闭连接。