出现错误的编码 由于经验欠缺 尚未解决

目录

 

报错

需求分析与数据库编码

javaBean

dao接口

daoImpl

测试类

工具类


报错

报错:java.sql.SQLException: Parameter index out of range (3 > number of parameters, which is 2).
错误详情:
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
	at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3813)
	at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3795)
	at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3840)
	at com.mysql.jdbc.PreparedStatement.setInt(PreparedStatement.java:3784)
	at cn.itcase.empdao.EmpDaoImpl.saveEmp(EmpDaoImpl.java:34)
	at cn.itcase.empdao.EmpDaoImptest.testSave(EmpDaoImptest.java:26)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

需求分析与数据库编码



代码
数据库部分
需求:插入两条数据 
李杰  18  
张股 19

数据库需求分析

编号    员工姓名    年龄    部门
01       李俊杰      18     开发部
02       张三        19     开发部
部门字段存在数据冗余,为减少数据冗余   使用外键约束

整理上述得
编号    员工姓名    年龄    部门
01       李俊杰      18     1
02       张三        19     1

部门编号      部门名称
1               开发部

部门与员工之间的关系
一对多    一个部门有许多员工

设计数据库 需要遵循三大范式
第一范式:表的每个字段是不可分割的独立单元
第二范式:在第一范式的基础上,每个表只表达一个意思;理解:表的每个字段都和表的主键有依赖/有关系
第三范式:在第二范式基础,要求每张表的非主键字段都只能和主键有直接决定依赖关系    目的:降低数据冗余

员工表   从表    员工表中的一个字段引用了部门表的主键
部门表   主表
主表约束从表     主键约束外键     外键在从表中
从表被主表约束   外键被主键约束    主键在主表中(注意:每章表都由自己的主键)

数据库编码总体实现思路
建表 
 先建主表  在建从表
 
数据操作
添加数据: 先添加主表,再添加副表
修改数据: 先修改副表,再修改主表
删除数据: 先删除副表,再删除主表

开发步骤:
1.设计javabean    实体类   私有化属性private  有无参构造  提供公开的setter和getter方法
2.设计dao接口
3.dao实现类
4.测试

CREATE DATABASE demo18 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; /*建库*/

USE demo18 /*使用数据库*/

CREATE TABLE dept( /*主表 部门表*/
deptId INT PRIMARY KEY AUTO_INCREMENT, /*部门id  主键约束(非空+唯一)自增长*/
deptName VARCHAR(20) NOT NULL         /*部门名称 非空约束*/
)

CREATE TABLE employee( /*员工表 从表*/
empId INT PRIMARY KEY AUTO_INCREMENT ,/*员工id*/
empName VARCHAR(20) NOT NULL , /*员工姓名*/
age INT NOT NULL,             /*年龄*/
dept_id INT NOT NULL , /*部门id 外键*/
CONSTRAINT employee_dept_Fk FOREIGN KEY(dept_id) REFERENCES dept(deptId) ON UPDATE CASCADE ON DELETE CASCADE
/* 外键约束  约束名称                   外键                参考表(主键) 级联修改      级联删除   */
)

javaBean



代码实现
1.JavaBean
package cn.itcase.empdao;

public class Dept { // 部门实现体类
	private int id;

	private String deptName;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getDeptName() {
		return deptName;
	}

	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}

	public Dept(int id, String deptName) {
       super();
       this.id = id;
       this.deptName = deptName;
	}

	public Dept() {

	}

	@Override
	public String toString() {
		return "Dept [id=" + id + ", deptName=" + deptName + "]";
	}

}

package cn.itcase.empdao;

public class Eemployee {
	private int empId;
	private String empName;
	private int age;
	private Dept deptid;// 对应员工表的外键

	public Dept getDept() {
		return deptid;
	}

	public void setDept(Dept dept) {
		this.deptid = deptid;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getEmpId() {
		return empId;
	}

	public void setEmpId(int empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	public Eemployee(int empId, String empName, int age, Dept deptid) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.age = age;
		this.deptid = deptid;
	}

	public Eemployee() {

	}

	@Override
	public String toString() {
		return "Eemployee [empId=" + empId + ", empName=" + empName + ",age="
				+ age + ",deptid=" + deptid + "]";
	}

}

dao接口



2.dao
package cn.itcase.empdao;

public interface DeptEmpDao {
	/**
	 * protected void save(Eemployee emp);
	 * 报错:
	 * 接口方法保存的非法修饰符;只允许公开和摘要
	 * @param emp
	 */

       public  void  saveEmp(Eemployee emp);
       public  void  saveDept(Dept dept);


