这里报异常了
来源:5-1 删除分类修改关联商品的外键
MasonM
2019-06-01 16:47:35
老师,我使用了
public void update(Product product) { Connection conn=null; PreparedStatement pstmt=null; try { //获得链接 conn=JDBCUtils.getConnection(); //编写SQL String sql = "UPDATE product SET pname=?,author=?,price=?,description=?,filename=?,path=?,cid=? WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体属性 pstmt.setString(1,product.getPname()); pstmt.setString(2,product.getAuthor()); pstmt.setDouble(3,product.getPrice()); pstmt.setString(4,product.getDescription()); pstmt.setString(5,product.getFilename()); pstmt.setString(6,product.getPath()); pstmt.setInt(7,new Integer(product.getCategory().getCid())); //或者:这样才能设置NULL值 因为int是没有NULL值的 //pstmt.setObject(7,product.getCategory().getCid()); pstmt.setInt(8,product.getPid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.release(pstmt,conn); } }
下面这样去设置null值,为什么还会报异常呢?
pstmt.setInt(7,new Integer(product.getCategory().getCid()));
\
如果我使用
pstmt.setObject(7,product.getCategory().getCid());
则不会报错,并且成功把分类删除以及把对应商品的分类置为NULL
这是为什么呢,不是两种方式都可以吗?
另外我想问一下,
用pstmt.setObject()是好处是不是不用管传入的数据类型是什么,都可以接收到,并自动根据传入的类型写入数据库呢?
如果这样的话,为什么我们不统一全部使用pstmt.setObject()呢,这样不是更方便吗?
9回答
同学你好,老师根据经验猜测,同学在JSP页面中没有将值传入后端哦~
同学检查下JSP页面,看是否取到cid的值,并成功传入后台程序中。
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
MasonM
提问者
2019-06-02
public void update(Connection conn,Product product) { PreparedStatement pstmt=null; try { //编写SQL String sql = "UPDATE product SET pname=?,author=?,price=?,description=?,filename=?,path=?,cid=? WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体属性 System.out.println("看看Cid的值:"+product.getCategory().getCid()); pstmt.setString(1,product.getPname()); pstmt.setString(2,product.getAuthor()); pstmt.setDouble(3,product.getPrice()); pstmt.setString(4,product.getDescription()); pstmt.setString(5,product.getFilename()); pstmt.setString(6,product.getPath()); pstmt.setInt(7,new Integer(product.getCategory().getCid())); // pstmt.setObject(7,product.getCategory().getCid()); //或者:这样才能设置NULL值 因为int是没有NULL值的 //pstmt.setObject(7,product.getCategory().getCid()); pstmt.setInt(8,product.getPid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { //不需要释放连接,只需要释放PreparedStatement if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
当我删除有对应商品存在的分类就这样了
这是业务层的代码
package com.mason.service.impl; import com.mason.dao.CategoryDao; import com.mason.dao.ProductDao; import com.mason.dao.impl.CategoryDaoImpl; import com.mason.dao.impl.ProductDaoImpl; import com.mason.domain.Category; import com.mason.domain.Product; import com.mason.service.CategoryService; import com.mason.utils.JDBCUtils; import java.sql.Connection; import java.sql.SQLException; import java.util.List; public class CategoryServiceImpl implements CategoryService { @Override public List<Category> findAll() { //调用CategoryDao的方法 System.out.println("CategoryService的findAll方法执行了"); CategoryDao categoryDao = new CategoryDaoImpl(); return categoryDao.findAll(); } @Override public void save(Category category) { CategoryDao categoryDao = new CategoryDaoImpl(); categoryDao.save(category); } @Override public Category findOne(Integer cid) { CategoryDao categoryDao = new CategoryDaoImpl(); return categoryDao.findOne(cid); } @Override public void update(Category category) { CategoryDao categoryDao = new CategoryDaoImpl(); categoryDao.update(category); } @Override public void delete(Integer cid) { /** * 事务管理:在业务层统一创建连接对象,保证多个DAO中使用同一个连接 * 1:创建连接之后,将连接对象传递给DAO * 2:创建一个连接对象,将连接对象绑定到当前线程中(ThreadLocal) */ Connection conn=null; try { conn= JDBCUtils.getConnection(); //开启事务: conn.setAutoCommit(false); //要在删除分类之前,先将所属该分类的商品处理一下(置为NULL) ProductDao productDao = new ProductDaoImpl(); List<Product> list = productDao.findByCid(cid); for (Product product : list) { product.getCategory().setCid(null); productDao.update(conn,product); } // int d=1/0;//测试异常使用 //删除具体分类 CategoryDao categoryDao = new CategoryDaoImpl(); categoryDao.delete(conn,cid); //提交事务 conn.commit(); } catch (Exception e) { //回滚事务 try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
吃吃吃鱼的猫
2019-06-02
同学你好,在下图标识位置输出product.getCategory().getCid()的值。检查传进来的cid的值。
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
吃吃吃鱼的猫
2019-06-02
同学你好,代码没有报错,就证明代码没有问题了呢~
同学可以查看一下分类中的cid在数据库,实体类,JSP页面传入的,是否是Integer类型,如果不是,则会报错。
//如下代码 表示sql命令的提交由程序负责,程序必须调用commit才能将sql语句真正写入数据库,在之后的课程中会对此详细讲解呢~
conn.setAutoCommit(false);
//提交事务,将sql真正提交至数据库
conn.commit();
//回滚事务,这里举一个例子,假设A给B转账,A的钱减少,B的money增加,两者是一个整体。只有两个操作都成功完成了,事务才会提交,否则都会回滚到原来的状态。
conn.rollback();
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
MasonM
提问者
2019-06-01
package com.mason.service.impl; import com.mason.dao.CategoryDao; import com.mason.dao.ProductDao; import com.mason.dao.impl.CategoryDaoImpl; import com.mason.dao.impl.ProductDaoImpl; import com.mason.domain.Category; import com.mason.domain.Product; import com.mason.service.CategoryService; import com.mason.utils.JDBCUtils; import java.sql.Connection; import java.sql.SQLException; import java.util.List; public class CategoryServiceImpl implements CategoryService { @Override public List<Category> findAll() { //调用CategoryDao的方法 System.out.println("CategoryService的findAll方法执行了"); CategoryDao categoryDao = new CategoryDaoImpl(); return categoryDao.findAll(); } @Override public void save(Category category) { CategoryDao categoryDao = new CategoryDaoImpl(); categoryDao.save(category); } @Override public Category findOne(Integer cid) { CategoryDao categoryDao = new CategoryDaoImpl(); return categoryDao.findOne(cid); } @Override public void update(Category category) { CategoryDao categoryDao = new CategoryDaoImpl(); categoryDao.update(category); } @Override public void delete(Integer cid) { /** * 事务管理:在业务层统一创建连接对象,保证多个DAO中使用同一个连接 * 1:创建连接之后,将连接对象传递给DAO * 2:创建一个连接对象,将连接对象绑定到当前线程中(ThreadLocal) */ Connection conn=null; try { conn= JDBCUtils.getConnection(); //开启事务: conn.setAutoCommit(false); //要在删除分类之前,先将所属该分类的商品处理一下(置为NULL) ProductDao productDao = new ProductDaoImpl(); List<Product> list = productDao.findByCid(cid); for (Product product : list) { product.getCategory().setCid(null); productDao.update(conn,product); } // int d=1/0;//测试异常使用 //删除具体分类 CategoryDao categoryDao = new CategoryDaoImpl(); categoryDao.delete(conn,cid); //提交事务 conn.commit(); } catch (Exception e) { //回滚事务 try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
这是剩下的业务层的代码,麻烦老师了!!!!非常感谢!!
MasonM
提问者
2019-06-01
老师,这是最新的代码!!谢谢!!麻烦您了!!!
package com.mason.dao.impl; import com.mason.dao.ProductDao; import com.mason.domain.Product; import com.mason.utils.JDBCUtils; import javax.servlet.http.HttpServletRequest; import java.io.File; 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 ProductDaoImpl implements ProductDao { @Override public List<Product> findAll() { System.out.println("ProductDao的findAll方法"); Connection conn = null; ResultSet rs = null; PreparedStatement pstmt = null; List<Product> list = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "SELECT * FROM product p,category c WHERE p.cid=c.cid ORDER BY p.pid"; //预编译SQL pstmt = conn.prepareStatement(sql); //执行SQL rs = pstmt.executeQuery(); //遍历结果集 list = new ArrayList(); while (rs.next()) { Product product = new Product(); product.setPid(rs.getInt("pid")); product.setFilename(rs.getString("filename")); product.setPname(rs.getString("pname")); product.setAuthor(rs.getString("author")); product.setPrice(rs.getDouble("price")); product.setDescription(rs.getString("description")); product.setPath(rs.getString("path")); //封装Category product.getCategory().setCid(rs.getInt("cid")); product.getCategory().setCname(rs.getString("cname")); product.getCategory().setCdesc(rs.getString("cdesc")); list.add(product); } for (Product p : list) { System.out.println("商品" + p + " 商品分类名称:" + p.getCategory().getCname()); } } catch (Exception e) { e.printStackTrace(); } finally { //释放资源 JDBCUtils.release(rs, pstmt, conn); } //如果没有数据,也不会返回NULL,因为前面list = new ArrayList(); return list; } @Override public void save(Product product) { Connection conn = null; PreparedStatement pstmt = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "INSERT product values(null,?,?,?,?,?,?,?)"; //预编译SQL pstmt = conn.prepareStatement(sql); //设置具体参数 pstmt.setString(1, product.getPname()); pstmt.setString(2, product.getAuthor()); pstmt.setDouble(3, product.getPrice()); pstmt.setString(4, product.getDescription()); pstmt.setString(5, product.getFilename()); pstmt.setString(6, product.getPath()); pstmt.setInt(7, product.getCategory().getCid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.release(pstmt, conn); } } @Override public Product findOne(Integer pid) { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "SELECT * FROM product p,category c WHERE p.cid=c.cid AND p.pid=?"; //预编译SQL pstmt = conn.prepareStatement(sql); //设置具体属性 pstmt.setInt(1, pid); //执行SQL rs = pstmt.executeQuery(); //判断结果集 if (rs.next()) { //封装数据 Product product = new Product(); product.setPid(rs.getInt("pid")); product.setPname(rs.getString("pname")); product.setDescription(rs.getString("description")); product.setFilename(rs.getString("filename")); product.setPrice(rs.getDouble("price")); product.setPath(rs.getString("path")); product.setAuthor(rs.getString("author")); product.getCategory().setCid(rs.getInt("cid")); product.getCategory().setCname(rs.getString("cname")); product.getCategory().setCdesc(rs.getString("cdesc")); return product; } } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.release(rs, pstmt, conn); } return null; } @Override public void update(Product product) { Connection conn=null; PreparedStatement pstmt=null; try { //获得链接 conn=JDBCUtils.getConnection(); //编写SQL String sql = "UPDATE product SET pname=?,author=?,price=?,description=?,filename=?,path=?,cid=? WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体属性 pstmt.setString(1,product.getPname()); pstmt.setString(2,product.getAuthor()); pstmt.setDouble(3,product.getPrice()); pstmt.setString(4,product.getDescription()); pstmt.setString(5,product.getFilename()); pstmt.setString(6,product.getPath()); pstmt.setObject(7,product.getCategory().getCid()); //或者:这样才能设置NULL值 因为int是没有NULL值的 //pstmt.setObject(7,product.getCategory().getCid()); pstmt.setInt(8,product.getPid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.release(pstmt,conn); } } @Override public void delete(Integer pid) { Connection conn=null; PreparedStatement pstmt=null; try { //获得连接 conn=JDBCUtils.getConnection(); //编写SQL String sql = "DELETE FROM product WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体参数 pstmt.setInt(1, pid); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.release(pstmt,conn); } } @Override public List<Product> findByCid(Integer cid) { Connection conn = null; ResultSet rs = null; PreparedStatement pstmt = null; List<Product> list = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "SELECT * FROM product p,category c WHERE p.cid=c.cid AND p.cid=?"; //预编译SQL pstmt = conn.prepareStatement(sql); //设置具体参数 pstmt.setInt(1,cid); //执行SQL rs = pstmt.executeQuery(); //遍历结果集 list = new ArrayList(); while (rs.next()) { Product product = new Product(); product.setPid(rs.getInt("pid")); product.setFilename(rs.getString("filename")); product.setPname(rs.getString("pname")); product.setAuthor(rs.getString("author")); product.setPrice(rs.getDouble("price")); product.setDescription(rs.getString("description")); product.setPath(rs.getString("path")); //封装商品所属分类 product.getCategory().setCid(rs.getInt("cid")); product.getCategory().setCname(rs.getString("cname")); product.getCategory().setCdesc(rs.getString("cdesc")); list.add(product); } } catch (Exception e) { e.printStackTrace(); } finally { //释放资源 JDBCUtils.release(rs, pstmt, conn); } //如果没有数据,也不会返回NULL,因为前面list = new ArrayList(); return list; } public void update(Connection conn,Product product) { PreparedStatement pstmt=null; try { //编写SQL String sql = "UPDATE product SET pname=?,author=?,price=?,description=?,filename=?,path=?,cid=? WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体属性 pstmt.setString(1,product.getPname()); pstmt.setString(2,product.getAuthor()); pstmt.setDouble(3,product.getPrice()); pstmt.setString(4,product.getDescription()); pstmt.setString(5,product.getFilename()); pstmt.setString(6,product.getPath()); pstmt.setInt(7,new Integer(product.getCategory().getCid())); //或者:这样才能设置NULL值 因为int是没有NULL值的 //pstmt.setObject(7,product.getCategory().getCid()); pstmt.setInt(8,product.getPid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { //不需要释放连接,只需要释放PreparedStatement if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
全部代码就这样了
当我删除一个有对应商品存在的分类的时候,就报异常了,
但是当我把语句改成setObject之后就没问题,正常执行删除
也正常把商品分类置为NULL了,请问这是为什么呢?
MasonM
提问者
2019-06-01
老师,但我没搞懂的是
//开启事务:
conn.setAutoCommit(false);
和
//提交事务
conn.commit();
和
//回滚事务
conn.rollback();
是什么意思呀?
这三个方法都是什么意思呀?能否详细介绍一下呢?
MasonM
提问者
2019-06-01
package com.mason.dao.impl; import com.mason.dao.ProductDao; import com.mason.domain.Product; import com.mason.utils.JDBCUtils; import javax.servlet.http.HttpServletRequest; import java.io.File; 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 ProductDaoImpl implements ProductDao { @Override public List<Product> findAll() { System.out.println("ProductDao的findAll方法"); Connection conn = null; ResultSet rs = null; PreparedStatement pstmt = null; List<Product> list = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "SELECT * FROM product p,category c WHERE p.cid=c.cid ORDER BY p.pid"; //预编译SQL pstmt = conn.prepareStatement(sql); //执行SQL rs = pstmt.executeQuery(); //遍历结果集 list = new ArrayList(); while (rs.next()) { Product product = new Product(); product.setPid(rs.getInt("pid")); product.setFilename(rs.getString("filename")); product.setPname(rs.getString("pname")); product.setAuthor(rs.getString("author")); product.setPrice(rs.getDouble("price")); product.setDescription(rs.getString("description")); product.setPath(rs.getString("path")); //封装Category product.getCategory().setCid(rs.getInt("cid")); product.getCategory().setCname(rs.getString("cname")); product.getCategory().setCdesc(rs.getString("cdesc")); list.add(product); } for (Product p : list) { System.out.println("商品" + p + " 商品分类名称:" + p.getCategory().getCname()); } } catch (Exception e) { e.printStackTrace(); } finally { //释放资源 JDBCUtils.release(rs, pstmt, conn); } //如果没有数据,也不会返回NULL,因为前面list = new ArrayList(); return list; } @Override public void save(Product product) { Connection conn = null; PreparedStatement pstmt = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "INSERT product values(null,?,?,?,?,?,?,?)"; //预编译SQL pstmt = conn.prepareStatement(sql); //设置具体参数 pstmt.setString(1, product.getPname()); pstmt.setString(2, product.getAuthor()); pstmt.setDouble(3, product.getPrice()); pstmt.setString(4, product.getDescription()); pstmt.setString(5, product.getFilename()); pstmt.setString(6, product.getPath()); pstmt.setInt(7, product.getCategory().getCid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.release(pstmt, conn); } } @Override public Product findOne(Integer pid) { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "SELECT * FROM product p,category c WHERE p.cid=c.cid AND p.pid=?"; //预编译SQL pstmt = conn.prepareStatement(sql); //设置具体属性 pstmt.setInt(1, pid); //执行SQL rs = pstmt.executeQuery(); //判断结果集 if (rs.next()) { //封装数据 Product product = new Product(); product.setPid(rs.getInt("pid")); product.setPname(rs.getString("pname")); product.setDescription(rs.getString("description")); product.setFilename(rs.getString("filename")); product.setPrice(rs.getDouble("price")); product.setPath(rs.getString("path")); product.setAuthor(rs.getString("author")); product.getCategory().setCid(rs.getInt("cid")); product.getCategory().setCname(rs.getString("cname")); product.getCategory().setCdesc(rs.getString("cdesc")); return product; } } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtils.release(rs, pstmt, conn); } return null; } @Override public void update(Product product) { Connection conn=null; PreparedStatement pstmt=null; try { //获得链接 conn=JDBCUtils.getConnection(); //编写SQL String sql = "UPDATE product SET pname=?,author=?,price=?,description=?,filename=?,path=?,cid=? WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体属性 pstmt.setString(1,product.getPname()); pstmt.setString(2,product.getAuthor()); pstmt.setDouble(3,product.getPrice()); pstmt.setString(4,product.getDescription()); pstmt.setString(5,product.getFilename()); pstmt.setString(6,product.getPath()); pstmt.setObject(7,product.getCategory().getCid()); //或者:这样才能设置NULL值 因为int是没有NULL值的 //pstmt.setObject(7,product.getCategory().getCid()); pstmt.setInt(8,product.getPid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.release(pstmt,conn); } } @Override public void delete(Integer pid) { Connection conn=null; PreparedStatement pstmt=null; try { //获得连接 conn=JDBCUtils.getConnection(); //编写SQL String sql = "DELETE FROM product WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体参数 pstmt.setInt(1, pid); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.release(pstmt,conn); } } @Override public List<Product> findByCid(Integer cid) { Connection conn = null; ResultSet rs = null; PreparedStatement pstmt = null; List<Product> list = null; try { //获得连接 conn = JDBCUtils.getConnection(); //编写SQL String sql = "SELECT * FROM product p,category c WHERE p.cid=c.cid AND p.cid=?"; //预编译SQL pstmt = conn.prepareStatement(sql); //设置具体参数 pstmt.setInt(1,cid); //执行SQL rs = pstmt.executeQuery(); //遍历结果集 list = new ArrayList(); while (rs.next()) { Product product = new Product(); product.setPid(rs.getInt("pid")); product.setFilename(rs.getString("filename")); product.setPname(rs.getString("pname")); product.setAuthor(rs.getString("author")); product.setPrice(rs.getDouble("price")); product.setDescription(rs.getString("description")); product.setPath(rs.getString("path")); //封装商品所属分类 product.getCategory().setCid(rs.getInt("cid")); product.getCategory().setCname(rs.getString("cname")); product.getCategory().setCdesc(rs.getString("cdesc")); list.add(product); } } catch (Exception e) { e.printStackTrace(); } finally { //释放资源 JDBCUtils.release(rs, pstmt, conn); } //如果没有数据,也不会返回NULL,因为前面list = new ArrayList(); return list; } public void update(Connection conn,Product product) { PreparedStatement pstmt=null; try { //编写SQL String sql = "UPDATE product SET pname=?,author=?,price=?,description=?,filename=?,path=?,cid=? WHERE pid=?"; //预编译SQL pstmt=conn.prepareStatement(sql); //设置具体属性 pstmt.setString(1,product.getPname()); pstmt.setString(2,product.getAuthor()); pstmt.setDouble(3,product.getPrice()); pstmt.setString(4,product.getDescription()); pstmt.setString(5,product.getFilename()); pstmt.setString(6,product.getPath()); pstmt.setObject(7,product.getCategory().getCid()); //或者:这样才能设置NULL值 因为int是没有NULL值的 //pstmt.setObject(7,product.getCategory().getCid()); pstmt.setInt(8,product.getPid()); //执行SQL pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); }finally { //不需要释放连接,只需要释放PreparedStatement if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
好帮手慕阿满
2019-06-01
同学你好,应该是可以的,问一下同学如下位置是那一句代码呢?
建议同学具体指明一下。
另外,pstmt.setObject()可以传入任何类型的参数,但是使用setObject方法可能效率会低一些,所以建议数据类型确定时,不要使用setObject方法。
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
相似问题