1.基本概念
Java DataBase Connectivity:Java数据库连接
本质:定义了一套操作所有关系型数据库的规则,即接口
2.快速入门
导入驱动jar包
MySQL连接数据库mysql-connector-8.0 jar包使用注意:
https://blog.csdn.net/qq_37137348/article/details/83790382
public class JDBCDemo01 {
public static void main(String[] args) throws Exception {
//导入驱动jar包
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取数据库连接对象
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/myemployees?userSSL=false&serverTimezone=UTC", "root", "123456");
//定义一个sql语句
String sql="update employees set salary=25000 where employee_id=100";
//获取执行sql的对象Statement
Statement statement = con.createStatement();
//执行sql
int count = statement.executeUpdate(sql);
//处理结果
System.out.println(count);
//释放资源
statement.close();
con.close();
}
}
DriverManager:驱动管理对象
功能:
1.注册驱动
告诉程序该适用哪一个数据库驱动jar
static void registerDriver(Driver driver):注册与给定的驱动程序DriveManager
2.获取数据库连接
static Connection getConnection(String url,String user,String password)
url:指定连接的路径
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
Connection:数据库连接对象
功能:
1.获取执行sql对象
2.管理事务
开启事务:setAutoCommit(boolean,autoCommit),调用该方法设置参数为false即开启事务
提交事务:commit()
回滚事务:rollback()
Statement:
用于执行静态sql并返回其生成的结果的对象
boolean execute(String sql):执行任意sql
int executeUpdate(String sql):执行DML(insert,update,delete)语句,返回影响的行数
ResultSet executeQuery(String ,sql):执行DQL(select)语句,结果集对象,封装查询结果
public class JDBCDemo02 {
public static void main(String[] args) {
Statement statement=null;
Connection connection=null;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//定义sql
String sql="insert into departments values(null,'Los',null,1700)";
//获取Connection对象
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myemployees?userSSL=false&serverTimezone=UTC", "root", "199824");
//获取sql对象statement
statement = connection.createStatement();
//执行sql
int count = statement.executeUpdate(sql);
//处理结果
if(count>0){
System.out.println("添加成功");
}else{
System.out.println("添加失败");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
//避免空指针异常
if (statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
其他sql语句类似,修改sql内容即可
Result:
ResultSet:结果集对象,封装查询结果
boolean next():游标向下移动一行
getXxx(参数):获取数据
Xxx代表数据类型
参数,int代表列号(从1开始),String代表列名称
public class JDBCDemo03 {
public static void main(String[] args) {
Statement statement=null;
Connection connection=null;
ResultSet res=null;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//定义sql
String sql="select * from departments where department_id<=100";
//获取Connection对象
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myemployees?userSSL=false&serverTimezone=UTC", "root", "199824");
//获取sql对象statement
statement = connection.createStatement();
//执行sql
res = statement.executeQuery(sql);
//获取数据
//让游标向下移动
res.next();
int id=res.getInt(1);
String name=res.getString("department_name");
int m_id=res.getInt(3);
int l_id=res.getInt("location_id");
System.out.println(id+","+name+","+m_id+","+l_id);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
//避免空指针异常
if (statement!=null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (res!=null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
注意:
使用步骤:游标向下移动一行,判断是否有数据,再获取数据
循环判断打印结果
while(res.next()){
int id=res.getInt(1);
String name=res.getString("department_name");
int m_id=res.getInt(3);
int l_id=res.getInt("location_id");
System.out.println(id+","+name+","+m_id+","+l_id);
}
JDBC工具类
目的:简化书写
分析:
1.抽取注册驱动
2.抽取方法连接对象。需求:不想传递参数,保证工具类的通用性
解决:配置文件
3.抽取方法释放资源
public class JDBCUtils {
//获取连接,return连接对象。采用配置文件,使用静态代码块读取文件
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 = JDBCUtils.class.getClassLoader();
URL resource = classLoader.getResource("jdbc.properties");
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 e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
//释放资源
public static void close(Statement stmt,Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//释放资源重载形式
public static void close(ResultSet res,Statement stmt,Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(res!=null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
PreparedStatement:
1.sql注入问题
在拼接sql时有一些sql的特殊关键字参与到字符串的拼接,会造成安全性问题
2.解决sql注入
使用PreparedStatement对象
3.预编译sql
参数使用?作为占位符
4。步骤
定义sql时,sql的参数使用?作为占位符
获取执行sql语句的对象 PreparedStatement ,Connection.prepareStatement(String sql)
执行sql,给?赋值。方法:setXxx(参数1,参数2)
参数1位位置,参数2为?的值
后期均会使用PreparedStatement完成增删改查所有操作
可以防止sql注入,效率更高
JDBC控制事务
操作:
开启事务:setAutoCommit(boolean,autoCommit),调用该方法设置参数为false即开启事务
提交事务:commit()
回滚事务:rollback()
3.数据库连接池
概念
其实就是一个容器,存放数据库连接的容器
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完后,会将连接对象归还给容器
优点:
节约系统资源
用户访问高效
实现
1.标准接口:DataSource,方法:获取连接,getConnection()
2.由数据库厂商实现,C3P0,Druid
C3P0
1.基本使用
<?xml version="1.0" encoding="utf-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/myemployees?&useSSL=false&serverTimezone=UTC</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
<property name="checkoutTimeout">3000</property>
</default-config>
<named-config name="otherc3p0">
</named-config>
</c3p0-config>
注意修改配置文件信息jdbcUrl,如果使用mysqlconnector8要按照如上修改
public class C3P0Demo1 {
public static void main(String[] args) throws SQLException {
//导入jar包与配置文件
//创建数据库连接池对象
DataSource ds=new ComboPooledDataSource();
//获取连接对象
Connection connection=ds.getConnection();
//打印连接对象
System.out.println(connection);
}
}
Druid
1.基本使用
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/myemployees?useSSL=false&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT&allowPublicKeyRetrieval=true
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
minIdle=3
validationQuery:SELECT 1
testWhileIdle:true
testOnBorrow:false
testOnReturn:false
注意url信息,具体见:https://www.cnblogs.com/mjn1/p/11197753.html
public class DruidDemo1 {
public static void main(String[] args) throws Exception {
//导入jar包
//定义配置文件
//加载配置文件
Properties pro=new Properties();
InputStream resourceAsStream = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(resourceAsStream);
//获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
Connection connection = ds.getConnection();
System.out.println(connection);
}
}
2.工具类
public class JDBCUtils {
//定义成员变量
private static DataSource ds;
static{
//加载配置文件
Properties pro=new Properties();
try {
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//获取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 connection){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//重载形式释放资源
public static void close(ResultSet res,Statement stmt, Connection connection){
if(res!=null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static DataSource getDataSourece(){
return ds;
}
}
4.JDBCTemplate
1.基本入门
public class JDBCTemplateDemo1 {
public static void main(String[] args) {
//导入jar包
//创建JDBCTemplate对象
JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSourece());
//调用方法
String sql="update employees set salary=? where employee_id=?";
int count = template.update(sql, 30000, 100);
System.out.println(count);
}
}
2.JDBCTemplate方法
update():执行DML语句,增删改
queryForMap():查询结果将结果封装为map集合
queryForList():查询结果将结果封装为list集合
query():查询结果将结果封装为JavaBean对象
queryForObject():查询结果将结果封装为对象
public class JDBCTemplateDemo1 {
//创建JDBCTemplate对象
private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSourece());
@Test
public void test1(){
//queryForMap():查询结果将结果封装为map集合
String sql="select * from departments where department_id=?";
Map<String, Object> map = template.queryForMap(sql, 100);
System.out.println(map);
}
@Test
public void test2(){
//queryForList():查询结果将结果封装为list集合
String sql="select * from departments where department_id<=?";
List<Map<String, Object>> list = template.queryForList(sql, 100);
for (Map<String, Object> dp : list) {
for (Map.Entry<String, Object> entry : dp.entrySet()) {
System.out.print(entry.getKey()+":"+entry.getValue()+"\t");
}
System.out.println();
}
}
@Test
public void test3(){
//query():查询结果将结果封装为JavaBean对象(实际情况)
String sql="select * from departments where department_id<=?";
List<Department> list = template.query(sql, new RowMapper<Department>() {
@Override
public Department mapRow(ResultSet rs, int i) throws SQLException {
int id = rs.getInt("department_id");
String name = rs.getString("department_name");
int m_id = rs.getInt("manager_id");
int l_id = rs.getInt("location_id");
Department dpt = new Department(id, name, m_id, l_id);
return dpt;
}
},100);
for (Department dpt : list) {
System.out.println(dpt);
}
}
@Test
public void test4(){
/*
一般我们使用BeanPropertyRowMapper实现类
可以完成数据到JavaBean的自动封装
new BeanPropertyRowMapper<类型>(类型.class)
*/
String sql="select * from departments where department_id<=?";
List<Department> list = template.query(sql, new BeanPropertyRowMapper<>(Department.class),100);
for (Department dpt : list) {
System.out.println(dpt);
}
}
@Test
public void test5(){
//queryForObject():查询结果将结果封装为对象
String sql="select count(department_id) from departments where department_id<=?";
Long total=template.queryForObject(sql, Long.class,100);
System.out.println(total);
}
}