   /*访问修饰符:
	   * private     私有控制访问符      被修饰的成员变量仅能被自身访问
	  * public      公共访问控制符      所有类都可以访问,但会降低运行安全性和数据的封装性,谨慎使用
	  * protected   保护访问控制符       主要是供子类引用,同一包中的其他类也可引用
	  * default     缺省默认访问符       没有定义成员变量的修饰符默认为default,可以被本类或同一包中的其他类访问
	  * 非访问修饰符
	  * static      静态域修饰符   用static修饰的成员变量仅属于本类的变量,而不属于任何一个具体对象,
	  *         static修饰的成员变量保存在类的公共存储单元,该类任何对象访问它是获取的数据都市相同的
	  *                       该类的任何对象修改它是,都是对同一内存单元进行操作
	  * final       最终域修饰符   修饰常量 被它修饰的常量在运行过程中常量的值不可再该变
	  * volatile    共享(易失)域修饰符   被它修饰的成员变量可能被几个线程控制和修改,一般用来修饰可接受外部输入的域
	 * transient   暂时性域修饰符   修饰暂时性变量
	          * */
}

daoImpl



3.dao实现类
package cn.itcase.empdao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import cn.itcase.util.JDBCUtil;

public class EmpDaoImpl implements DeptEmpDao {
	// 全局变量
	private Connection conn;
	private PreparedStatement pstmt;
	private ResultSet rs;
	// 部门Id
	int deptid=0;

	@Override
	public void saveEmp(Eemployee emp) {
		// 保存员工
		String sql_emp = "insert into employee(empName,dept_id)values(?,?,?)";

		try {
			// 连接数据库
			conn = JDBCUtil.getConnection();

			// 保存员工
			pstmt = conn.prepareStatement(sql_emp);
			
			pstmt = conn.prepareStatement(sql_emp,
					Statement.RETURN_GENERATED_KEYS);
			//员工id
			//int EmpId =0;
			// 设置参数
			//pstmt.setInt(1,emp.getEmpId());
			pstmt.setString(2, emp.getEmpName());
			pstmt.setInt(3, emp.getAge());
			pstmt.setInt(4, deptid); // 外键

			// 执行预编译操作
			pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.closeAll(conn, pstmt, rs);

		}
	}

	@Override
	public void saveDept(Dept dept) {
		// 保存部门
		String sql_dept = "insert into dept(deptName) values(?)";
		// 部门id
		deptid = 0;
		try {
			// 连接数据库
			conn = JDBCUtil.getConnection();

			/* 保存部门,获取自动增长 一.需要指定返回自动增长标记 */
			pstmt = conn.prepareStatement(sql_dept,
					Statement.RETURN_GENERATED_KEYS);

			// 设置参数
			//pstmt.setInt(1,dept.getId()); // 主键
			pstmt.setString(2, dept.getDeptName());

			// 执行
			pstmt.executeUpdate();

			/* 二.获取上面保存的部门自增长的主键 */
			rs = pstmt.getGeneratedKeys();

			// 得到返回自增长的字段
			if (rs.next()) {
				deptid = rs.getInt(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.closeAll(conn, pstmt, rs);
		}

	}

}

测试类



4.测试类
package cn.itcase.empdao;

import org.junit.Before;
import org.junit.Test;

public class EmpDaoImptest {
	DeptEmpDao empDao = null;

	@Before
	public void init() {
		empDao = new EmpDaoImpl();
	}

	@Test
	public void testSave() {
		try {
			Dept dept = new Dept();
			dept.setDeptName("");
			empDao.saveDept(dept);

			Eemployee emp = new Eemployee();
			emp.setEmpName("");
			emp.setAge(18);
			emp.setDept(dept);
			empDao.saveEmp(emp);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

工具类

JDBCUtil 工具类
package cn.itcase.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * JDBCUtil工具类
 * 
 * @author Administrator
 * 
 */
public class JDBCUtil {
	// static 修饰的成员属性 是共享数据 类加载时加载 类文件消失时消失
	private static String url = "jdbc:mysql://localhost:3306/demo18"; // 连接数据库
	// 等价上句代码 private staitc String url ="jdbc:mysql:///demo17";
	private static String user = "root"; // 数据库的登录用户名
	private static String password = "root"; // 数据库的登录密码

	/**
	 * 获取连接的方法封装
	 */
	public static Connection getConnection() {

		try {
			// 加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			return DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			throw new RuntimeException();
		}

	}

	/**
	 * 释放资源的方法封装
	 * 
	 * Connection 建立连接的对象 Statement 执行命令,将sql语句发送到数据库执行 ResultSet 保存查询结果对象
	 */
	public static void closeAll(Connection conn, Statement stmt, ResultSet rs) {
		try {
			if (rs != null) {
				rs.close();
				rs = null;
			}
			if (stmt != null) {
				stmt.close();
				stmt = null;
			}
			if (conn != null && conn.isClosed()) {
				conn.close();
				conn = null;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}
}





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旭日初扬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值