学习笔记——CRUD&&login
一、学习重点
二、学习内容
案例一:查询(面对对象思想)
package com.jsoft.morning.test; import org.junit.Test; import java.util.List; public class Demo { /** * 需求:查询学生姓名,分数,科目名 * * 利用面向对象的思想 * * 得到一个集合。 * 所有的查询和拼装集合的操作都在Dao类中去做 * 我们在Demo这个类中只做测试。 * */ StudentScoreCourseDao dao = new StudentScoreCourseDao(); @Test public void test01() { // 查询学生姓名,成绩,科目名 // System.out.println(dao.getAll()); // System.out.println(dao.getById(2)); // System.out.println(dao.getBySidAndCid(2, 2)); // System.out.println(dao.getCount(1)); System.out.println(dao.getOrderScore()); } }
package com.jsoft.morning.test; public class StudentScoreCourse { private String sname; private Integer score; private String cname; public StudentScoreCourse() { } public StudentScoreCourse(String sname, Integer score, String cname) { this.sname = sname; this.score = score; this.cname = cname; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } @Override public String toString() { return "StudentScoreCourse{" + "sname='" + sname + '\'' + ", score=" + score + ", cname='" + cname + '\'' + '}'; } }
package com.jsoft.morning.test; import util.JDBCUtil; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class StudentScoreCourseDao { private final Connection conn; { try { conn = JDBCUtil.getConnection(); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SQLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } /** * 查询的方法 * 查询学生姓名,分数,科目名 */ public List<StudentScoreCourse> getAll() { List<StudentScoreCourse> stus = new ArrayList<>(16); String sql = "select s.name sname,r.score,c.name cname " + "from student s " + "left join scores r on s.id = r.s_id " + "left join course c on c.id = r.c_id"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); while(rs.next()){ String sname = rs.getString("sname"); int score = rs.getInt("score"); String cname = rs.getString("cname"); StudentScoreCourse ssc = new StudentScoreCourse(sname,score,cname); stus.add(ssc); } } catch (SQLException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt,rs); } return stus; } /** * 查询某一个学生的分数 */ public List<StudentScoreCourse> getById(Integer sid) { List<StudentScoreCourse> stus = new ArrayList<>(16); String sql = "select s.name sname,r.score,c.name cname " + "from student s " + "left join scores r on s.id = r.s_id " + "left join course c on c.id = r.c_id where s_id = ?"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = conn.prepareStatement(sql); pstmt.setInt(1,sid); rs = pstmt.executeQuery(); while(rs.next()){ String sname = rs.getString("sname"); int score = rs.getInt("score"); String cname = rs.getString("cname"); StudentScoreCourse ssc = new StudentScoreCourse(sname,score,cname); stus.add(ssc); } } catch (SQLException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt,rs); } return stus; } /** * 查询某一个学生的某一科的分数 */ public StudentScoreCourse getBySidAndCid(Integer sid,Integer cid) { PreparedStatement pstmt = null; ResultSet rs = null; StudentScoreCourse ssc = null; String sql = "select s.name sname,r.score,c.name cname " + "from student s " + "left join scores r on s.id = r.s_id " + "left join course c on c.id = r.c_id where s_id = ? and c_id = ?"; try { pstmt = conn.prepareStatement(sql); pstmt.setInt(1,sid); pstmt.setInt(2,cid); rs = pstmt.executeQuery(); while(rs.next()){ String sname = rs.getString("sname"); int score = rs.getInt("score"); String cname = rs.getString("cname"); ssc = new StudentScoreCourse(sname,score,cname); } } catch (SQLException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt,rs); } return ssc; } /** * 查询某一个学生的总分 */ public Integer getCount(Integer id) { Integer score = 0; String sql = "select sum(score) score " + "from scores " + "GROUP BY s_id HAVING s_id = ?"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = conn.prepareStatement(sql); pstmt.setInt(1,id); rs = pstmt.executeQuery(); while (rs.next()) { score = rs.getInt("score"); } } catch (SQLException e) { throw new RuntimeException(e); }finally { JDBCUtil.close(conn,pstmt,rs); } return score; } /** * 查询某一个学生的平均分 */ /** * 按照总分排序 */ public List<Integer> getOrderScore() { PreparedStatement pstmt = null; ResultSet rs = null; List<Integer> scores = new ArrayList<>(); String sql = "select sum(score) score " + "from scores " + "GROUP BY s_id ORDER BY score desc,s_id asc"; try { pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); while(rs.next()) { int score = rs.getInt("score"); scores.add(score); } } catch (SQLException e) { throw new RuntimeException(e); } return scores; } }
案例二:银行信息表(查询、取款...)
package com.jsoft.afternoon.test; import org.junit.Test; /** * 1、创建一张银行信息表 * 字段:主键 银行卡号,余额...... * 2、封装方法,存款,取款,转账,所有的操作最终要数据持久化。 * 3、查询余额的方法。 * 4、开户、修改密码。 */ public class Demo { private AccountDao accountDao = new AccountDao(); @Test public void test01() { // System.out.println(accountDao.out("1102345678", 2000.00)); accountDao.transform("1102345678","1209876543",10000.00); } }
package com.jsoft.afternoon.test; public class Account { private Integer id; private String accountid; private Double balance; public Account() { } public Account(Integer id, String accountid, Double balance) { this.id = id; this.accountid = accountid; this.balance = balance; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAccountid() { return accountid; } public void setAccountid(String accountid) { this.accountid = accountid; } public Double getBalance() { return balance; } public void setBalance(Double balance) { this.balance = balance; } }
package com.jsoft.afternoon.test; import util.JDBCUtil; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class AccountDao { private final Connection conn; { try { conn = JDBCUtil.getConnection(); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SQLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } /** * 转账 */ public Integer transform(String out,String in,Double balance){ // 取款之前要先查询 ResultSet rs = null; PreparedStatement preparedStatement = null; PreparedStatement preparedStatement2 = null; double b = 0; String sql = "select balance from bank where accountid = ?"; try { preparedStatement = conn.prepareStatement(sql); preparedStatement.setString(1,out); rs = preparedStatement.executeQuery(); while(rs.next()) { b = rs.getDouble("balance"); } if(b >= balance) { // 余额够 // 执行修改 conn.setAutoCommit(false); sql = "update bank set balance = balance - ? where accountid = ?"; preparedStatement = conn.prepareStatement(sql); preparedStatement.setDouble(1,balance); preparedStatement.setString((int)2,out); int i = preparedStatement.executeUpdate(); sql = "update bank set balance = balance + ? where accountid = ?"; preparedStatement2 = conn.prepareStatement(sql); preparedStatement2.setDouble(1,balance); preparedStatement2.setString((int)2,in); i = preparedStatement2.executeUpdate(); conn.commit(); return i; }else{ // 余额不够 throw new RuntimeException("余额不足,转账失败"); } } catch (SQLException e) { try { conn.rollback(); } catch (SQLException ex) { throw new RuntimeException(ex); } throw new RuntimeException(e); } finally { JDBCUtil.close(conn,preparedStatement,rs); JDBCUtil.close(null,preparedStatement2); } } /** * 取款 */ public Integer out(String accountid,Double balance) { // 取款之前要先查询 ResultSet rs = null; PreparedStatement preparedStatement = null; double b = 0; String sql = "select balance from bank where accountid = ?"; try { preparedStatement = conn.prepareStatement(sql); preparedStatement.setString(1,accountid); rs = preparedStatement.executeQuery(); while(rs.next()) { b = rs.getDouble("balance"); } if(b >= balance) { // 余额够 // 执行修改 sql = "update bank set balance = balance - ? where accountid = ?"; preparedStatement = conn.prepareStatement(sql); preparedStatement.setDouble(1,balance); preparedStatement.setString((int)2,accountid); int i = preparedStatement.executeUpdate(); return i; }else{ // 余额不够 throw new RuntimeException("余额不足,取款失败"); } } catch (SQLException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,preparedStatement,rs); } } /** * 存款 * @param accountid * @param balance * @return */ public Integer in(String accountid,Double balance) { int i = 0; String sql = "update bank set balance = ? where accountid = ?"; PreparedStatement preparedStatement = null; try { preparedStatement = conn.prepareStatement(sql); preparedStatement.setDouble(1,balance); preparedStatement.setString(2,accountid); i = preparedStatement.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,preparedStatement); } return i; } /** * 开户 * @param accountid * @param balance * @return */ public Integer add(String accountid,Double balance) { int i = 0; String sql = "insert into bank (accountid,balance) values (?,?)"; PreparedStatement preparedStatement = null; try { preparedStatement = conn.prepareStatement(sql); preparedStatement.setString(1,accountid); preparedStatement.setDouble(2,balance); i = preparedStatement.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,preparedStatement); } return i; } }
三、笔记内容
账号登陆
package com.jsoft.morning; import util.JDBCUtil; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; /** * Statement的不足: * 1、大量的字符串拼接,代码可读性降低。 * 2、sql注入 * SQL注入:BUG * 通过字符串的拼接,可以得到一个恒等的sql语句,可以跳过某些判断。 */ public class Ch01 { public static void main(String[] args) { login("zxcvzxcvzxcv","b' or '1' = '1"); } public static void login(String username,String password) { Scanner sc = new Scanner(System.in); // 1.获取连接 Connection conn = null; Statement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.createStatement(); // System.out.println("请输入用户名:"); // String username = sc.next(); // System.out.println("请输入密码:"); // String password = sc.next(); String sql = "select * from user where username = '" + username + "' and password = '" + password + "'"; // StringBuilder strb = new StringBuilder("select * from user where username = "); // strb.append("'").append(username).append("'").append(" and password = '") // .append(password).append("'"); // String sql = strb.toString(); System.out.println("sql:" + sql); rs = stmt.executeQuery(sql); if(rs.next()){ System.out.println("登录成功,欢迎回来:" + username); }else { System.out.println("账号或密码错误!"); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SQLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,stmt,rs); } } }
PreparedStatement
package com.jsoft.morning; import org.junit.Test; import util.JDBCUtil; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * PreparedStatement:预编译(预加载)接口 * 1、通过conn获取的对象 * 2、是Statement接口的子接口 * 3、sql语句中可以传参。用?占位,通过setXXX方法来给?赋值 * 4、提高性能 * 5、避免sql注入 */ public class Ch02 { @Test public void test03() { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); String sql = "select * from user where username = ? and password = ?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1,"aaa"); pstmt.setString(2,"b' or '1' = '1"); rs = pstmt.executeQuery(); if(rs.next()) { System.out.println("登录成功..."); }else { System.out.println("账号或密码错误..."); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SQLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt,rs); } } @Test public void test02() { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); String sql = "select * from scores where s_id = ?"; pstmt = conn.prepareStatement(sql); pstmt.setInt(1,7); rs = pstmt.executeQuery(); while(rs.next()) { int sId = rs.getInt("s_id"); int score = rs.getInt("score"); int cId = rs.getInt("c_id"); System.out.println("学号:" + sId + ",分数:" + score + ",科目号:" + cId); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SQLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt,rs); } } @Test public void test01() { Connection conn = null; PreparedStatement pstmt = null; try { conn = JDBCUtil.getConnection(); String sql = "update teacher set name = ? where id = ?"; // 预编译 pstmt = conn.prepareStatement(sql); // 给占位符赋值,根据位置 pstmt.setString(1,"JJ"); pstmt.setInt(2,6); // 正式执行sql int i = pstmt.executeUpdate(); System.out.println(i); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SQLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt); } } }
元数据
package com.jsoft.afternoon; import org.junit.Test; import util.JDBCUtil; import java.io.IOException; import java.sql.*; public class Ch01 { @Test public void test03() { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); String sql = "select * from user"; pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); // 获取元数据 /* 元数据:表格本身的数据 表格的列名,结果集的列名 */ ResultSetMetaData metaData = rs.getMetaData(); // System.out.println(metaData.getColumnName(1)); // System.out.println(metaData.getColumnName(2)); // System.out.println(metaData.getColumnCount()); // metaData.get for (int i = 1; i <= metaData.getColumnCount() ; i++) { metaData.getColumnName(i); } while (rs.next()) { int id = rs.getInt("id"); String username = rs.getString("username"); String password = rs.getString("password"); System.out.println("id:" + id + ",username:" + username + ",password:" + password); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SQLException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt,rs); } } }
数据库事务
package com.jsoft.afternoon; import org.junit.Test; import util.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * 数据库事务:是数据库的特性 * * Mysql的数据库引擎 * 1.在MySQL中,只有使用了Innodb引擎的数据库才支持事务 * 2.事务处理可以用来维护数据的完整性。保证sql语句要么全部执行, * 要么全部不执行。 * 3. 发生在DML中,增删改。 * * 事务的四大特征ACID * 1、原子性 A。 * 一个事务,要么全部完成,要么全部不完成。 * 2、一致性 C。 * 在事务开始之前和事务结束之后,数据库的完整性没有被破坏。 * 3、隔离性 Isolation * 数据库允许多个事务同时对数据进行处理。每个事务之间是相互隔离。 * 4、持久性 D * 事务结束以后,对数据的增删改是永久性的。 * * 术语:提交事务,回滚事务(事务回滚) * * 1、事务一旦提交,就不可能回滚。 * 2、当一个连接对象被创建时,默认情况下自动提交事务。 * 3、关闭连接时,数据会自动提交事务。 * * 操作事务的步骤: * 1、关闭事务的自动提交 * * 当做出增删改操作,把变化发生在内存中,提交事务,才会真正提交给数据库。 * */ public class Ch02 { @Test public void test01() { Connection conn = null; PreparedStatement pstmt1 = null; PreparedStatement pstmt2 = null; try { conn = JDBCUtil.getConnection(); // 关闭事务的自动提交 // true:开启(默认) false:关闭 // 开启一个事务 conn.setAutoCommit(false); // 把id为1的账户余额-1000 String sql1 = "update bank set balance = balance - 1000 where id = 1"; pstmt1 = conn.prepareStatement(sql1); pstmt1.executeUpdate(); String sql2 = "update bank set balance = balance + 1000 where id = 2"; pstmt2 = conn.prepareStatement(sql2); pstmt2.executeUpdate(); int i = 10 / 0; // 提交事务 conn.commit(); System.out.println("转账成功..."); } catch (Exception e) { try { // 事务回滚 conn.rollback(); } catch (SQLException ex) { throw new RuntimeException(ex); } throw new RuntimeException(e); } finally { JDBCUtil.close(conn,pstmt1); JDBCUtil.close(null,pstmt2); } } }