# JDBC
# 什么是JDBC
- Java DataBase Connectivity,java数据库连接,实际上jdbc是java中的一套和数据库交互的api (application program interface 应用程序编程接口)
# 为什么使用JDBC
- 因为java程序员需要连接多种数据库(orcale,mysql,deb2等)为了避免每一个数据库都学习一套心的api,sum公司提出了一个jdbc接口,各个数据库厂商根据此接口写实现类(驱动),这样java程序员只需要掌握JDBC接口中的一套方法,就可以访问任何数据库。
# 如何使用JDBC
- 创建maven工程
- 下载mysql-Connector-java 5.1.6版本相关jar包,从pom.xml导入
- 创建JDBCDemo1.java类 添加main方法
- 使用步骤
- 注册驱动
- 获取数据库连接对象
- 创建sql执行对象
- 执行sql语句
- 关闭资源
//1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","chengyi123"); //3. 创建sql执行对象 Statement stat = conn.createStatement(); //4. 执行sql语句 String sql = "insert into jdbct1 values(1,'Tom')"; stat.executeUpdate(sql); System.out.println("插入成功"); //5.关闭资源 stat.close(); conn.close();
# 执行sql语句的方法
- execute(sql) 可以执行任意sal,但是推荐执行DDL 返回值为boolean值,true代表有结果集(例如执行查询语句会返回查询结果),false代表没有结果集,成功或失败通过是否有异常来判断
- executeUpdate(sql) 推荐执行DML 返回值为int 代表生效的行数
- executeQuery(sql) 推荐执行DQL
返回值ResultSet 里面装了查询结果
next()方法的作用:判断有没有吓一条数据有返回值
为true (同时游标往下移动) 没有则false//1. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","chengyi123"); //3. 创建sql执行对象 Statement stat = conn.createStatement(); //4. 执行sql语句 ResultSet rs = stat.executeQuery("select * from jdbct1"); //遍历结果 while(rs.next()){ int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println(id+":"+name); } //5.关闭资源 stat.close(); conn.close();
# 数据库类型和java类型对比
mysql java
int getInt
varchar getString
float/double getFloat/getDouble
detetime/timestamp getDate
# ResultSet获取数据的方式
- 通过字段名获取 如:getString("name")
- 通过查询到结果数据的位置获取 如:getString(2);(位置从1开始)
# 读取配置文件(在resources包里创建一个.properties文件,这里就是指读取这个文件,类似读取xml)
Properties prop = new Properties();
//得到文件的输入流
InputStream ips = DBUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
//把文件流交给prop
prop.load(ips);
//获取保存的数据
String age = prop.getProperty("age");
String name = prop.getProperty("name");
System.out.println(age+":"+name);
# 数据库连接池
DBCP DataBase Connection Pool:数据库连接池
为什么使用:如果没有连接池,每一次业务都需要和数据库服务器建立一次连接,业务处理完断开连接,如多有上万次业务就会有上万次的开关连接,频繁开关连接非常浪费资源,使用数据库连接池,可以设置几个初始连接,如果有业务需要使用连接,则从连接池中直接获取,如果连接池中连接用光,则会等待连接归还后再获取连接
如何使用:
- 下载jar包:从maven私服中搜索commons-dbcp
//1. 创建数据源对象
BasicDataSource dataSource = new BasicDataSource();
//2.设置数据库连接信息
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/db3");
dataSource.setUsername("root");
dataSource.setPassword("chengyi123");
//3. 设置连接池策略信息
dataSource.setInitialSize(2);//初始连接数量
dataSource.setMaxActive(5);//最大连接数量
//4. 从连接池中获取连接对象
Connection conn = dataSource.getConnection();
# 解决jdbc乱码问题
在url后面添加如下内容 jdbc:mysql://localhost:3306/db3**?useUnicode=true&characterEncoding=UTF-8**
# PreparedStatement
- 预编译的sql执行对象
- 好处:
- 代码可读性更高,不容易出错(因为statement拼接字符串又麻烦又容易出错)
- 带有预编译效果,执行效率比statement略高
- 可以避免sql注入,因为预编译的时候已经把sql语句的逻辑固定,替换?进去的内容只能以值的形式体现,如果包含逻辑sql内容,则无效
- sql 中有变量就用preparedStatement,没有变量就用statement
- 使用方式:()
//获取数据库连接对象 Connection conn = DBUtils.getConn(); //创建预编译sql执行对象,?占位符 String sql="insert into user values(null,?,?)"; PreparedStatement stat = conn.prepareStatement(sql); //把?替换成真正的值 stat.setString(1, name); stat.setInt(2, age); //执行sql stat.executeUpdate(); System.out.println("插入成功!");
# 通过登录案例演示sql注入
# 批量操作 batch
批量操作:可以把多次sql合并成一次执行,避免了频繁和数据库服务器进行交互,从而提高执行效率
代码参见:TestBatch.java
# 批量插入避免内存溢出
//获取数据库连接对象
conn = DBUtils.getConn();
//创建sql执行对象
stat = conn.createStatement();
//执行sql语句
String sql1="insert into user values(null,'悟空',18)";
String sql2="insert into user values(null,'八戒',28)";
String sql3="insert into user values(null,'沙僧',38)";
//单条执行
// stat.executeUpdate(sql1);
// stat.executeUpdate(sql1);
// stat.executeUpdate(sql1);
//批量执行
stat.addBatch(sql1);
stat.addBatch(sql2);
stat.addBatch(sql3);
//执行arr是每条sql的生效行数
int arr[] = stat.executeBatch();
System.out.println("执行完成!");
# 分页查询
在控制台输入页数和每页的数量,得到对应的内容 如:输入 页数输入3 每页数量输入5 则得到 第11-15条数据
- 参见代码 pageSelect.java
# 事务
- 设置自动提交的状态 conn.setAutoCommit(true/false);
- 提交 conn.commit();
- 回滚 conn.rollback();
- 转账实现
- 代码参见 TransactionTest.java
# 获取自增主键值
- 代码参见 AutoPrimaryKey
# 练习:往部门表插入一个神仙部,同时往员工表插入孙悟空和猪八戒,并且和神仙部建立关系
- 代码参见 DeptAndEmpTest
# 获取元数据
数据库的元数据: 数据库厂商(mysql oracle),数据库的连接信息等都成为数据库的元数据
表的元数据:表有哪些字段,字段类型等。
代码参见 MetaDataTest