MySql&JDBC
项目:学生管理程序
项目要求:使用JDBC程序操作MySql数据库中的学生数据
实现功能:
1、操作界面的显示
2、管理员的登录
3、统计学生人数
4、查看学生名单
5、按照学号查询学生信息
6、按照学号修改学生信息
7、删除学生记录
8、新增年级记录
9、退出程序
项目程序虽然简单,但也涵盖了JDBC基本的知识点,独立完成这个项目,可以对Durid、DBUtils等JDBC常用工具有初步的认识。
!!!(需要打上mysql_jdbc、Durid等相应的jar包)!!!
首先对项目进行分层:
1、实体层:包含管理员类、学生类
2、数据操作层:封装DBUtils,提高代码复用率
3、服务层:
登录验证方法
返回学生人数方法
返回学生信息方法
按照查询修改学生信息方法
按照学号修改学生信息方法
删除学生方法
新增学生记录方法
4、界面层:包括服务层方法返回结果的展示
然后就要各层的实现:
1、实体层没什么好说的,就是建相应的类。
拿学生类举例,数据库中每条学生信息都包括学号、姓名等信息,所以学生类中也要有这些信息,然后就是补充相应的构造函数。
例如:
//拿学生类举个例子
public class Student {
private int num;
private String stuName;
private int grade;
private String birth;
public Student(int num, String stuName, int grade, String birth) {
super();
this.num = num;
this.stuName = stuName;
this.grade = grade;
this.birth = birth;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Student [num=" + num + ", stuName=" + stuName + ", grade=" + grade + ", birth=" + birth + "]";
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public String getBirth() {
return birth;
}
public void setBirth(String birth) {
this.birth = birth;
}
}
2、数据操作层的实现主要是要封装DBUtils的几个方法,让服务层调用更加方便简单。
主要封装的有:
返回值是int型,代表sql语句增删改操作成功与否的update()方法
返回值是对象,代表sql查询语句一个结果的BeanHandler类,使用的是query()方法
返回值是多个对象,代表sql查询语句多个结果的BeanListHandler类,使用的是query()方法
返回值是Object,代表sql查询语句第一行第一列结果ScalarHandler类,使用的是query()方法
例如:
//先写出基础的数据操作类,再用相应类继承这个基础类
package com.bald.dao;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.bald.utils.JDBCUtilsByDruid;
/*
* 封装DBUtils方法
*/
public class BasicDao<T> {
/*
* 通用的增删改方法,针对于任何表
*/
public int update(String sql,Object...param) {
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
QueryRunner qr = new QueryRunner();
return qr.update(connection, sql, param);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
/*
* 返回单个对象,针对任何表
*/
public T querySingle(String sql,Class<T> clazz,Object...params) {
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
QueryRunner qr = new QueryRunner();
return qr.query(connection, sql,new BeanHandler<T>(clazz), params);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
/*
* 返回多个对象,针对任何表
*/
public List<T> queryNulti(String sql,Class<T> clazz,Object...params) {
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
QueryRunner qr = new QueryRunner();
return qr.query(connection, sql,new BeanListHandler<T>(clazz), params);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
/*
* 返回单个值
*/
public Object scalar(String sql,Object...params) {
Connection connection = null;
try {
connection = JDBCUtilsByDruid.getConnection();
QueryRunner qr = new QueryRunner();
return qr.query(connection, sql,new ScalarHandler(), params);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
/*
* 批处理
*/
public void batchUpdate(String sql, Object[][] params) {
Connection conn = null;
try {
conn = JDBCUtilsByDruid.getConnection();
QueryRunner qr = new QueryRunner();
qr.batch(conn,sql, params);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,conn);
}
return;
}
public void tP(String sql1, Object[]params1,String sql2, Object[]params2) throws SQLException {
Connection conn = null;
try{
conn = JDBCUtilsByDruid.getConnection();
//开启事务
conn.setAutoCommit(false);
/**
* 在创建QueryRunner对象时,不传递数据源给它,是为了保证这两条SQL在同一个事务中进行,
* 我们手动获取数据库连接,然后让这两条SQL使用同一个数据库连接执行
*/
QueryRunner runner = new QueryRunner();
runner.update(conn,sql1,params1);
//模拟程序出现异常让事务回滚
runner.update(conn,sql2,params2);
//sql正常执行之后就提交事务
conn.commit();
} catch (Exception e) {
e.printStackTrace();
//出现异常之后就回滚事务
if(conn!=null) {
conn.rollback();
System.out.println("数据操作失败,回滚成功。");
}
} finally {
//关闭数据库连接
JDBCUtilsByDruid.close(null,null,conn);
}
return;
}
}
3、服务层就是将数据操作层的相应方法封装成实现各种功能,供界面层调用。
例如:
package com.bald.service;
import java.util.List;
import java.util.Scanner;
import com.bald.bean.Student;
import com.bald.dao.StuDao;
public class StuService extends StuDao {
StuDao dao = new StuDao();
/*
* 返回学生人数
*/
public int stuNum(int grade) {
Object count=null;
if(grade==0){
count = dao.scalar("select count(*) from student");
}
else count = dao.scalar("select sum from grade where grade=?", grade);
return Integer.parseInt(count+"");
}
/*
* 返回学生信息
*/
public List<Student> stu(int grade){
List<Student> list = dao.queryNulti("select * from student where grade=?", Student.class, grade);
return list;
}
/*
* 通过学号查询学生
*/
public Student queryIdStu(int num) {
Student stu = dao.querySingle("select * from student where num=?", Student.class, num);
return stu;
}
/*
* 通过姓名查询学生
*/
public Student queryNameStu(String name) {
Student stu = dao.querySingle("select * from student where stuName=?", Student.class, name);
return stu;
}
/*
* 新增学生信息:学号、姓名、年级、出生日期
*/
public void insert() {
Scanner s = new Scanner(System.in);
System.out.println("请输入新增学生的信息");
System.out.print("学号=");
int num = s.nextInt();
System.out.print("姓名=");
String name = s.next();
System.out.print("年级(1-4)=");
int g = s.nextInt();
System.out.print("出生日期(%Y-%M-%D)=");
String date = s.next();
int p = dao.update("INSERT INTO student VALUES(?,?,?,?)",num,name,g,date );
if(p==1)System.out.println("添加成功");
else System.out.println("添加失败");
return;
}
/*
* 删除指定学生
*/
public void delete() {
Scanner s = new Scanner(System.in);
System.out.print("请输入需要删除学生的学号:");
int num = s.nextInt();
int p = dao.update("delete from student where num=?",num );
if(p==1)System.out.println("删除成功");
else System.out.println("删除失败");
return;
}
/*
* 一次性增加一万名学生进入一年级,进行批处理
*/
public void entrance() {
Object count = dao.scalar("select max(num) from student");
String sql="insert into student values(?,?,?,?)";
Object[][] params= new Object[1000][];//1000条信息处理一次
int n = Integer.parseInt(count+"");//找出当前最后的学号
for(int i=n+1,j=0;i<1001+n;i++,j++) {
params[j]= new Object[4];
params[j][0] = i;
params[j][1] = "stu"+i;
params[j][2] = 1;
params[j][3] = "2000-1-1";
}
dao.batchUpdate(sql, params);
System.out.println("新生录入成功");
return;
}
/*
* 修改指定学号学生信息
*/
public void alter() {
Scanner s = new Scanner(System.in);
System.out.print("请输入需要修改信息学生的学号:");
int num = s.nextInt();
Student stu = dao.querySingle("select * from student where num=?", Student.class, num);
if(stu==null) {
System.out.println("查无此人!");
return;
}
dao.update("delete from student where num=?",num );
System.out.println("请输入需要修改的信息,不需要修改的则输入-1。");
System.out.print("姓名=");
String name = s.next();
if(name.equals("-1"))name=stu.getStuName();
System.out.print("年级(1-4)=");
int g = s.nextInt();
if(g==-1)g=stu.getGrade();
System.out.print("出生日期(%Y-%M-%D)=");
String date = s.next();
if(date.equals("-1")) date=stu.getBirth();
int p = dao.update("INSERT INTO student VALUES(?,?,?,?)",num,name,g,date );
if(p==1)System.out.println("修改成功");
else System.out.println("修改失败");
return;
}
}
4、界面层就是输出、输入以及各种的循环判断语句。
最后界面层调用服务层,服务层调用数据操作层,数据操作层操作数据库,用实体层中的实体接收数据库的返回值,完成程序的实现。
下面是我的实现代码(萌新求轻喷(*゜ロ゜)ノ)->GitHub连接
-
src/main/java/com/bald
*bean:实体类
*dao:数据操作类
*service:服务类
*util:工具类
*view:界面类 -
src/main/resource
*properties:Durid配置文件
*database creative.txt:数据库建库脚本
ps:我的代码中有很多我自己添加的功能,为了练习批处理、事务处理,所以功能本身可能很傻B,希望不要介意。