JDBC:Java DataBase Connectivity
Java数据库连接,Java语言操作数据库
JDBC本质:其实是官方(SUN公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
步骤:
public static void main(String[] args){
Connection conn = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取Connection对象
conn = DriverManager.getConnection("jdbc:mysql://db.mysqltest.mijiaoyu.cn:3306/edu_teachingplan4", "root", "Dxmmysql20A20!@#");
// sql语句
String sql = "select * from tp_interveneobject limit 10";
// 获取执行sql对象Statement
statement = conn.createStatement();
// 执行sql
resultSet = statement.executeQuery(sql);
// 处理sql
while (resultSet.next()) {
System.out.println(resultSet.getInt("code"));
System.out.println(resultSet.getString("name"));
};
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
// 释放资源
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
2. 获取数据库连接
方法:static Connection getConnection(String url, String user, String password)
参数:
1. url:语法:jdbc:mysql:// ip地址(域名):端口号/数据库名称
例子:jdbc:mysql://localhost:3306/db3
细节:如果链接的是本机的mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql///数据库名称
2. user:用户名
3. password:密码
Connection:数据库连接对象
功能:
1. 获取执行sql的对象
Statement createStatement();
PreparedStatement prepareStatement(String sql);
2. 管理事务
开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
提交事务:conmmit();
回滚事务:rollback();
Statement:执行sql的对象
功能:
1. 执行sql
1. boolean execute(String sql):可以执行任意的sql
2. int executeUpdate(String sql):执行的是DML(增删改)语句、DDL(create/alter/drop)语句
返回值: 影响的行数,可以通过影响的行数判断DML语句是否执行成功
3. ResultSet executeQuery(String sql):执行DQL(select)语句
ResultSet:结果集对象,封装查询结果
1. boolean next():游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是返回false,如果不是则返回true(true有数据,false没有数据)
2. getXxx(参数):获取数据
Xxx:代表数据类型 如:getInt()、getString()
参数:
1. int:代表列的编号,从1开始。 如:getString(1)
2. String:代表列名称。如:getDouble("balance")
注意:
使用步骤:
1. 游标向下移动一行
2. 判断是否有数据
3. 获取数据
PreparedStatement:执行sql的对象
1. sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全问题
1. 输入用户名,输入密码:a' or 'a' = 'a
2. sql:select * from user where username = 'zhangsan' and password = 'a' or 'a' = 'a';
2. 解决sql注入问题:使用PreparedStatement对象来解决
3. 预编译的sql:参数使用?作为占位符
4. 步骤:
1. 导入驱动jar包
2. 注册驱动
3. 获取数据库连接对象 Connection
4. 定义sql
注意:sql的参数使用?作为占位符。如:select * from user where username = ? and password = ?;
5. 获取执行sql语句的对象PreparedStatement Connection.preparedStatement(String sql)
6. 给参数?赋值
方法:setXxx(参数1, 参数2)
参数1:?的位置编号 从1开始
参数2:?的值
7. 执行sql,接收返回结果,不需要传递sql语句
8. 处理结果
9. 释放资源
5. 注意:后期都会使用 PreparedStatement来完成增删改查的所有操作
1. 可以防止sql注入
2. 效率更高
// JDBC工具类
public class JdbcUtil {
private static String url;
private static String user;
private static String password;
private static String driver;
static {
try {
// 创建Properties集合类对象
Properties pro = new Properties();
// 获取src路径下文件的方式-->ClassLoader类加载器
ClassLoader classLoader = JdbcUtil.class.getClassLoader();
// 获取URL资源定位符对象
URL resource = classLoader.getResource("jdbc.properties");
if (resource != null) {
// 获取文件绝对路径
String path = resource.getPath();
// 加载文件
pro.load(new FileReader(path));
}
// 获取数据并赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
// 获取Connection对象
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
// 释放资源
public static void close(PreparedStatement ps, Connection conn) {
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
// 登录案例
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = sc.next();
System.out.println("请输入密码:");
String password = sc.next();
boolean flag = login(user, password);
if (flag) {
System.out.println("登录成功!");
} else {
System.out.println("用户名或密码错误!");
}
}
public static boolean login(String user, String password) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
if (user == null || password == null) {
return false;
}
try {
conn = JdbcUtil.getConnection();
String sql = "select * from user where username = ? and password = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, user);
ps.setString(2, password);
resultSet = ps.executeQuery();
return resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(resultSet, ps, conn);
}
return false;
}
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务(执行sql前开启事务)
提交事务:conmmit();(执行完所有sql提交事务)
回滚事务:rollback();(在catch中回滚事务)
其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完后,会将连接对象归还给容器
C3P0:数据库连接池技术
步骤:
1. 导入jar包(两个)c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,不要忘记导入数据库驱动jar包
2. 定义配置文件
1. 名称:c3p0.properties或者c3p0-config.xml
2. 路径:直接将文件放在src目录下即可
3. 创建核心对象,数据库连接池对象 ComboPooledDataSource
4. 获取连接:getConnection
Druid:数据库连接池实现技术,由阿里巴巴提供
// druid.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/python
username=root
password=xxxxx
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
1. 步骤:
a. 导入jar包 druid-1.0.9.jar
b. 定义配置文件
1. 是properties形式的
2. 可以叫任意名称,可以放在任意目录下
c. 获取数据库连接池对象:通过工厂类来获取:DruidDataSourceFactory
d. 获取连接:getConnection
2. 定义工具类
a. 定义一个类 JDBCUtils
b. 提供静态代码块加载配置文件,初始化连接池对象
c. 提供方法
1. 获取连接方法:通过数据库连接池获取连接
2. 释放资源
3. 获取连接池的方法
// Druid工具类
public class JDBCUtils {
// 定义成员变量DataSource
private static DataSource ds;
static {
try {
// 加载配置文件
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
// 获取DataSource
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
// 释放资源
public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 获取连接池方法
public static DataSource getDataSource() {
return ds;
}
}