解决办法:
端口号错误。
初学者可以这么搞,坚持半年,效果显著。
我们需要从外往里面依次释放,与你声明的时候相反。就像人们穿衣服一样,然后脱衣服,效果类似。
遍历数组,需要判断,有些语句不需要赋值。所以需要先判断是否需要赋值,所以先判断是否为空。
系统架构的解耦,主要是为了今后的扩展。因为 今天的项目 需求变更多,项目大。
表示层:jsf structs2.0 门窗
框架: spring 骨骼
持久层:hibernate
层与层之间是松耦合的。
三层:
Web层 , service层, DAO层 表示层,服务层,数据访问层
Web层调用service层;服务层调用dao层。
必须先有,才能调用。所以,编程从后往前。
生产与使用分离。想象一下 主板与内存条的关系。
无缘无故多搞出来一层,其目的是上面一层DAO层几乎不怎么动,而service层只需调用即可。也就是说,我们多了一个interface层。
访问数据库的工具在util中,我如何在impl中使用工具
错误:
你在程序中操作的长度大于在数据库当中的长度
因为我在设计数据库表的时候,sex的长度只有1,而我在程序里面赋值为男,为两个字符。所以,长度不一致。
当然,还有其他一些错误:比如长度不一致,顺序不一致。 ? 与 param必须严格一致。一个? 对应一个变量。一个参数,这样才可以。
新闻栏目添加 、 修改、查询()、删除(新闻栏目下面有很多新闻内容,先删除内容,再删除栏目)
下面讲讲规范:
一般 我们开发分为几层。DAO层 一般放接口
下面以UserInfo这张表为例,讲讲MVC金典操作。
实体类的建立,依据数据库表中的字段而来的。下面是这些数据库表中的字段名。
然后,通过eclipse 生成getter 和 setter 方法。程序如下面所示。
package com.buu.news.day3.entity; public class UserInfo { private String userID; private String UserRealName; private String sex; private String birth; private String famillyaddress; private String email; private String tel; private String userLoginName; private String regDate; private String userPasword; private String conform; private String flag; public String getUserID() { return userID; } public void setUserID(String userID) { this.userID = userID; } public String getUserRealName() { return UserRealName; } public void setUserRealName(String userRealName) { UserRealName = userRealName; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getBirth() { return birth; } public void setBirth(String birth) { this.birth = birth; } public String getFamillyaddress() { return famillyaddress; } public void setFamillyaddress(String famillyaddress) { this.famillyaddress = famillyaddress; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } public String getUserLoginName() { return userLoginName; } public void setUserLoginName(String userLoginName) { this.userLoginName = userLoginName; } public String getRegDate() { return regDate; } public void setRegDate(String regDate) { this.regDate = regDate; } public String getUserPasword() { return userPasword; } public void setUserPasword(String userPasword) { this.userPasword = userPasword; } public String getConform() { return conform; } public void setConform(String conform) { this.conform = conform; } public String getFlag() { return flag; } public void setFlag(String flag) { this.flag = flag; } } 建立UserInfo这个表的接口层,定义一些个操作,我们称之为用户操作接口。主要完成 用户登录、删除、修改、查询和插入新的用户等操作。 操作如下: package com.buu.news.day3.dao; import java.sql.ResultSet; import com.buu.news.day3.entity.UserInfo; /* * 用户操作接口 * 1、登录操作 * 2、删除操作 * 3、修改操作 * 4、查询操作 * 5、插入新的用户操作 */ public interface UserDao { //需要先定义一个封装用户的实体类 /* *1、 用户登录操作 * 参数:用户对象 * 返回值:true :登录成功 * false:登录失败 */ public boolean userLogin(UserInfo user); /* *2、 删除用户操作 * 参数:用户对象 * 返回值:int : 0:不成功 * !0 :成功 */ public int userDelete(UserInfo user); /* *3、 用户修改 * 参数:用户对象 * 返回值:int : 0:不成功 * !0 :成功 */ public int userUpdate(UserInfo user); /* *4、 用户插入 * 参数:用户对象 * 返回值:int : 0:不成功 * !0 :成功 */ public int userInsert(UserInfo user); /* *5、 用户查询 * 参数:用户对象 * 返回值:resultset集合 * */ public ResultSet userSelect(UserInfo user); } 建立UserServiceDao的接口层,此层与上面的代码一样。只是增加了一个接口而已。 建立UserDaoImpl ,此类是UserDao的实现类,实现UerDao接口。 代码如下:(里面有增删改查) package com.buu.news.day3.dao.impl; import java.sql.ResultSet; import com.buu.news.day3.dao.UserDao; import com.buu.news.day3.entity.UserInfo; import com.buu.news.day3.util.ConnDB; public class UserDaoImpl extends ConnDB implements UserDao { //public ConnDB conn = new ConnDB(); public int userDelete(UserInfo user) { // TODO Auto-generated method stub String sql = "delete from userInfo where userID = ?"; //占位符? String[] param = {user.getUserID()}; //调用方法必须传数组 int rtn = this.executeSQL(sql, param); if(rtn > 0) System.out.println("删除成功"); else System.out.println("删除失败"); return rtn; } public int userInsert(UserInfo user) { // TODO Auto-generated method stub String sql = "insert into userInfo values(?,?,?,?,?,?,?,?,?,?,?)"; String[] param = {user.getUserRealName(),user.getSex(),user.getBirth(),user.getFamillyaddress(),user.getEmail(),user.getTel(),user.getUserLoginName(),user.getRegDate(),user.getUserPasword(),user.getConform(),user.getFlag()}; int rtn = this.executeSQL(sql, param); if(rtn > 0) System.out.println("插入成功"); else System.out.println("插入失败"); return rtn; } public boolean userLogin(UserInfo user) { // TODO Auto-generated method stub return false; } public ResultSet userSelect(UserInfo user) { // TODO Auto-generated method stub String sql = "select * from userInfo where userID = ?"; String[] param = {user.getUserID()}; ResultSet rs = this.executeSelectSQL(sql,param); if(rs != null) System.out.println("查询成功"); else System.out.println("查询失败"); return rs; } public int userUpdate(UserInfo user) { // TODO Auto-generated method stub String sql = "update userInfo set userRealName = ?,sex = ?,birth = ?,fimallyAddress = ?,Email=?"; sql += ",Tel=?,userLoginName=?,regDate=?,userPassword=?,confirm1=?,flog=? where userID=?"; String[] param = {user.getUserRealName(),user.getSex(),user.getBirth(),user.getFamillyaddress(),user.getEmail(),user.getTel(),user.getUserLoginName(),user.getRegDate(),user.getUserPasword(),user.getConform(),user.getFlag(),user.getUserID()}; int rtn = this.executeSQL(sql, param); if(rtn > 0) System.out.println("更新成功"); else System.out.println("更新失败"); return rtn; } } 其中,有几个关键的地方,需要提一下 关键地方一:this.executeSelectSQL(sql,param); 和 this.executeSQL(sql, param); 这两句是增删改 与 查 分家的地方。我们可以定义工具类来实现顶层操作。 这些顶层操作是工具,是可以重复利用的代码逻辑。 关键地方二:为啥用this,其实这里面我们完全可以用类的实例化,然后再调用对象.方法来实现,这里却用到了上面的形式。我们在实现此接口的同事,还可以 继承工具类,这样的话,我们就可以不用实例化了,这样的话,代码量可以进一步减少。健壮性又有所提高。 工具类 ConnDB 代码如下: package com.buu.news.day3.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /* * 数据库基本操作 * 1、获取连接对象 * 2、释放相关资源 * 3、数据库增删改查 */ public class ConnDB { //定义数据连接字符串,访问数据库用户名和密码 public final static String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; public final static String url = "jdbc:sqlserver://localhost:1433;DataBaseName=NewsSystem"; public final static String dbName = "sa"; public final static String dbPa = "123456"; /*1、获取数据库连接对象 * 返回值:connection对象 */ public Connection getConn() { Connection conn = null; try { Class.forName(driver); conn = DriverManager.getConnection(url, dbName, dbPa); System.out.println("数据库连接成功");//提示的 } catch (Exception e) { //为了使抛出的异常减少,抛出ClassNotFound的父类即可 // TODO Auto-generated catch block e.printStackTrace(); }//必须要有异常处理,增加程序的健壮性 return conn; } /*释放连接数据库的所有资源 * 资源包括:连接对象connection,statement对象,preparement对象,resultset对象 */ public void closeAll(Connection conn, Statement stmt, PreparedStatement pstmt, ResultSet rs) { try { if(rs!=null) rs.close(); if(pstmt!=null) pstmt.close(); if(stmt!=null) stmt.close(); if(conn!=null) conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * 执行更新操作:插入、修改、删除(会有成功和失败) * 参数:sql语句; param:sql赋值参数 * 返回值:int类型。sql语句对数据库影响的行数 * 0:含义:插入、修改、删除失败 */ public int executeSQL(String sql, String[] param) { Connection conn = null; PreparedStatement pstmt = null; int rtn = 0; //处理sql语句,执行sql语句 conn = this.getConn();// 里面已经有链接了 try { pstmt = conn.prepareStatement(sql);//sql语句只有一条,但赋的值不只一条,避免重复造轮子 if(param != null) { for(int i = 0; i < param.length; ++i) { pstmt.setString(i+1, param[i]);//为预编译的sql语句赋参数,语句下标从1开始。(数组里面的个数 就是 sql语句中占位符的个数,不过sql语句里面的下标从1开始,数组下标从0开始) } } //执行sql语句 rtn = pstmt.executeUpdate(); //只有他返回int类型参数 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return rtn; } /* * 执行查询操作 * 参数:sql语句; param:sql赋值参数 * 返回值:ResultSet类型 * */ public ResultSet executeSelectSQL(String sql, String[] param) { Connection conn = null; PreparedStatement pstmt = null; //处理sql语句,执行sql语句 conn = this.getConn();// 里面已经有链接了 ResultSet rtn = null; try { pstmt = conn.prepareStatement(sql);//sql语句只有一条,但赋的值不只一条,避免重复造轮子 if(param != null) { for(int i = 0; i < param.length; ++i) { pstmt.setString(i+1, param[i]);//为预编译的sql语句赋参数,语句下标从1开始。 } } //执行sql语句 rtn = pstmt.executeQuery(); //只有他返回int类型参数 } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return rtn; } } 创建数据库访问接口 ,这里 为UserServiceDaoImpl ,是UserServiceDao接口类的实现。 程序里面只是一个接口而已,先实例化,然后返回一些个值。 package com.buu.news.day3.service.impl; import java.sql.ResultSet; import com.buu.news.day3.dao.UserDao; import com.buu.news.day3.dao.impl.UserDaoImpl; import com.buu.news.day3.entity.UserInfo; import com.buu.news.day3.service.UserServiceDao; public class UserServiceDaoImpl implements UserServiceDao { //创建数据库访问接口 private UserDao userdao = new UserDaoImpl(); public int userDelete(UserInfo user) { // TODO Auto-generated method stub int rtn = userdao.userDelete(user); return rtn; } public int userInsert(UserInfo user) { // TODO Auto-generated method stub int rtn = userdao.userInsert(user); return rtn; } public boolean userLogin(UserInfo user) { // TODO Auto-generated method stub boolean rtn = userdao.userLogin(user); return rtn; } public ResultSet userSelect(UserInfo user) { // TODO Auto-generated method stub ResultSet rs = userdao.userSelect(user); return rs; } public int userUpdate(UserInfo user) { // TODO Auto-generated method stub int rtn = userdao.userUpdate(user); return rtn; } } 以上搞定了 业务逻辑层调用 数据访问层, 后面开始搞 表示层调用 业务逻辑层。