概念:Java DataBase Connectivity Java数据库连接,Java语言操作数据库
本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据驱动 jar包,我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动 jar包中的实现类-**-__面试题**
快速入门:
步骤:
1.导入驱动 jar包 mysql-connector-java-5.1.37-bin.jar
复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
右键 —Add as Library
2.注册驱动
3.获取数据库连接对象 Connection
4.定义sql
5.获取执行sql语句对象 Statement
6.执行sql得到返回结果
7.处理结果
8.释放资源
代码实现:
//导入驱动 jar包
//注册驱动
Class.forName(“com.mysql.jdbc.Driver”);
//获取数据库连接对象
Connection connection = DriverManager.getConnection(“jdbc:mysql://localhost:3306/wx”, “root”, “root1234”);
//定义sql语句
String sql=”update account set balance=5000 where name=’张三’”;
//获取执行sql语句对象Statement
Statement stmt=connection.createStatement();
int i = stmt.executeUpdate(sql);
System.out.println(i);
stmt.close();
connection.close();
1.DriverManager 驱动管理对象
**功能
1.注册驱动:告诉程序应该使用那个数据库驱动jar
static void registerDriver(Driver driver):注册与给定的驱动程序:DriverManager
写代码使用 Class.forName(“com.mysql.jdbc.Driver”);
通过查看源码发现 com.mysql.jdbc.Driver类中存在静态代码块
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException(“Can’t register driver!”);
}
}
注意:mysql5之后的驱动jar包可以省略注册驱动
2.获取数据库连接
static [Connection](../../java/sql/Connection.html) |
**[getConnection](../../java/sql/DriverManager.html#getConnection(java.lang.String, java.lang.String, java.lang.String))**([String](../../java/lang/String.html) url, [String](../../java/lang/String.html) user, [String](../../java/lang/String.html) password) 试图建立到给定数据库 URL 的连接。 |
---|---|
参数:
url:指定连接的路径
mysql:jdbc://ip地址(域名):端口号/数据库名称
user:名
password:密码
2.Connection 数据库连接对象
**功能
1.获取执行sql的对象
[Statement](../../java/sql/Statement.html) |
**[createStatement](../../java/sql/Connection.html#createStatement())**() 创建一个 Statement 对象来将 SQL 语句发送到数据库。 |
---|---|
[PreparedStatement](../../java/sql/PreparedStatement.html) |
**[prepareStatement](../../java/sql/Connection.html#prepareStatement(java.lang.String))**([String](../../java/lang/String.html) sql) 创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。 |
---|---|
2.管理事务
**开启事务
该方法的参数设置为false则开启事务
void |
**[setAutoCommit](../../java/sql/Connection.html#setAutoCommit(boolean))**(boolean autoCommit) 将此连接的自动提交模式设置为给定状态。 |
---|---|
**提交事务
void |
**[commit](../../java/sql/Connection.html#commit())**() 使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前持有的所有数据库锁。 |
---|---|
**回滚事务
void |
**[rollback](../../java/sql/Connection.html#rollback())**() 取消在当前事务中进行的所有更改,并释放此 Connection 对象当前持有的所有数据库锁。 |
---|---|
应用:JDBC管理事务
使用Connection来管理事务
*开启事务—>在执行sql之前—>setAutoCommit(参数)—>参数设为false为开启事务
*提交事务—>所有sql执行完后
*回滚事务—>在catch中回滚事务
//JDBC事务管理
public class JdbcDemo04 {
public static void main(String[] args) {
Connection connection=null;
PreparedStatement pstmt1=null;
PreparedStatement pstmt2=null;
try {
connection = JDBCUtils.getConnection();
connection.setAutoCommit(false);
String sql1=”update account set balance=balance-? where name=?”;
String sql2=”update account set balance=balance+? where name=?”;
pstmt1 = connection.prepareStatement(sql1);
pstmt2 = connection.prepareStatement(sql2);
pstmt1.setDouble(1,1500);
pstmt1.setString(2,”张三”);
pstmt2.setDouble(1,1500);
pstmt2.setString(2,”李四”);
pstmt1.executeUpdate();
//int x=3/0;//手动制造异常
pstmt2.executeUpdate();
connection.commit();
} catch (Exception e) {
try {
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.close(null,pstmt1,null);
JDBCUtils.close(null,pstmt2,connection);
}
}
3.Statement 执行sql的对象
执行sql
1.返回值是影响的行数,通过这个影响的行数可与判断DML语句是否执行成功,返回值>0执行成功,反之则失败
int |
**[executeUpdate](../../java/sql/Statement.html#executeUpdate(java.lang.String))**([String](../../java/lang/String.html) sql) 执行给定 SQL 语句,该语句可能为 INSERT 、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。 |
---|---|
executeUpdate的使用
Connection connection = null;
Statement statement = null;
try {
Class.forName(“com.mysql.jdbc.Driver”);
connection = DriverManager.getConnection(“jdbc:mysql://localhost:3306/wx”,”root”,”root1234”);
//添加记录
/String sql1=”insert into account values(4,’赵六’,1000)”;
statement = connection.createStatement();
int i1 = statement.executeUpdate(sql1);
System.out.println(i1);
if(i1>0){
System.out.println(“添加成功”);
}else{
System.out.println(“添加失败”);
}/
//修改记录
/String sql2=”update account set balance=5555 where name=’王五’”;
statement = connection.createStatement();
int i2 = statement.executeUpdate(sql2);
System.out.println(i2);/
//删除记录
String sql3=”delete from account where id=4”;
statement = connection.createStatement();
int i3 = statement.executeUpdate(sql3);
System.out.println(i3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(statement!=null){
statement.close();
}
if(connection!=null){
connection.close();
}
}
2.执行DQL语句
[ResultSet](../../java/sql/ResultSet.html) |
**[executeQuery](../../java/sql/Statement.html#executeQuery(java.lang.String))**([String](../../java/lang/String.html) sql) 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 |
---|---|
4.ResultSet 结果集对象
**next():游标向下移动一行
**getXxx(参数):获取数据—-Xxx代表数据类型
*参数
int:代表列的编号从1开始,如getId(1)
String:代表列名称,如getString(“balance”)
使用ResultSet和exectuteQuery*
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
Class.forName(“com.mysql.jdbc.Driver”);
connection = DriverManager.getConnection(“jdbc:mysql://localhost:3306/wx”,”root”,”root1234”);
String sql=”select from account”;
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
while(resultSet.next()){
int id=resultSet.getInt(1);
String name=resultSet.getString(“name”);
double balance=resultSet.getDouble(“balance”);
System.out.println(id+”—-“+name+”—-“+balance);
}
} 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();
}
}
}
练习:写一个方法,查询emp表中的数据封装成对象,然后装入集合
public static void main(String[] args) {
List
for(Emp e:list){
System.out.println(“Emp{“ +
“id=” + e.getId() +
“, ename=’” + e.getEname() + ‘\’’ +
“, jobid=” + e.getBonus() +
“, mgr=” + e.getMgr() +
“, joindate=” + e.getJoindate() +
“, salary=” + e.getSalary() +
“, bonus=” + e.getBonus() +
“, dept_id=” + e.getDept_id() +
‘}’);
}
}
private static List
Connection connection = null;
Statement statement = null;
ResultSet resultSet= null;
List
try {
Class._forName
connection = DriverManager.getConnection(“jdbc:mysql://localhost:3306/wx”,”root”,”root1234”);
String sql=”select *from emp”;
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
list=new ArrayList<>();
Emp emp=null;
while(resultSet.next()){
int id=resultSet.getInt(“id”);
String ename=resultSet.getString(“ename”);
int job_id=resultSet.getInt(“job_id”);
int mgr=resultSet.getInt(“mgr”);
Date joindate=resultSet.getDate(“joindate”);
double salary=resultSet.getDouble(“salary”);
double bonus=resultSet.getDouble(“bonus”);
int dept_id=resultSet.getInt(“dept_id”);
emp=new Emp();//重要写法
emp.setId(id);
emp.setEname(ename);
emp.setJob_id(job_id);
emp.setMgr(mgr);
emp.setJoindate(joindate);
emp.setSalary(salary);
emp.setBonus(bonus);
emp.setDept_id(dept_id);
list.add(emp);
}
} 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();
}
}
}
return list;
}
抽取JDBC工具类—JDBDCUtils
//JDBC工具类
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
static{
//获取src路径下文件的方式——>ClassLoader类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL resource = classLoader.getResource(“jdbc.properties”);
//吧URL转为字符串
String path = resource.getPath();
Properties pro=new Properties();
try {
pro.load(new FileReader(path));
} catch (IOException e) {
e.printStackTrace();
}
url= pro.getProperty(“url”);
user=pro.getProperty(“user”);
password= pro.getProperty(“password”);
driver= pro.getProperty(“driver”);
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
//关闭资源的方法
public static void close(ResultSet rs, Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
练习:输入用户名和密码判断能否登录成功
public class JdbcTestUtils {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
System.out.println(“请输入用户名:”);
String username=in.next();
System.out.println(“请输入密码:”);
String password=in.next();
boolean l = login(username, password);
if(l){
System.out.println(“登陆成功!”);
}else{
System.out.println(“用户名或密码错误!”);
}
}
private static boolean login(String userName,String passWord){
if(userName==null||passWord==null){
return false;
}
ResultSet resultSet = null;
Connection connection=null;
Statement statement=null;
try {
connection= JDBCUtils.getConnection();
String sql=”select *from db1 where username=’”+userName+”‘ and password=’”+passWord+”‘“;
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
return resultSet.next();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(resultSet,statement,connection);
}
return false;
}
}
5.PreparedStatement 执行sql的对象
1.SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与拼接,会造成安全问题
1.输入用户随便,输入密码:a’ or ‘a’=’a
2.sql: “select from db1 where username= ? and password= ? “
2.解决sql注入问题:使用PreparedStatement对象来解决
3.预编译sql:参数使用?作为占位符
4.步骤:
1.导入驱动 jar包 mysql-connector-java-5.1.37-bin.jar
* 复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
右键 —Add as Library
2.注册驱动
3.获取数据库连接对象 Connection
4.定义sql
sql使用?作为占位符
5.获取执行sql语句对象 PreparedStatementStatement
6.给?赋值,
方法:setXxx(参数1,参数2)从1开始
参数1:?的位置从1开始
参数2:?的值
7.执行sql得到返回结果
8.处理结果
9.释放资源
注意:后期都使用PreparedStatementStatement而不用Statement
1.可以防止SQl注入
2.效率更高
数据库连接池
概念:存放数据库连接的容器
原理:当系统初始化好后,容器被创建,容器会申请一些连接对象,当用户访问数据库时,从容器中获得连接对象,用户访问完成之后就将连接对象归还给容器—>高效
**实现:Datasource接口 javax.sql包下的
**方法:获取连接
[Connection](../../java/sql/Connection.html) |
**[getConnection](../../javax/sql/DataSource.html#getConnection())**() 尝试建立与此 DataSource 对象所表示的数据源的连接。 |
---|---|
**归还连接:如果连接对象是从连接池中获取的,那么调用Connection.close()方法不再是关闭连接,而是将连接对象归还连接池
连接池一般由数据库厂商来实现
**C3P3:数据库连接池技术
**Druid:数据库连接池技术,阿里巴巴提供
C3P0的使用步骤:
1.导入两个 jar包:c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
还要导入数据库驱动jar包 mysql-connector-java-5.1.37-bin.jar
2.定义配置文件
名称:c3p0.properties or c3p0-config.xml
路径:放在src目录下
3.创建数据库连接池对象CombopooledDatasource
**4.获取连接getConnection
Druid使用步骤:
1.导入jar包 :druid-1.0.9.jar
2.定义配置文件
properties的
可以叫任意名称,放在任意目录下
加载配置文件
3.创建数据库连接池对象,通过工厂类来获取DruidDatasourceFactory
**4.获取连接getConnection
定义工具类JDBCUtils2
1.提供静态代码块加载配置文件,初始化连接池对象
2.提供方法:
1.获得连接的方法
2.释放资源
3.获取连接池的方法
//测试Druid工具类JDBCUtils2
public class JDBCUtil2TestDruid {
public static void main(String[] args) {
Connection connection =null;
PreparedStatement pstmt =null;
ResultSet resultSet =null;
PreparedStatement pstmt2 =null;
try {
connection = JDBCUtils2.getConnection();
String sql1=”insert into account values(?,?,?)”;
pstmt = connection.prepareStatement(sql1);
pstmt.setInt(1,4);
pstmt.setString(2,”微信”);
pstmt.setDouble(3,9999);
int i = pstmt.executeUpdate();
String sql2="select _*_from account";<br /> pstmt2 = connection.prepareStatement(sql2);<br /> resultSet = pstmt2.executeQuery();<br /> while(resultSet.next()){<br /> int id=resultSet.getInt("id");<br /> String name=resultSet.getString("name");<br /> Double balance=resultSet.getDouble("balance");<br /> System._out_.println(id+"---"+name+"---"+balance);<br /> }<br /> } catch (SQLException e) {<br /> e.printStackTrace();<br /> } finally {<br /> JDBCUtils2._close_(resultSet,pstmt2,null);<br /> JDBCUtils2._close_(null,pstmt,connection);<br /> }
}<br />}
Spring JDBC
Spring框架对JDBC的简单封装。提供一个JDBCTemplate对象简化JDBC的开发
步骤:
1.导入jar包
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
2.创建JdbcTemplate对象,依赖于数据源DataSource
JdbcTemplate template=new JdbcTemplate(DataSource);
3.调用JdbcTemplate的方法来完成CRUD操作
*update():执行DML语句
*queryForMap():查询结果封装为map集合
**只能封装一条记录,列为key,值为value
*queryForList():查询结果封装为list集合
**将每一条记录封装为map,再将所有map装到list集合
*query():查询结果,封装为JavaBean对象
query()的参数RowMapper
使用的实现类BeanPropertyRowMapper
List<类型> list = template.query(sql, new BeanPropertyRowMapper<类型>(类型.class));
*queryForObject():查询结果,将结果封装为对象
一般用于聚合函数的查询
练习
1.修改1号的数据salary为10000
2.添加一条记录
3.删除刚才添加的记录
4.查询所有记录,封装为map
5.查询所有记录,封装为list
6.查询所有记录,将其封装为Emp对象的list集合
7.查询总记录数
public class JdbcTemplateDemo01 {
private static JdbcTemplate template=new JdbcTemplate(JDBCUtils2.getDataSource());
public static void main(String[] args) {
String sql1=”update account set balance=? where name=?”;
int i = template.update(sql1, 5555.5, “张三”);
}
@Test
public void test1(){
String sql=”select *_from emp where id=?”;
Map
System.out.println(map);
}
@Test
public void test2(){
String sql=”select *_from emp”;
List.queryForList(sql);
for(Map
System.out.println(n);
}
}
@Test
public void test3(){
String sql=”select *_from emp”;
List
for(Emp n:list){
System.out.println(n);
}
}
@Test
public void test4(){
String sql=”select count(id) from emp”;
Integer it = template.queryForObject(sql, Integer.class);
System.out.println(it);
}
}