JDBC
- 用java操作数据库
- Java DataBase Connectivity
- 官方定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包,我们可以使用这套接口
JDBC编程,真正执行的代码是驱动jar包中的实现类
- 执行sql语句
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver")
//获取数据库的连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbtest3", "root", "123456789")
//定义sql语句
String sql = "update commpany set age = 30 where id = 2"
//获取执行sql对象
Statement statement = connection.createStatement()
//执行sql
int count = statement.executeUpdate(sql)
System.out.println(count)
//释放资源
statement.close()
connection.close()
public static void main(String[] args){
Statement statement = null;
Connection connection = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbtest3", "root", "123456789");
String sql = "select * from commpany;";
resultSet = statement.executeQuery(sql);
.....
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
各类对象
DrivaerManager
- 驱动管理,注册驱动,获取数据库连接
- 现在的版本可以省略注册驱动的步骤
- 静态代码块,注册驱动时,直接运行
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
getConnection的第一个参数执行数据库格式jdbc:mysql://ip地址(域名):端口号/数据库
- 如果连接的是本机的msq服务器,并且mysql的端口为3306,则可以简写为
jdbc:mysql:///数据库
Connection
connection.setAutoCommit(false);
connection.commit();
connection.rollback();
Statement
//执行任意的sql
boolean res = statement.execute(sql);
//执行sql 执行DML增删改语句 (insert update delete) DDL语句(create alter drop)
//返回影响的行数
int count = statement.executeUpdate(sql);
//执行DQL查询语句,返回结果集
ResultSet resultSet = statement.executeQuery(sql);
ResultSet
resultSet.next();
resultSet.getXXX();
//执行sql
resultSet = statement.executeQuery(sql)
resultSet.next()
int anInt = resultSet.getInt(1)
String name = resultSet.getString("name")
int age = resultSet.getInt("age")
String dep_name = resultSet.getString("dep_name")
String dep_location = resultSet.getString("dep_location")
System.out.println(anInt + " - " + name + " - " + age + " - " + dep_name + " - " + dep_location)
while (resultSet.next()) {
int anInt = resultSet.getInt(1)
String name = resultSet.getString("name")
int age = resultSet.getInt("age")
String dep_name = resultSet.getString("dep_name")
String dep_location = resultSet.getString("dep_location")
System.out.println(anInt + " - " + name + " - " + age + " - " + dep_name + " - " + dep_location)
}
PreparedStatement
- 预编译sql,参数使用
?作为占位符
- 防止sql注入,效率更高
- sql注入问题,在拼接sql时有一些sql的关键字参与字符串拼接,造成安全性问题
String sql = "select * from user where username = ? and password = ?;"
preparedStatement = connection.prepareStatement(sql)
//sql赋值
preparedStatement.setString(1, username)
preparedStatement.setString(2, password)
//执行
resultSet = preparedStatement.executeQuery()
事务
PreparedStatement preparedStatement = null
Connection connection = null
ResultSet resultSet = null
try {
//获取数据库的连接对象
connection = JDBCUtility.getConnection()
//开启事务
connection.setAutoCommit(false)
//定义sql语句
String sql = "update account set balance = balance + ? where id = ?"
//获取执行sql对象
preparedStatement = connection.prepareStatement(sql)
//设置sql 减500
preparedStatement.setDouble(1,+500)
preparedStatement.setInt(2,1)
//执行sql
preparedStatement.executeUpdate()
//手动异常
int i = 3 / 0
//设置sql 加500
preparedStatement.setDouble(1,-500)
preparedStatement.setInt(2,2)
//执行sql
preparedStatement.executeUpdate()
//提交事务
connection.commit()
//要抓大异常
} catch (Exception throwables) {
throwables.printStackTrace()
//回滚
try {
if (connection != null) {
connection.rollback()
}
} catch (SQLException e) {
e.printStackTrace()
}
} finally {
JDBCUtility.close(resultSet, preparedStatement, connection)
}
数据库连接池
- 一个存放数据库连接的容器
- 当系统初始化后,容器被创建,容器申请一些连接对象,当用户访问数据库时,从容器中获取连接对象,用户访问完之后,将连接对象归还给容器
- 节约资源,用户访问高效
C3P0
- 导入jar包,设置配置文件,名字必须为
*.properties(手动导入)/c3p0-config.xml(默认加载)
//创建数据库连接池
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource()
//使用指定名称配置 xml文件中的另一段
//ComboPooledDataSource otherc3p0 = new ComboPooledDataSource("otherc3p0")
//获取一个连接
Connection connection = comboPooledDataSource.getConnection()
//归还
connection.close()
System.out.println(connection)
Druid
Properties properties = new Properties()
InputStream resourceAsStream = DemoDruid.class.getClassLoader().getResourceAsStream("druid.properties")
properties.load(resourceAsStream)
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties)
for (int i = 0
Connection connection = dataSource.getConnection()
System.out.println(connection)
if (i == 5) {
//归还
connection.close()
}
}
Spring-JDBC
//创建JDBCTemplate
JdbcTemplate jdbcTemplate = new JdbcTemplate(DemoJDBCUtility.getDataSource())
String sql = "update account set balance = 400 where id = ?"
//自动释放资源,以参数列表的形式传递sql值
int update = jdbcTemplate.update(sql, 1)
System.out.println(update)
String sql = "insert into commpany values (null, ?, ?, ?, ?)"
//自动释放资源,以参数列表的形式传递sql值
int update = jdbcTemplate.update(sql, "dawsda", 40, "市场部", "hangzhou")
String sql = "Delete from commpany where id = ?"
//自动释放资源,以参数列表的形式传递sql值
int update = jdbcTemplate.update(sql, 10)
String sql = "select * from commpany where id = ?"
//查询的结果集长度只能为1
Map<String, Object> stringObjectMap = jdbcTemplate.queryForMap(sql, 1)
stringObjectMap.forEach((s, o) -> System.out.println(s + " - " + o))
sql = "select * from commpany"
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql)
maps.forEach(map -> map.forEach((s, o) -> System.out.println(s + " - " + o)))
List<Employee> employees = jdbcTemplate.query(sql, new RowMapper<Employee>() {
@Override
public Employee mapRow(ResultSet resultSet, int i) throws SQLException {
int anInt = resultSet.getInt("id")
String name = resultSet.getString("name")
int age = resultSet.getInt("age")
String dep_name = resultSet.getString("dep_name")
String dep_location = resultSet.getString("dep_location")
return new Employee(name, anInt, age, dep_name, dep_location)
}
})
for (Employee employee : employees) {
System.out.println(employee)
}
- 利用temp中的实现类,快速封装对象
new BeanPropertyRowMapper<类型>(类型.class)
List<Employee> employees = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Employee>(Employee.class))
System.out.println(employees)
String sql = "select count('id') from commpany"
Object o = jdbcTemplate.queryForObject(sql, Long.class)
System.out.println(o)