本文主要是对数据库方面进行案例复习,共包含两版,这是第二版,对数据库不是很理解的同学可以看看,最好自己试着敲一遍,一定会有帮助的。
数据库版(二)
为了复习和巩固前面所学习的知识,我做了这个练习,遇到了问题,加深了自己的一些理解。
本文适用于Java初学者,也欢迎大佬指正其中所包含的不足,谢谢!
如有疑问,请及时提出,或者私信我,
如有意向,也可私信加微信共勉!
这只是第三版,使用数据库连接池,对大家熟悉数据操作很有帮助,另外,还有前两版的内容,包括数组版和未使用连接池的数据库版,大家可以进入我的主页进行浏览,觉得还行,请点个赞再走趴。
至此该练习就完成了,有任何问题请私信我!
需求:设置一个学生管理系统
1.添加学生信息
2.显示学生信息
3.删除学生信息
4.修改学生信息
5.查看学生信息
6.排序
7.退出
数据库连接池版
工具类
c3p0 (了解即可):
- 导包,两个包(c3p0的工具包和依赖的jar包)。
- 定义配置文件:
- 名称 :c3p0.properties或c3p0-config.xml。
- 路径:直接将文件放在src目录下。
- 创建核心对象:数据库连接池对象 ComBoPooledDataSource。
- 获取连接:getConnection。
Druid:
使用步骤
- 导包。
- 定义配置文件:
- 是properties形式的
- 可以叫任意名称,可以放在任意目录下。
- 创建数据库连接池对象:通过工厂类来获取 DruidDataSourceFactory
- 获取连接。
定义工具类
- 定义一个类JDBCUtils.java
- 提供静态代码块加载配置文件,并初始化连接池对象
- 提供方法
- 获取连接的方法:通过数据库连接池获取
- 释放z资源
- 获取连接池的方法
Spring JDBC
- Spring框架对JDBC的简单封装
- 步骤:
- 导入jar包(5个)
- 创建JdbcTemplate对象。依赖于数据源DataSource。
- JdbcTemplate template = new JdbcTemplate(ds);
- 使用JdbcTemplate方法来完成CRUD操作。
- update():执行DML语句,增删改语句。
- queryForMap():查询结果,将结果封装为map集合
- 注意:这个方法查询的结果集长度只能是1
- 将列名作为key,值作为value,将这条记录封装为一个map集合
- queryForList():查询结果,将结果封装为list集合
- 将每一条记录封装为map集合,再将集合装在到List集合中
- 一般不会将查询结果封装为List集合,而是将数据封装为JavaBean对象,再把JavaBean对象装到List集合中
- query():查询结果,将结果封装为JavaBean对象
- queryForObject:查询结果,将结果封装为对象
- 单行单列的查询使用queryForObject
- 该操作在获取到JdbcTemplate对象之后,不需要获取连接,也不需要释放资源。
- 只需关心如何定义SQL语句,如何执行,以及怎么处理。
Druid数据库连接池的使用
package cn.xlb.db.util;
import cn.xlb.db.dao.Manage2;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/*
@author XiHai ShengGe
Druid连接池工具类
*/
public class JDBCUtils {
//定义成员变量DataSource
private static DataSource ds;
static {
try {
//加载配置文件
Properties pro = new Properties();
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
pro.load(is);
//pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties"));
//获取连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
*获取连接
*
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/*
*释放资源
*三个参数
*/
public static void close(ResultSet res,Statement stmt, Connection conn){
if (res != null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//两个参数
public static void close(Statement stmt, Connection conn){
close(null,stmt,conn);
}
/*
*获取连接池
*
*/
public static DataSource getDataSource(){
return ds;
}
}
package cn.xlb.db.dao;
import cn.xlb.db.util.JDBCUtils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/*
@author XiHai ShengGe
*/public class Manage2 {
public static void main(String[] args){
Connection conn = null;
Statement stmt = null;
//获取连接
try {
conn = JDBCUtils.getConnection();
String sql = "select * from student";
stmt = conn.createStatement();
ResultSet res = stmt.executeQuery(sql);
System.out.println(res);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
JDBCUtils.close(stmt,conn);
}
}
}
对比前面的工具类,发现免去了获取属性集的步骤等操作,使用更加简便
遇到的问题
- 使用JdbcTemplate中的query方法进行查询时,传入参数new BeanPropertyRowMapper(Student.class)实现对象的快速封装,传入的实体类中数据类型不能定义基本的数据类型,因为基本的数据类型不能接收null,所以应该将数据类型定义为引用数据类型
org.springframework.jdbc.IncorrectResultSetColumnCountException: Incorrect column count
- 在使用JdbcTemplate的方法queryForObject (),查询内容是,SQL语句查询的是 * (即超过两个值),所以数据库报错
- queryForObject ()只能查询单行单列的数据。
- 在查询所有值时,建议采用query()方法查询,封装为JavaBean对象的集合。
下面就是该练习的主体了,代码如下
manage.java
package cn.xlb.db.dao;
import cn.xlb.db.domain.Student;
import cn.xlb.db.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
/*
@author XiHai ShengGe
*/
public class Manage2 {
public static void main(String[] args){
//创建JdbcTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//开始进行操作,避免程序使用一次后就退出
System.out.println("欢迎进入学生管理系统\n" +
"1.添加学生信息\n" +
"2.显示学生信息\n" +
"3.删除学生信息\n" +
"4.修改学生信息\n" +
"5.查询学生信息\n" +
"6.排序\n" +
"7.退出\n");
//创建Scanner对象,以免循环体中重复创建
Scanner s = new Scanner(System.in);
Manage2 manage = new Manage2();
while (true) {
System.out.println("请输入你要进行的操作:");
int i = s.nextInt();
switch (i) {
case 1:
manage.add(s,template);
break;
case 2:
manage.show(template);
break;
case 3:
manage.del(s,template);
break;
case 4:
manage.update(s,template);
break;
case 5:
manage.inquire(s,template);
break;
case 6:
manage.sort(s,template);
break;
case 7:
//不需要手动释放资源
System.exit(0);
break;
default:
System.out.println("请输入1~7之间的数");
}
}
}
private void sort(Scanner s, JdbcTemplate template) {
String sql1 = "select * from student order by number";
String sql2 = "select * from student order by grade";
List<Student> list = null;
System.out.println("请输入排序方式(1表示按学号排序,2表示按成绩排序)");
int i = s.nextInt();
switch (i){
case 1:
list = template.query(sql1, new BeanPropertyRowMapper<>(Student.class));
break;
case 2:
list = template.query(sql2,new BeanPropertyRowMapper<>(Student.class));
break;
default:
System.out.println("请输入1或2");
}
for (Student student : list) {
System.out.println("学号:" + student.getNumber() + " 姓名:" + student.getName() + " 成绩:" + student.getGrade());
}
}
private void inquire(Scanner s, JdbcTemplate template) {
System.out.print("请输入需要查询的学号:");
int number = s.nextInt();
String sql = "select * from student where number = ?";
List<Student> list = template.query(sql, new BeanPropertyRowMapper<>(Student.class), number);
if (list != null) {
for (Student student : list) {
System.out.println("学号:" + student.getNumber() + " 姓名:" + student.getName() + " 成绩:" + student.getGrade());
}
}else {
System.out.println("该学号的学生信息不存在");
}
}
private void update(Scanner s, JdbcTemplate template) {
System.out.print("请输入需要更新的学生学号:");
int number = s.nextInt();
String sql1 = "select * from student where number = ? ";
//使用queryForMap()方法,判断是否有这一条记录
Map<String, Object> map = template.queryForMap(sql1,number);
if (map != null) {
System.out.println("请输入更改后的姓名");
String name = s.next();
System.out.println("请输入更改后的成绩");
int grade = s.nextInt();
String sql = "update student set name = ? ,grade = ? where number = ?";
int i = template.update(sql, name, grade, number);
if (i > 0) {
System.out.println("更新成功");
}
}else {
System.out.println("没有该学号的学生");
}
}
private void del(Scanner s, JdbcTemplate template) {
System.out.println("请输入需要删除学生信息的学号");
int number = s.nextInt();
System.out.println("您确定要删除吗?(1是2否)");
int n = s.nextInt();
switch (n){
case 1 :
String sql1 = "select * from student where number = ?";
Map<String, Object> map = template.queryForMap(sql1, number);
if (map != null){
String sql = "delete from student where number = ?";
int i = template.update(sql, number);
if (i > 0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
}else {
System.out.println("没有该学号学生信息");
}
}
}
private void show(JdbcTemplate template) {
String sql = "select * from student";
//查询所有记录,将其封装为Student对象的List集合
//使用提供的方法,快速封装
List<Student> list = template.query(sql, new BeanPropertyRowMapper<Student>(Student.class));
//自己写方法实现封装过程,不推荐使用
/*
List<Student> list = template.query(sql, new RowMapper<Student>() {
@Override
public Student mapRow(ResultSet res, int i) throws SQLException {
int number = res.getInt("number");
String name = res.getString("name");
int grade = res.getInt("grade");
Student student = new Student();
student.setNumber(number);
student.setName(name);
student.setGrade(grade);
return student;
}
});
*/
for (Student student : list) {
System.out.println("学号:" + student.getNumber() + " 姓名:" + student.getName() + " 成绩:" + student.getGrade());
}
}
private void add(Scanner s, JdbcTemplate template) {
System.out.print("请输入需要添加的学号:");
int number = s.nextInt();
System.out.print("请输入需要添加的姓名:");
String name = s.next();
System.out.print("请输入需要添加的成绩:");
int grade = s.nextInt();
//如果添加的学号相同,会直接报错,在设计数据库时,要注意主键的设置方法
String sql = "insert into student values(?,?,?)";
int i = template.update(sql, number, name, grade);
if (i > 0){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
}
}
JDBCUtils.java
package cn.xlb.db.util;
import cn.xlb.db.dao.Manage2;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/*
@author XiHai ShengGe
Druid连接池工具类
*/
public class JDBCUtils {
//定义成员变量DataSource
private static DataSource ds;
static {
try {
//加载配置文件
Properties pro = new Properties();
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
pro.load(is);
//pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties"));
//获取连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
*获取连接
*
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/*
*释放资源
*三个参数
*/
public static void close(ResultSet res,Statement stmt, Connection conn){
if (res != null){
try {
res.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//两个参数
public static void close(Statement stmt, Connection conn){
close(null,stmt,conn);
}
/*
*获取连接池
*
*/
public static DataSource getDataSource(){
return ds;
}
}
Student.java
package cn.xlb.db.domain;
/*
@author XiHai ShengGe
*/
public class Student {
private Integer number;
private String name;
private Integer grade;
public Student() {
}
public Student(Integer number, String name, Integer grade) {
this.number = number;
this.name = name;
this.grade = grade;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getGrade() {
return grade;
}
public void setGrade(Integer grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student{" +
"number=" + number +
", name='" + name + '\'' +
", grade=" + grade +
'}';
}
}
jdbc.properties
driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/crud
username = root
password = 123456
# 初始化连接数
initialSize = 5
# 最大连接数
maxActive = 10
# 最大等待时间
maxWait = 3000