回顾
1. MySQL性能
数据库类型
查询密集型
修改密集型
查询sql执行次数(innodb存储引擎)
慢查询日志监控(我们需要手动开启)
2. MySQL索引
索引=排好序的数据结构
数据结构
二叉树
红黑树
BTree
B+Tree
hash
创建表时指定索引
create table 表名(
id int primary key auto_increment,
`name` varchar(32),
`telephone` varchar(11),
index(`name`),
unique(`telephone`)
);
索引创建原则
1)内容可识别度不低于70%
2)作为条件查询的字段
3)作为表连接字段(主键、外键)
4)经常排序的字段
数据库存储引擎
myisam:非聚集索引
innodb:聚集索引
mycat:数据库中间件
JDBC
今日目标
1. JDBC基础
2. 用户登录案例【大作业】
B/S架构,编写用户登录案例
一 JDBC基础
1.1 概述
Java 数据库连接(Java DataBase Connectivity)
作用:通过Java语言操作数据库
本质:是官方(sun公司)定义的一套操作所有关系型数据库的规则(接口)。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,运行时的代码其实是驱动jar包中的实现类。
1.2 快速入门
需求
通过java代码向数据库user表插入一条记录
① 准备数据库和表
② 创建java工程,导入MySQL驱动jar包
③ 编写插入代码
// 1.注册驱动
// 2.建立连接
// 3.编写sql
// 4.获取sql执行对象
// 5.执行sql并返回结果
// 6.处理结果
// 7.释放资源
public class JDBCQuick {
public static void main(String[] args) throws Exception {
// 1.注册驱动
DriverManager.registerDriver(new Driver());
// 2.建立连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day23", "root", "root");
// 3.编写sql(在java编写sql 结尾;可以省略)
String sql = "insert into user values(null,'lucy','666')";
// 4.获取sql执行对象
Statement statement = connection.createStatement();
// 5.执行sql并返回结果
int i = statement.executeUpdate(sql);
// 6.处理结果
if (i>0) {
System.out.println("添加成功");
}else{
System.out.println("添加失败");
}
// 7.释放资源
statement.close();
connection.close();
}
}
1.3 API介绍
sun公司提供的:java.sql包下
DriverManager:驱动管理对象
1. 注册驱动
1)【了解】
static void registerDriver(Driver driver)
我们通过翻看MySQL Driver实现类的源码发现内部的静态代码已经提供了注册驱动功能
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
2)反射【掌握】
Class.forName("com.mysql.jdbc.Driver");
3)SPI 服务提供接口 【Service Provider Interface】
2. 建立连接
static Connection getConnection(String url, String user, String password)
参数说明:
url:连接指定数据库地址【固定格式】
格式:jdbc:mysql://ip地址+端口/数据库名
实例:
jdbc:mysql://localhost:3306/day23
jdbc:mysql:///day23
user:用户名
password:密码
Connection:数据库连接对象
1. 获取sql执行对象【小货车】
Statement createStatement() 【今天】
PreparedStatement prepareStatement(String sql) 【后天】
2. 事务管理
1)关闭自动提交(开启事务)
void setAutoCommit(boolean autoCommit)
参数:
true:自动提交【默认值】
false:手动提交
2)提交事务
void commit()
3)回滚事务
void rollback()
Statement:执行sql的对象
1. 执行所有类型sql语句【了解】
boolean execute(String sql)
----------------------------------
2. 仅执行DML类型sql语句
int executeUpdate(String sql)
参数:dml类型sql(insert、update、delete)
返回值:影响行数
3. 仅执行DQL类型sql语句
ResultSet executeQuery(String sql)
参数:dql类型sql(select)
返回值:结果集
ResultSet:结果集对象,封装查询结果
1. 指针下移
boolean next()
返回值:
true:表示此行有数据
false:表示此行没有数据
2. 获取数据
T getXxx(int 列编号)
T getXxx(String 列名)
补充:获取所有类型
Object getObject(String 列名)
String getString(String 列名)
1.4 CRUD操作【2、3、4遍...】
// 1.注册驱动
// 2.建立连接
// 3.编写sql
// 4.获取sql执行对象
// 5.执行sql并返回结果
// 6.处理结果
// 7.释放资源
user表 添加一条记录
// 新增:课下作业
@Test
public void testInsert()throws Exception{
}
user表 修改一条记录
// 修改
@Test
public void testUpdate()throws Exception{
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.建立连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day23", "root", "root");
// 3.编写sql
String sql = "update user set username = '勒布朗' where id = 5";
// 4.获取sql执行对象
Statement statement = connection.createStatement();
// 5.执行sql并返回结果
int i = statement.executeUpdate(sql);
// 6.处理结果
if (i>0) {
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
// 7.释放资源
statement.close();
connection.close();
}
user表 删除一条记录
// 删除
@Test
public void testDelete()throws Exception{
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.建立连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day23", "root", "root");
// 3.编写sql
String sql = "delete from user where id = 7";
// 4.获取sql执行对象
Statement statement = connection.createStatement();
// 5.执行sql并返回结果
int i = statement.executeUpdate(sql);
// 6.处理结果
if (i>0) {
System.out.println("删除成功");
}else{
System.out.println("删除失败");
}
// 7.释放资源
statement.close();
connection.close();
}
user表 查询所有记录
// 查询
@Test
public void testFindAll() throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.建立连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day23", "root", "root");
// 3.编写sql
String sql = "select * from user";
// 4.获取sql执行对象
Statement statement = connection.createStatement();
// 5.执行sql并返回结果
ResultSet resultSet = statement.executeQuery(sql);
// 6.处理结果
while (resultSet.next()) {
// 获取数据
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
System.out.println("编号:" + id + " 用户名:" + username + " 密码:" + password);
}
// 7.释放资源
resultSet.close();
statement.close();
connection.close();
}
1.5 工具类【抄一遍...】
通过上面案例需求我们会发现每次去执行SQL语句都需要注册驱动,获取连接,得到Statement,以及释放资源。发现很多重复的劳动,我们可以将重复的代码定义到一个工具类中。
目的:简化书写,一劳永逸
步骤分析
public class JdbcUtils{
// 1.注册驱动【保证一次】
static{
}
// 2.提供获取连接的静态方法
public static Connection getConnection(){
return null;
}
// 3.提供释放资源的方法
public void close(){
}
}
1.5.1 版本一
public class JdbcUitls1 {
// 1.注册驱动【保证一次】
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// e.printStackTrace();
throw new RuntimeException("加载mysql驱动失败");
}
}
// 2.提供获取连接的静态方法
public static Connection getConnection()throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/day23", "root", "root");
}
// 3.提供释放资源的方法
public static void close(ResultSet resultSet, Statement statement,Connection connection) {
if (resultSet!=null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 重载关闭方法
public static void close(Statement statement,Connection connection){
close(null, statement, connection);
}
}
1.5.2 版本二
抽取配置文件
编写工具类
public class JdbcUitls {
// 声明变量
private static String driver = null;
private static String url = null;
private static String user = null;
private static String password = null;
// 加载jdbc.properties配置文件,初始化变量
static {
// SE阶段所学
// new Properties().load();
// sun公司专门提供了一从src目录下加载properties类型的工具类 ResourceBundle
ResourceBundle jdbc = ResourceBundle.getBundle("jdbc");
driver = jdbc.getString("jdbc.driver");
url = jdbc.getString("jdbc.url");
user = jdbc.getString("jdbc.user");
password = jdbc.getString("jdbc.password");
}
// 1.注册驱动【保证一次】
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
// e.printStackTrace();
throw new RuntimeException("加载mysql驱动失败");
}
}
// 2.提供获取连接的静态方法
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
// 3.提供释放资源的方法
public static void close(ResultSet resultSet, Statement statement, Connection connection) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 重载关闭方法
public static void close(Statement statement, Connection connection) {
close(null, statement, connection);
}
}
1.6 事务操作
* 事务
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
* MySQL操作
1.开启事务
begin | start transaction;
2.提交事务
commit;
3.回顾事务
rollback;
* java操作(使用Connection对象)
1.关闭自动提交(开启事务)
void setAutoCommit(false);
2.提交事务
void commit();
3.回顾事务
void rollback();
需求
通过java代码实现转账案例
① 导入账户表
② 编写转账代码
public class TXDemo{
@Test
public void testTX(){
try{
// 1.获取连接【JdbcUtils工具类】
// 2.开启事务
// 3.罗志祥扣钱
// 机器故障
// 4.蝴蝶姐加钱
// 5.提交事务
}catch(Exception e){
// 6.回滚事务
}finally{
// 7.释放资源
}
}
}
public class TXDemo {
@Test
public void testTX() {
Connection connection = null;
Statement statement = null;
try {
// 1.获取连接【JdbcUtils工具类】
connection = JdbcUitls.getConnection();
// 2.开启事务
connection.setAutoCommit(false);
tatement = connection.createStatement();
// 3.罗志祥扣钱
// 机器故障
// 4.蝴蝶姐加钱
// 5.提交事务
connection.commit();
} catch (Exception e) {
try {
// 6.回滚事务
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
// 7.释放资源
JdbcUitls.close(statement, connection);
}
}
}
public class TXDemo {
@Test
public void testTX() {
Connection connection = null;
Statement statement = null;
try {
// 1.获取连接【JdbcUtils工具类】
connection = JdbcUitls.getConnection();
// 2.开启事务
connection.setAutoCommit(false);
statement = connection.createStatement();
// 3.罗志祥扣钱
String xiangSql = "update account set money = money-100 where id = 2";
int xiangResult = statement.executeUpdate(xiangSql);
if (xiangResult > 0) {
System.out.println("罗志祥支付成功~~~");
}
// 机器故障
int a = 1 / 0;
// 4.蝴蝶姐加钱
String dieSql = "update account set money = money + 100 where id = 1";
int dieResult = statement.executeUpdate(dieSql);
if (dieResult > 0) {
System.out.println("蝴蝶姐收款成功~~~");
}
// 5.提交事务
connection.commit();
} catch (Exception e) {
e.printStackTrace();
try {
// 6.回滚事务
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
// 7.释放资源
JdbcUitls.close(statement, connection);
}
}
}
二 案例:用户登录【大作业】
需求
用户输入账号和密码,实现登录网站功能
2.1 需求分析
2.2 代码实现
① 创建web工程,并导入jar包
② 导入页面资源
③ 复制JdbcUtils工具类
④ LoginServlet
表单提交
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 统一编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 1.接收请求
String username = request.getParameter("username");
String password = request.getParameter("password");
try {
// 2.操作JDBC
// 2.1 获取连接
Connection connection = JdbcUitls.getConnection();
// 2.2 编写sql
// String sql = "select * from user where username ='admin' and password ='123'";
String sql = "select * from user where username ='" + username + "' and password ='" + password + "'";
System.out.println(sql);
// 2.3 获取sql执行对象
Statement statement = connection.createStatement();
// 2.4 执行sql并返回结果
ResultSet resultSet = statement.executeQuery(sql);
// 3.判断是否登录成功
if (resultSet.next()) {// 成功
String loginUsername = resultSet.getString("username");
request.getSession().setAttribute("loginUsername", loginUsername);
response.sendRedirect(request.getContextPath() + "/list.jsp");
} else {// 失败
request.setAttribute("error", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
⑤ list.jsp
⑥ login.jsp
老师晚上总结
疑惑|拓展
-
mysql练习错题说明
-
昨晚有同学反馈《索引与函数加强题目》第四、第五道题错误.
说明:
- 第四题: 答案是没有错的,只不过我们复制答案的时候千万不要让字符串换行.
- 第五题: 答案是没有错的
-- 查询学过“李平老师”所教的所有课的同学的学号、姓名 -- 1. 找到李平老师的tid SELECT tid FROM teacher WHERE tname='李平老师'; -- 2. 到李平老师教的所有课程cid 2 4 SELECT cid FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tname='李平老师'); -- 3. 找到李平老师教的所有课程数量 SELECT COUNT(cid) FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tname='李平老师'); -- 4. 找到所有学习李平老师课程的学生student_id SELECT s.`student_id` FROM score s WHERE s.`course_id` IN (SELECT cid FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tname='李平老师')); -- 5. 找到所有选择了李平老师所有课程的学生student_id SELECT s.`student_id` FROM score s WHERE s.`course_id` IN (SELECT cid FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tname='李平老师')) GROUP BY s.`student_id` HAVING COUNT(s.`student_id`) =(SELECT COUNT(cid) FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tname='李平老师')); -- 6. 找到学生的信息(学号和姓名) SELECT s.`sid`,s.`sname` FROM student s WHERE s.`sid` IN (SELECT s.`student_id` FROM score s WHERE s.`course_id` IN (SELECT cid FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tname='李平老师')) GROUP BY s.`student_id` HAVING COUNT(s.`student_id`) =(SELECT COUNT(cid) FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tname='李平老师')));
-
-
jdbc的操作步骤
package com.itheima.test; import org.junit.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class Demo1 { @Test public void test01() throws Exception { //1. 加载驱动 Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day21", "root", "abc123"); //3. 创建sql的运输器 Statement st = connection.createStatement(); //4. 准备sql语句 , 执行sql String sql ="insert into account(name,balance) values ('狗娃',1000)"; int row = st.executeUpdate(sql); System.out.println("受影响的行数:"+row); //5. 关闭资源 st.close(); connection.close(); } }
-
注册驱动的代码感觉没用, 该语句虽然可以不写,但是建议同学还是写,符合市场的习惯
@Test public void test01() throws Exception { //1. 加载驱动, 感觉该语句没啥用,为什么会有这种感觉呢,因为该语句和代码下面的所有语句都没有任何关联。 //答案: 其实是有关联的, 因为你加载Driver类的时候会执行静态代码块,静态代码块的代码中出现了DriverManager //以前DriverManager比较笨,它不知道从哪里去寻找驱动类,所以需要你注册。 //从mysql5.0开始DriverManager就变得聪明了,该语句可以省略。 // Class.forName("com.mysql.jdbc.Driver"); //2. 获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day21", "root", "abc123"); //3. 创建sql的运输器 Statement st = connection.createStatement(); //4. 准备sql语句 , 执行sql String sql ="insert into account(name,balance) values ('狗剩',1000)"; int row = st.executeUpdate(sql); System.out.println("受影响的行数:"+row); //5. 关闭资源 st.close(); connection.close(); }
-
为什么需要关闭连接, 关闭的作用是干嘛呢?
以前你们学过io流,那么请问io流关闭资源的目的是什么? io关闭资源的目的就是释放文件资源,因为文件资源是有限的。 * 凡是有限的资源我们用完之后都应该马上是否。 jdbc的close方法的作用就是释放连接Connection对象。 因为connection代表 java程序与mysql数据库连接,这种连接数是有限的,默认情况mysql最高的并发connection数量是100, 所以用完毕之后一定要释放资源。
-
增删改使用的方法,查询使用的方法?
增删改: executeupdate()
查询: executequery()
-
Statement的execute方法的误区
//execute方法一般我们用于创建表 @Test public void test03() throws Exception { //2. 获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql:///day21", "root", "abc123"); //3. 创建sql的运输器 Statement st = connection.createStatement(); //4. 准备sql语句 , 执行sql String sql ="insert into account(name,balance) values ('铁蛋',1000)"; sql ="select * from account"; //execute方法的返回值:如果你执行的sql是查询语句返回true,其他语句一律是false,所以该返回值没有任何的意义 boolean flag = st.execute(sql); // execute() 方法的返回值是boolean。 System.out.println("执行的结果:"+ flag); //5. 关闭资源 st.close(); connection.close(); }
-
ResultSet结果集的使用, 结果集常见的错误
@Test public void test04() throws Exception { //2. 获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql:///day21", "root", "abc123"); //3. 创建sql的运输器 Statement st = connection.createStatement(); //4. 准备sql语句 , 执行sql String sql = "select name,balance from account"; // resultSet是一个结果集,这个结果集会把本次sql查询的数据全部加载到ResultSet中。 ResultSet rs = st.executeQuery(sql); //next() 游标向下移动一个单位,并且返回是否还有数据,如果游标没法向下移动代表已经是数据末尾。 while(rs.next()) { System.out.println("姓名:" + rs.getString("name") + " 余额:" + rs.getDouble("balance")); } //5. 关闭资源 st.close(); connection.close(); }
-
工具类的Connection什么时候为null,不明白为什么需要非空判断.
@Test public void test05() throws Exception { Connection connection = null; Statement st = null; ResultSet rs =null; try { //2. 获取连接 connection = JdbcUitls.getConnection(); // 执行该语句的时候就会出现异常, //3. 创建sql的运输器 st = connection.createStatement(); //4. 准备sql语句 , 执行sql String sql = "select name,balance from account"; // resultSet是一个结果集,这个结果集会把本次sql查询的数据全部加载到ResultSet中。 rs = st.executeQuery(sql); //next() 游标向下移动一个单位,并且返回是否还有数据,如果游标没法向下移动代表已经是数据末尾。 if(rs.next()) { System.out.println("姓名:" + rs.getString("name") + " 余额:" + rs.getDouble("balance")); } } catch (Exception e){ e.printStackTrace(); }finally { //出现异常的时候资源还是还关闭,没因为在finally块中 JdbcUitls.close(rs,st,connection); }
重点
- jdbc实现对数据的CURD
- 完成jdbc工具类的抽取
- 事务的操作
- 完成登陆案例,最好使用三层架构的方式实现
学习反馈
反馈 | 答案 |
---|---|
关于resultset希望老师可以再讲讲。 | 刚刚老师已经和大家讲解了 |
快开学吧 | 好的 |
答疑区
疑问 | 答案 |
---|---|
这个SQL执行对象是怎么实现的?通过协议传输数据包吗? | 数据库其实也是一个服务器,跟我们学习的tomcat一样,可以接受客户端的连接,通过这个连接执行sql语句.底层使用网络编程来传输数据. |
jdbc是不是用到了模板设计模式? | 是的 |
建立连接的那个地址是怎么来的呢? | url的是固定中,其中有些参数是可以改变的,例如ip地址,端口号,项目名称,后面会详细讲解. |
3306是固定的吗? | mysql默认端口是3306,可以在my.ini配置文件中修改 |
java代码能直接创建库,创建表吗 | 可以,但是我们一般只是用jdbc来操作数据库的数据,增删改查。 |
这个idea到数据库是不是c/s结构,底层连接用的tcp协议,通过3次握手建立连接,4次挥手断开连接,并且中间传输内容没有限制。(他的3次握手建立连接是封装到底层了吗?4次挥手代表的是释放资源吗?) | 不是 他用的是jdbc协议的封装,这个暂时不要研究,先把课上的重点弄明白了,这个可以作为扩展自己去搜一下 |
注册驱动是不是也可以用class.forName(); 这两个有什么区别 | 是的,两种都可以注册,但是Class.forname这种我们可以把驱动类的类名编写在配置文件中,不需要写死,更加灵活 |
注册驱动那里为什么不用反射直接注册?如果用DriverManager.registerDriver注册的话,里面的静态代码块不也执行了吗,这不相当于注册了两次? | 是的,等会说讲倒 |
请问老师们,有些项目里,sql语句中数据位置用的是?,这个?是占位符嘛?怎么理解呢 | 明天会讲到 |
Driver.Class为什么有耦合呢? | 需要直接使用 驱动包里面的 类 Driver。 而不是jdbc‘接口。’ |
.class有耦合,那getClass可以用吗 | 目前咱们的代码都有耦合, 待会会讲到如何解耦 |
为什么要 注册驱动呢, 以前不都是导入jar包, 然后就可以直接使用jar包中定义的静态方法或者可以使用定义好的获取抽象方法的实现类,在通过实现类对象调用方法就行了. 不太理解为什么要注册驱动呢 | 这就涉及到JDBC的代码设计思想: 面向接口编程 如果你有认真观察, 你就发现课上的这个入门案例中, 只有第一个步骤(注册驱动)跟mysql的驱动jar包耦合.其它代码都是面向接口的写法, 而这些接口是sun公司制定的. 如果没有注册驱动这步, 我们的jdbc根本不知道是使用了哪家数据库软件的驱动(是mysql还是oracle) 那么注册驱动是什么作用呢? 实际上第二步的Connection连接是由Driver对象来获取的(在DriverManager的底层), 第一步注册驱动的作用就是设置 mysql驱动包的Driver实现类, 在第二步获取连接时使用. |
password没密码直接="",就可以么 | 可以的,但是建议给数据库设置下密码 |
能大致讲一讲这个底层jdbc协议网络编程吗 | |
JDBC 和数据库的连接时间是多久,什么时候或者什么情况下断开连接?查询的时候指针是直接从数据库中获取到的数据吗? | 使用完毕我们会关闭连接,查询数据的时候,数据会被封装到ResultSet结果中,我们是从ReusltSet结果集中获取数据 |
resultset executeQuery(string sql)这个方法是不是把返回的表格中的数据从字符串形式(返回每一行字符串数据都映射成了java对象,再把这些对象封装到resultset集对象里面。 | 结果集里面都是字符串类型.你可以在获取的时候调用rs.getXXX类型进行转型. |
ResultSet是个set集合吗?如果查询的结果集中存在重复的行的话,会重复显示吗?假如确实需要对这些重复的数据单独处理的话,而不是只显示一个的话 | ResultSet不是Set集合,该类的内部维护了集合用于存储查询到的数据 |
resultset封装的数据好像是一种特殊形式,有个方法可以getxxx(int 列号)列号这个东西就很秀了,如果是封装的字符串类型怎么有列号这个东西,好像就是把整个表映射到集合里面。但是网络传输协议传输的只是string类型, 结果有列号证明分列了,是这个内部进行分列,还是传过来就分好了? | 这都是resultset内部做的处理.我们只需要知道resultset干了啥.怎么用就好.不需要去研究resultset是怎么实现的.当然猜一下也是可以的.如果我们把精力都放在研究底层.不太适合我们现在这个阶段该干的事. |
resultSet结果集的数据 是不是根据 查询条件 select * from 一致, 得到所有 就取所有 得到具体的字段 就只能取某个具体的数据 | 是的,比如:select name,age from 表名,那么resultSet结果集只有name与age两个字段的数据。 |
建立连接通道那个异常不抛,使用jdk7的try()catch 把所有语句都写到这里 可以吗 是不是就可以省略释放资源了 | 是的,完全可以 |
事务开启了,事务什么时候关闭呢 | 执行完毕提交事务,出现异常回滚事务,提交或者回滚都是结束事务 |
可以一条事务 开一辆车吗 就是罗志祥一个createStatement,蝴蝶姐一个createStatement | 一个事务中创建多个statement是可以的。 但是多个用户是用不了一个事务的。 |