一个要求:转载注明出处
一、JDBC?什么玩应?
JDBC(Java Database connectivity),java数据库连接,java中用来规范客户端如何访问数据库的应用程序接口。简单讲,用来执行sql语句的一类java API。
那我们了解了JDBC用来和数据进行连接,并且能够执行sql语句,是不是要学学sql语句呢?
那么请你关掉这个网页,百度搜索sql语句。
(开玩笑的啊,别别别!别走啊!)
来都来了,怎么可能不知道sql语句呢?(强行给自己加戏)
然后,JDBC实现增删查改需要做什么准备呢?
我们都知道,做个项目是有很多准备步骤的,就像女孩子洗澡一样,先放水,试水温,倒点精油,撒点花瓣,然后不可描述的洗了起来,都是我脑补的。
那我们的准备是什么嘞?
首先,打开IDEA,你也可以用别的,然后直接右上角关掉网页吧,不然会很累的(对于新手来说,因为我经历过)
然后,创建一个maven项目,上一篇文章介绍过了。
再然后,你就可以开始写代码啦。
那我们实现增删查改是对什么操作嘞?当然是数据库啦!
所以,打开你的mysql/......等等等什么都好,这里推荐用Navicat for MySQL,可视化软件,新手超适合~(收费软件,自己想办法解决,关键词:破解)
右键最上面的连接用户名,然后新建数据库,随便取个名,我取得是mission1 。
然后新建了个表,填上数据什么的,这些自己想办法解决
这是我新建的字段,参考就好,这样字段太多了,你们适当减少,还可以减少后续代码压力,并且增强学习效果。
然后是我的项目结构
从结构上看,里面有Student类,对应数据库里的表;JdbcUnit类,这个就好玩儿了,里面东西很杂,一会介绍,总之是个重要的东西;StudentDAO接口和其实现类StudentDAOImpl,这里涉及DAO层的概念,也放一放,一会讲;还有个StudentTest类,涉及Junit单元测试的一点内容,可以理解为我们平时写一个驱动程序,用来测试方法什么的有没有问题。
结构上分析,我们有数据库中的数据了(Student类),但是要增删查改,怎么办?首先就要连接数据库。
开始讲JdbcUnit了啊!
JdbcUnit.java
package com.ptteng.web.util; import java.sql.*; /** * Created by Administrator on 2017/06/28. */ public class JdbcUtil { //定义数据库URL语句 private static final String url = "jdbc:mysql://localhost:3306/mission1?" + "user=root&password=yubotao9527&useUnicode=true&characterEncoding=UTF8"; //利用单例模式创建Connection对象 private static Connection conn = null; //加载驱动 public static Connection getConn(){ if(conn == null){ try{ Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url); } catch(ClassNotFoundException e){ //TODO Auto-generated catch block e.printStackTrace(); } catch(SQLException e){ //TODO Auto-generated catch block e.printStackTrace(); } } return conn; } //释放资源方法 public static void release(ResultSet rs, PreparedStatement pstmt){ if(rs!=null){ try{ rs.close(); } catch(SQLException e){ //TODO Auto-generated catch block e.printStackTrace(); } } if(pstmt!=null){ try{ pstmt.close(); } catch(SQLException e){ //TODO Auto-generated catch block e.printStackTrace(); } } } }
首先第一条语句,定义了url,它用来连接数据库的,url语句其实就是像我们平时用的网址链接一样,能够通过这个地址找到你想要的东西。
接着单例模式创建了connection对象,这个对象用来和数据库进行连接,百度单例模式去~
然后加载驱动,可以看到class.forname()方法:加载参数指定的类,并且初始化它。
不用理解太多,就知道是连接数据库用的,以后想知道的时候记得百度呦~
然后conn对象利用DriverManager.getConnection()方法使用之前定义的url语句和数据库建立连接。
然后就是抛异常了,不知道就去补知识,我也不太懂。反正class不存在和SQL语句异常都是要报错的。
然后返回conn对象,这里就是连接数据库喽。
然后我们看到第二块代码,释放资源。释放哪些资源呢?
ResultSet和PreparedStatement这两个对象rs和pstmt
首先介绍PreparedStatement,PreparedStatement继承Statement,是一个对象,用来创建sql语句且该sql语句中可具有一个或多个IN参数,每个IN参数都有一个?做占位符,且这个对象拥有setXXX的方法。executeUpdate也是一个方法,执行update,insert,delete等sql语句,用于返回执行成功的sql语句条数。
ResultSet对象具有指向当前数据行的指针;executeQuery方法执行给定语句,返回单个ResultSet对象。
诶,这里的executeUpdate和executeQuery方法也没见到啊,别急,马上来!
来之前,我们先来一下别的东西,嘿嘿嘿~
我们一定要先建好什么呢?什么最不可或缺呢?
当然是Student对象啦!
Student.java
package com.ptteng.web.domain; /** * Created by Administrator on 2017/06/28. */ public class Student { private String SName; private Integer QQ; private String Style; private String Time; private String School; private Integer SNumber; private String Link; private String Dream; private String FBro; private String YBro; private String WhereKnow; private Integer ID; private Integer create_at; private Integer update_at; public Student(){ super(); //TODO Auto-generated constructor stub } public Student(String SName,Integer QQ,String Style,String Time,String School,Integer SNumber,String Link,String Dream, String FBro,String YBro,String WhereKnow,Integer ID,Integer create_at,Integer update_at){ super(); this.SName = SName; this.QQ = QQ; this.Style = Style; this.Time = Time; this.School = School; this.SNumber = SNumber; this.Link = Link; this.Dream = Dream; this.FBro = FBro; this.YBro = YBro; this.WhereKnow = WhereKnow; this.ID = ID; this.create_at = create_at; this.update_at = update_at; } public String getSName(){ return SName; } public void setSName(String SName){ this.SName = SName; } public Integer getQQ(){ return QQ; } public void setQQ(Integer QQ){ this.QQ = QQ; } public String getStyle(){ return Style; } public void setStyle(String Style){ this.Style = Style; } public String getTime(){ return Time; } public void setTime(String Time){ this.Time = Time; } public String getSchool(){ return School; } public void setSchool(String School){ this.School = School; } public Integer getSNumber(){ return SNumber; } public void setSNumber(Integer SNumber){ this.SNumber = SNumber; } public String getLink(){ return Link; } public void setLink(String Link){ this.Link = Link; } public String getDream(){ return Dream; } public void setDream(String Dream){ this.Dream = Dream; } public String getFBro(){ return FBro; } public void setFBro(String FBro){ this.FBro = FBro; } public String getYBro(){ return YBro; } public void setYBro(String YBro){ this.YBro = YBro; } public String getWhereKnow(){ return WhereKnow; } public void setWhereKnow(String WhereKnow){ this.WhereKnow = WhereKnow; } public Integer getID(){ return ID; } public void setID(Integer ID){ this.ID = ID; } public Integer getCreate_at(){ return create_at; } public void setCreate_at(Integer create_at){ this.create_at = create_at; } public Integer getUpdate_at(){ return update_at; } public void setUpdate_at(Integer update_at){ this.update_at = update_at; } @Override public String toString(){ return "Student[SName="+SName+",QQ="+QQ+",Style="+Style+",Time="+Time+",School="+School+",SNumber="+SNumber+",Link="+Link+",Dream="+Dream+"," + "FBro="+FBro+",YBro="+YBro+",WhereKnow="+WhereKnow+",ID="+ID+",create_at="+create_at+",update_at="+update_at+"]"; } }
这里面一堆set、get的方法,还有实例变量什么的
但是有个明晃晃的@Override是不是感觉扎眼睛?那它是干什么的嘞?
这个标注是用来重载的,具体百度哦~
好,Sutdent类也介绍了,是不是该回答前面的问题呢?
看看我们还有什么问题没解决啊:哦,executeUpdate和executeQuery方法!
那我们就先放一放把,先讲一个更重要的概念,就是DAO层。
之前是不是就感觉StudentDAO接口和StudentDAOImpl这两个怪怪的?
为什么讲DAO层,DAO层是啥啊?能吃么?
不能吃,能玩!
看我给你玩一个。
DAO层(Data Access Object),一个面向数据库的接口,用来连接底层数据库和上层程序的;这个接口里放的可是增删查改的方法啊!重要吧!
既然是接口,那么就把方法定义就好喽~
StudentDAO.java
package com.ptteng.web.dao; import com.ptteng.web.domain.Student; /** * Created by Administrator on 2017/06/28. */ public interface StudentDAO { boolean insert(Student entity);//增 boolean deleteById(Integer ID);//删 boolean updateById(Student entity);//改 Student selectById(Integer ID);//查 }然后就要写接口的实现类啦~
StudentDAOImpl.java
package com.ptteng.web.dao; import com.mysql.jdbc.JDBC4Connection; import com.ptteng.web.domain.Student; import com.ptteng.web.util.JdbcUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * Created by Administrator on 2017/06/28. */ public class StudentDAOImpl implements StudentDAO { private static Connection conn; private PreparedStatement pstmt; private ResultSet rs; //增 public boolean insert(Student entity){ //声明返回值变量 boolean flag = false; //获取连接对象 conn = JdbcUtil.getConn(); //sql语句 String sql = "insert into businesstable(SName,QQ,Style,Time,School,SNumber,Link,Dream,FBro,YBro,WhereKnow,create_at)" + " values(?,?,?,?,?,?,?,?,?,?,?,?)"; try{ //由sql语句创建预处理对象 pstmt = conn.prepareStatement(sql); //占位符赋值 int index = 1; pstmt.setObject(index++,entity.getSName()); pstmt.setObject(index++,entity.getQQ()); pstmt.setObject(index++,entity.getStyle()); pstmt.setObject(index++,entity.getTime()); pstmt.setObject(index++,entity.getSchool()); pstmt.setObject(index++,entity.getSNumber()); pstmt.setObject(index++,entity.getLink()); pstmt.setObject(index++,entity.getDream()); pstmt.setObject(index++,entity.getFBro()); pstmt.setObject(index++,entity.getYBro()); pstmt.setObject(index++,entity.getWhereKnow()); pstmt.setObject(index++,entity.getCreate_at()); //执行更新 int i = pstmt.executeUpdate(); if(i>0){ flag = true; } } catch(SQLException e){ //TODO Auto-generated catch block e.printStackTrace(); } //释放资源 JdbcUtil.release(rs,pstmt); return flag; } //删 public boolean deleteById(Integer ID) { //声明变量返回 boolean flag = false; //获取连接对象 conn = JdbcUtil.getConn(); //sql语句 String sql = "delete from businesstable where ID = ?"; try{ pstmt = conn.prepareStatement(sql); int index = 1; pstmt.setObject(index++,ID); int i = pstmt.executeUpdate(); if(i>0){ flag = true; } } catch(SQLException e){ //TODO Auto-generated catch block e.printStackTrace(); } JdbcUtil.release(rs,pstmt); return flag; } //改 public boolean updateById(Student entity){ //声明返回值变量 boolean flag = false; //获取连接对象 conn = JdbcUtil.getConn(); //sql语句 String sql = "update businesstable set SName=?,QQ=?,Style=?,Time=?,School=?,SNumber=?,Link=?,Dream=?," + "FBro=?,YBro=?,WhereKnow=?,update_at=? where ID = 4"; try{ //由sql语句创建预处理对象 pstmt = conn.prepareStatement(sql); //占位符赋值 int index = 1; pstmt.setObject(index++,entity.getSName()); pstmt.setObject(index++,entity.getQQ()); pstmt.setObject(index++,entity.getStyle()); pstmt.setObject(index++,entity.getTime()); pstmt.setObject(index++,entity.getSchool()); pstmt.setObject(index++,entity.getSNumber()); pstmt.setObject(index++,entity.getLink()); pstmt.setObject(index++,entity.getDream()); pstmt.setObject(index++,entity.getFBro()); pstmt.setObject(index++,entity.getYBro()); pstmt.setObject(index++,entity.getWhereKnow()); pstmt.setObject(index++,entity.getUpdate_at()); //执行更新 int i = pstmt.executeUpdate(); if(i>0){ flag = true; } } catch(SQLException e){ //TODO Auto-generated catch block e.printStackTrace(); } //释放资源 JdbcUtil.release(rs,pstmt); return flag; } //查 public Student selectById(Integer ID){ //声明返回值变量 Student entity = new Student(); //获取连接 conn = JdbcUtil.getConn(); //sql语句 String sql = "select * from businesstable where ID = ?"; try{ pstmt = conn.prepareStatement(sql); int index = 1; pstmt.setObject(index++,ID); //执行更新 rs = pstmt.executeQuery(); if(rs.next()){ entity.setSName(rs.getString("SName")); entity.setQQ(rs.getInt("QQ")); entity.setStyle(rs.getString("Style")); entity.setTime(rs.getString("Time")); entity.setSchool(rs.getString("School")); entity.setSNumber(rs.getInt("SNumber")); entity.setLink(rs.getString("Link")); entity.setDream(rs.getString("Dream")); entity.setFBro(rs.getString("FBro")); entity.setYBro(rs.getString("YBro")); entity.setWhereKnow(rs.getString("WhereKnow")); entity.setID(rs.getInt("ID")); entity.setCreate_at(rs.getInt("create_at")); entity.setUpdate_at(rs.getInt("update_at")); } } catch(SQLException e){ //TODO Auto-generated catch block e.printStackTrace(); } JdbcUtil.release(rs,pstmt); return entity; } }
我们看到除了selectById中出现了executeQuery方法外,其他方法中都是executeUpdate方法。(其他地方看不懂自行百度)
前面说了,executeUpdate也是一个方法,执行update,insert,delete等sql语句,用于返回执行成功的sql语句条数。所以你看,select就没用。
而executeQuery方法执行给定语句,返回单个ResultSet对象。ResultSet对象用来干什么,返回指针的!所以逻辑就通了不是?
最后,前面方法也写了,什么都做了,还剩一个类了——StudentTest
StudentTest.java
package com.ptteng.web; import org.junit.Test; import com.ptteng.web.dao.StudentDAO; import com.ptteng.web.dao.StudentDAOImpl; import com.ptteng.web.domain.Student; /** * Created by Administrator on 2017/06/28. */ public class StudentTest { StudentDAO sDAO = new StudentDAOImpl(); @Test public void insert(){ Student entity = new Student(); entity.setSName("测试"); entity.setQQ(1111); entity.setStyle("java"); entity.setTime("2017.7.2"); entity.setSchool("GZU"); entity.setSNumber(1902); entity.setLink("www."); entity.setDream("dddd"); entity.setFBro("zy"); entity.setYBro("zy"); entity.setWhereKnow("zh"); //entity.setID(20); entity.setCreate_at(20170705); //entity.setUpdate_at(20170705); boolean flag = sDAO.insert(entity); if(flag){ System.out.println("插入成功"); }else{ System.out.println("插入失败"); } } @Test public void selectById(){ Student entity = sDAO.selectById(1); System.out.println(entity.toString()); } @Test public void updateById(){ Student entity = sDAO.selectById(4); entity.setSName("测试2"); entity.setQQ(2222); entity.setUpdate_at(20170705); boolean flag = sDAO.updateById(entity); if(flag){ System.out.println("更新成功"); } else{ System.out.println("更新失败"); } } @Test public void deleteById(){ boolean flag = sDAO.deleteById(27); if(flag){ System.out.println("删除成功"); }else{ System.out.println("删除失败"); } } }
看@Test是不是扎眼,这也是标注哦,看引用的包,是不是有个junit的?
junit是干啥的?简单说单元测试,复杂说,自己百度junit去。
@Test就是用来测试的。
我也是只学习了几天,只懂了点皮毛,如果有什么错误的地方,欢迎指正!
好了,到这里所有代码都说完了,自己改一改,敲一敲,看看能不能完成这个项目呢?
加油哦~
PS:记得自己先在数据库里插数据,怎么插?百度去。然后不要直接抄,那样你肯定报错,因为我的数据库里有啥数据你知道么?我那些参数是根据我的数据库来的,一定要自己敲哦~