JDBCday01
-
JDBC编程六步
-
注册驱动:通知jiava程序我们即将要谅解的是哪个品牌的数据库
-
获取数据库连接:java进程和mysql进程,两个进程之间的通道开启了,
-
获取数据库操作对象:这个对象很重要,用这个对象执行Sql
-
执行SQl语句:执行CRUD操作
-
处理查询结果集:如果第四步是select语句,才有这个第五步
-
释放资源:关闭所有的资源
-
-
可以根据表格中数据的特定类型去除如 (getint(1), getstring(2)),也可以全部用STring类型去除(getString) 数据表示,查找第一个,查找第二个
-
get后面可以跟字符串(get("enema"))这样代表取出列名叫ename的下面的值 注意!必须是查询结果的列明,不是表格的列明因为可能取别名
-
编写我的第一条JDBC语句
-
public static void main(String[] args) { Connection conn = null; Statement stmt = null; ResultSet se = null; try { //静态代码块的第二种注册方式 Class.forName("com.mysql.jdbc.Driver"); //连接数据库 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //获取数据库操作对象 stmt = conn.createStatement(); //操作数据库 String sql = "select e.ename as '员工',d.ename as '领导' from emp e left join emp d on e.mgr = d.empno"; se = stmt.executeQuery(sql); //遍历输出结果 while(se.next()){ String s = se.getString("员工"); String b = se.getString("领导"); System.out.println(s+","+b); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { if (se!=null){ try { se.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt!=null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
首先通过
-
Class.forName()来注册,
-
通过DriverManager.get Contection()来连接数据库
-
通过creatstatement()获取数据库对象
-
在执行sql语句
-
遍历输出数据
-
-
采用资源绑定器!
public static void main(String[] args) { //搞一个资源绑定器 ResourceBundle bundle = ResourceBundle.getBundle("db"); String driver = bundle.getString("driver"); String ur = bundle.getString("url"); String use = bundle.getString("user"); String pass = bundle.getString("password"); Connection conn = null; Statement stmt = null; ResultSet se = null; try { //静态代码块的第二种注册方式 Class.forName(driver); //连接数据库 conn = DriverManager.getConnection(ur,use,pass); //获取数据库操作对象 stmt = conn.createStatement(); //操作数据库 String sql = "select e.ename as '员工',d.ename as '领导' from emp e left join emp d on e.mgr = d.empno"; se = stmt.executeQuery(sql); //遍历输出结果 while(se.next()){ String s = se.getString("员工"); String b = se.getString("领导"); System.out.println(s+","+b); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { if (se!=null){ try { se.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt!=null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
-
首先在src下新建一个db.properties文件 里面写入driver=com.mysql.jdbc.Driver;
url=jdbc:mysql://localhost:3306/bjpowernode
user=root
password=xjj168
-
在class中调用Resourcebundle bundle = Resourcebundle.getBundle(“写入刚才创建的文件的地址但是注意不加properties”);
-
之后通过文件的k值找出文件的v值
-
这样之后的注册文件都可以用找出的值来代替,
-
这样以后该数据库很方便,只需要把配置文件的数据库改一下
-
-
随意输入一个用户名和密码,登录成功了,这种现象被称为sql注入现象
-
导致sql注入的根本原因是什么?怎么解决?
导致SQl注入的根本原因是: 用户不是一般的用户,用户是懂得程序的,输入的用户名信息,以及密码信息中含有SQl语句的关键字,这个SQl语句的原建筑和底层的SQl语句进行字符串拼接,导致原SQl语句被扭曲了,最主要的是原因是:用户提供的信息参与了SQl语句的编译
主要因素是:这个程序先进行的字符串的拼接,然后再进行的SQl语句的编译,正好被注入
-
怎么比肩sql语句的注入:
采用java.sql.preparedStatement接口(代替Statement),该接口的特点是:先进行了SQl语句的编译,然后在进行SQl语句的传值
-
优点是:避免了SQl语句的注入
-
缺点是:无法在进行SQl语句的拼接,只能给SQl语句传值
java.sql.Statement接口的特点:先进性字符串的拼接,然后在进行SQl语句的编译
-
优点是:使用Statement可以进行SQl语句的拼接
-
缺点是:可能存在注入现象
-
-
使用Statement接口的代码
Connection conn = null; Statement stmt =null; ResultSet rs = null; Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //获取数据库 stmt = conn.createStatement(); //执行sql语句 String sql = "select ename,epassword from t_user where ename = '"+loginname+"' and epassword = '"+loginpassword+"'"; //得到结果 rs = stmt.executeQuery(sql);
先进行了字符串的拼接,在进行了字符串的编译
-
使用prepareStatement接口
Connection conn = null; prepareStatement stmt =null; ResultSet rs = null; Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //获取预编译的数据库操作对象(?是一个占位数,表示一个值) String sql = "select ename,epassword from t_user where ename = ? and epassword = ?"; stmt = conn.prepareStatement(sql); //执行给占位符传值 stmt.getString(1,loginname)//如果是INt类型就是getint,1这个数字表示第几个问号,并将后面的值传给哪个问号 stmt.getString(1,loginpassword) //得到结果 rs = stmt.executeQuery();//这里也不需要在将sql语句传入
占位符?的两边不能有单引号,
-
Statement接口(父)和prepareStatement接口(子)是父子关系
-
public class Test{ public static void main(String[] args){ System.out.println("hellow,word"); } }
-
什么时候用Statement 什么时候用prepareStatement呢? 根据情况来定
-
比如我现在要用户输入desc,或者asc 来控制显示价钱的排列顺序
-
如果我用prepareStatement,
Connection conn = null; prepareStatement stmt =null; ResultSet rs = null; //先注册 class.forName("com.mysql.jdbc.Driver") //连接数据库 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //获取预编译的数据库操作对象(?是一个占位数,表示一个值) String sql = "select ename,sal from emp order by sal ?"; stmt = conn.prepaerStatement(sql); //传值 stmt.getString(1,用户的输入) //这个时候就出现了问题,因为用户输入的是字符串,所有这个赋值给上面问号的时候会自动加上单引号,但是sql语句里面,desc或者asc 不能加单引号,所以会出错 只能用Statement
-
-
用Statement
Connection conn = null; Statement stmt =null; ResultSet rs = null; //注册 Class.forName("com.mysql.jdbc.Driver"); //连接数据库 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //获取数据库对象 stmt = conn.createStatement(); //执行sql语句 String sql = "select ename,sal from emp order by sal ?"; //执行后得到一个结果 rs = stmt.executeQuery(sql);
-
采用Scanner接受用户输入的名字于数据对比
public static void main(String[] args) { //创建用户键盘输入 Scanner sc = new Scanner(System.in); System.out.println("请输入你的用户名"); String sname = sc.next(); System.out.println("请输入你的密码"); String spassword = sc.next(); User user = userjudeg(sname,spassword); if (user!=null){ System.out.println(user); }else { System.out.println("查无此人"); } } private static User userjudeg(String sname,String spassword){ Connection conn =null; PreparedStatement stmt = null; ResultSet rs =null; try { //注册 Class.forName("com.mysql.jdbc.Driver"); //连接数据库 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //写sql语句 String sql = "select * from t_user where ename = ? and epassword = ?"; stmt = conn.prepareStatement(sql); //赋值 stmt.setString(1,sname); stmt.setString(2,spassword); //执行sql语句,得到结果集 rs = stmt.executeQuery(); //处理结果 while(rs.next()){ int id = rs.getInt(1); String cname = rs.getString(2); String pwd = rs.getString(3); //封装对象 User user = new User(id,cname, pwd); return user; } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { 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(); } } } return null; } }
-
如何向数据量表格中插入图片(注意!对数据库表格数据进行修改用update,对表格的名字呀,数据类型修改用alter table 表名 modify 想要修改的类型名 修改类型名)
Connection conn= null; PreparedStatement stmt =null; try { //注册 Class.forName("com.mysql.jdbc.Driver"); //连接数据库 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //写sql语句 String sql ="insert into t_photo(id,photo)values(1,?)"; stmt = conn.prepareStatement(sql); //赋值 //创建inputSreanm InputStream is = new FileInputStream(new File("D:/photo/背景.jpg")); stmt.setBlob(1,is); //执行sql语句 得到结果集 int count = stmt.executeUpdate(); //处理结果 System.out.println(count>0?"插入成功":"插入失败"); } catch (ClassNotFoundException | SQLException | FileNotFoundException e) { e.printStackTrace(); }finally { if (stmt!=null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
-
在插入的时候输出自动增长的主键的值
Connection conn = null; prepareStatement stmt =null; ResultSet rs = null; Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","xjj168"); //获取预编译的数据库操作对象(?是一个占位数,表示一个值) String sql = "insert into t_user(ename,epassword)values(?,?)"; stmt = conn.prepareStatement(sql,Statement.RETURN_GRNERATEN_KEYS); //这里要在传入一个值 //执行给占位符传值 stmt.getString(1,"zhoujielun")//如果是INt类型就是getint,1这个数字表示第几个问号,并将后面的值传给哪个问号 stmt.getString(1,"777") //得到结果 int i = stmt.executeUpdate(); System.out.println(i>0?"成功":"失败"); rs = stmt.executeQuery();//这里也不需要在将sql语句传入 if(rs.next()){ Object object = rs.getObject(1) System.out.println(object); //就能输出主键自动增长的这个值 }