接下来几天的时间我将和大家一起学习java中数据库的操作。内容有点多,争取在国庆后全部更新完毕。知识点包括,jdbc基本操作、手动封装jdbc的操作、在不适用框架下快速操作数据库、简单的mysql知识点(常见的sql语句,事务处理等等)、最后学习两个持久层的框架,hibernate和MyBatis以及目前最为火的Nosql----redis数据库,后面两个框架可以更新会很慢。(因为我自己还没有学习)其实写了这么多篇博文以后,我发现自己也在慢慢的进步,刚开始学习,倒是希望那些看了我博客的有缘人提出宝贵的意见,对于程序员来说,永远不会找到自己的bug。总以为自己的才是最好的(hhh)
今天我们就简单的了解jdbc的基本操作以及封装jdbc工具类。
概念:jdbc、java database Connectivity 顾名思义就是java中连接数据库使用的。
下面通过一个简单的程序来看看怎么使用jdbc连接数据库的
package com.yxc.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* 测试数据库能不能连接成功
* 在开发过程中阶段性测试是很重要的的,不然写了很多的代码以后出错,
* 根本找不到错误的位置
*/
public class ConnectionTest {
public static void main(String[] args) {
//测试数据库能不能连接成功
//数据库的基本信息
String url="jdbc:mysql://localhost:3306/jdbc"; //数据库所在的位置 jdbc是你数据库的名字
String root="root"; //用户名
String password="123456"; //数据库密码
Connection conn=null; //定义一个数据库连接对象
//加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//获取一个数据库连接对象
conn = DriverManager.getConnection(url, root, password);
//测试数据库能不能连接上
//如果返回一个对象,说明连接成功,我们可以进行下面的操作
//如果出错,那么我们要开始检查错误的原因,数数据库的基本信息出错,还是驱动加载时报错
System.out.println(conn);
} catch (Exception e) {
e.printStackTrace();
}finally{
//最后一定记得关闭资源
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
jdbc连接数据库的基本步骤:
1、导入数据库连接jar包
2、开始上面的测试代码,测试是否可以连接到数据库。(这里说明一下,一定要在数据中新建数据库,我上面数据库名字为jdbc)
3、如果连接成功,才开始进行下面的操作
4、在数据库中创建表
5、在java中设计与表对应的实体类,最好字段的名字都一样
6、开始写代码
现在对于jdbc应该有初步的了解了吧!
数据库最常见的就是增删查改操作了,那么接下来我们写一个简单的增删查改功能。
package com.yxc.domain;
public class Student {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.yxc.jdbc;
import com.yxc.domain.Student;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* 下面我们通过一个案例来实现数据库的基本操作增删查改
* 使用数据库名:jdbc 表名 stu 表中三个字段 id,name,age;
* 我们使用静态方法,在主方法中测试。
*/
public class CRUD_Demo {
//因为数据库的一些基本信息是一样的,所以我们定义成成员变量,让整个类中都可以使用
//这样减少了代码量,到后面我们会把这些信息放在配置文件中,这样对于开发更加高效、方便。
//数据库的基本信息
public static String url="jdbc:mysql://localhost:3306/jdbc"; //数据库所在的位置
public static String user="root"; //用户名
public static String password="Y13627037792"; //数据库密码
public static String DriverName="com.mysql.jdbc.Driver"; //驱动名字
public static void main(String[] args) {
// //测试添加学生方法
//// Student stu=new Student();
//// stu.setId(2);
//// stu.setAge(22);
//// stu.setName("yangixn");
//// addStu(stu);
//测试删除学生
//System.out.println(deleteStu(2));
//测试更新数据
//System.out.println(updateStu());
//测试查询学生
//Student stu = findStu(1);
//System.out.println(stu);
//测试查询所有学生
List<Student> allStudent = findAllStudent();
System.out.println(allStudent);
}
/**添加一个学生
*如果添加成功返回1,失败返回0
* */
public static int addStu(Student stu1){
int result=0;
Connection conn =null;
Statement statement =null;
try {
Class.forName(DriverName);
DriverManager.getConnection(url, user, password);
String sql="insert into stu value("+stu1.getId()+",'"+stu1.getName()+"',"+stu1.getAge()+")";
statement = conn.createStatement();
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
conn.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
/**根据id一位学生
* 删除成功返回1 失败返回0
* */
public static int deleteStu(int id){
int result=0;
Connection conn =null;
Statement statement =null;
try {
Class.forName(DriverName);
conn = DriverManager.getConnection(url, user, password);
String sql="delete from stu where id="+id+"";
statement = conn.createStatement();
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
conn.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
/**更新数据
* 更新成功以后返回1,失败返回0
* */
public static int updateStu(){
int result=0;
Connection conn =null;
Statement statement =null;
try {
Class.forName(DriverName);
conn = DriverManager.getConnection(url, user, password);
String sql="update stu set name='June' where id=1";
statement = conn.createStatement();
result = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
}
finally{
try {
conn.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return result;
}
/**查找学生 查到以后返回学生对象*/
public static Student findStu(int id){
Student stu=null;
Connection conn =null;
Statement statement =null;
ResultSet resultSet =null; //这是一个结果集对象,封装了查询出来的所有结果
try {
Class.forName(DriverName);
conn = DriverManager.getConnection(url, user, password);
String sql="select * from stu where id="+id+"";
statement = conn.createStatement();
resultSet = statement.executeQuery(sql);
while(resultSet.next()){
//如果有数据,就创建一个对象保存起来
stu=new Student();
stu.setId(resultSet.getInt("id"));
stu.setName(resultSet.getString("name"));
stu.setAge(resultSet.getInt("age"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
conn.close();
statement.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return stu;
}
/**测试查询所有学生的信息
* 返回一个学生集合
*/
public static List<Student> findAllStudent(){
List<Student> list=new ArrayList<>();
Connection conn =null;
Statement statement =null;
ResultSet resultSet =null;
try {
Class.forName(DriverName);
conn = DriverManager.getConnection(url, user, password);
String sql="select * from stu ";
statement = conn.createStatement();
resultSet = statement.executeQuery(sql);
while(resultSet.next()){
//如果有数据,就创建一个对象保存起来
Student stu=new Student();
stu.setId(resultSet.getInt("id"));
stu.setName(resultSet.getString("name"));
stu.setAge(resultSet.getInt("age"));
//每一次获取的学生对象,保存在集合中
list.add(stu);
}
}catch (Exception e){
e.printStackTrace();
}finally{
try {
conn.close();
statement.close();
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//返回集合
return list;
}
}
这里我将⑤种方法都放在一个类中了,可能一时代码有点多,但是我们一个一个方法的看就会好很多。数据库中表的信息很简单,表名为stu,只有三个字段,int id, String name, int age; 所以对应的实体类就是Student。然后就是测试类。这里注意的就是测试的时候最好是一个个测试,不要一次性全部测试,因为有些数据如果已经新增了,再一次新增是会报错的,因为在数据中设计了id为主键的话,那么就不允许重复,稍加注意就好。
上面代码的不足之处:
1、在sql中有很多的字符串的拼接,很麻烦
2、很多相同的代码,能不能重构一波
3、数据库相关的信息我希望可以放在一个配置文件中,这样我的项目发给别人的时候,它改动配置文件就可以了,而不要动我的源码
4、对于查询数据的时候,对于结果集的处理很麻烦
下面的代码解决前三个不足,关于第四个不足的话,还需要在后面介绍。
db.properties(文件的后缀一定要是这个)
url=jdbc:mysql://localhost:3306/jdbc
user=root
password=123456
DriverName=com.mysql.jdbc.Driver
工具类里面一般提供静态方法,其它类可以直接调用
package com.yxc.utils;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
/**
* 一个工具类,获取连接对象以及资源的释放操作
* 这个类里面主要有两个静态方法,一个获取数据库连接对象,一个是关闭各种资源的方法
*/
public class JDBCUtils {
/**定义一个静态方法获取连接对象*/
public static Connection getConn() {
Connection conn=null;
FileInputStream in = null;
try {
//将配置文件中的信息读取进来
in = new FileInputStream("src/db.properties");
//创建一个配置文件的对象
Properties p = new Properties();
//将配置文件中的内容加载进来
p.load(in);
//获取配置文件的信息
Class.forName(p.getProperty("DriverName"));
//连接对象,将从配置文件中获取的数据库信息传进去
conn=DriverManager.getConnection(p.getProperty("url"),p.getProperty("user"),p.getProperty("password"));
} catch (Exception e) {
e.printStackTrace();
}
//最终返回一个数据库连接对象,外界的类通过这个方法就可以直接获取一个数据库连接对象
return conn;
}
/**关闭资源的方法 传进三个常见的资源*/
public static void close(Connection conn, Statement st, ResultSet rs){
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
这个是增删查改的类,可以对应最开始的类,显然代码干净了很多
package com.yxc.jdbc;
import com.yxc.domain.Student;
import com.yxc.utils.JDBCUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* 下面我们通过一个案例来实现数据库的基本操作增删查改
* 使用数据库名:jdbc 表名 stu 表中三个字段 id,name,age;
* 我们使用静态方法,在主方法中测试。
*/
public class CRUD_Demo {
public static void main(String[] args) {
//测试添加学生方法
//Student stu=new Student();
//stu.setId(3);
//stu.setAge(22);
//stu.setName("yangixn");
//System.out.println(addStu(stu));
//测试删除学生
//System.out.println(deleteStu(2));
//测试更新数据
//System.out.println(updateStu(3));
//测试查询学生
Student stu = findStu(1);
System.out.println(stu);
//测试查询所有学生
//List<Student> allStudent = findAllStudent();
//System.out.println(allStudent);
}
/**添加一个学生
*如果添加成功返回1,失败返回0
* */
public static int addStu(Student stu1){
int result=0;
Connection conn =null;
PreparedStatement ps =null;
try {
//直接通过工具类获取连接对象
conn=JDBCUtils.getConn();
//为了不搞复杂拼接,我们先使用占位符?
String sql="insert into stu value(?,?,?)";
//对于prepareStatement这个方法来说支持预编译,先执行sql语句
ps = conn.prepareStatement(sql);
//设置参数的值,参数从下标1开始
ps.setInt(1,stu1.getId());
ps.setString(2,stu1.getName());
ps.setInt(3,stu1.getAge());
result = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps,null);
}
return result;
}
/**根据id一位学生
* 删除成功返回1 失败返回0
* */
public static int deleteStu(int id){
int result=0;
Connection conn =null;
PreparedStatement ps =null;
try {
conn=JDBCUtils.getConn();
String sql="delete from stu where id=?";
ps=conn.prepareStatement(sql);
ps.setInt(1,id);
//注意下面这句话就不要将sql传进去了,不然是会报错的
result = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.close(conn,ps,null);
}
return result;
}
/**更新数据
* 更新成功以后返回1,失败返回0
* */
public static int updateStu(int id){
int result=0;
Connection conn = null;
PreparedStatement ps = null;
try {
conn=JDBCUtils.getConn();
String sql="update stu set name='June' where id=?";
ps = conn.prepareStatement(sql);
ps.setInt(1,id);
result = ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps,null);
}
return result;
}
/**查找学生 查到以后返回学生对象*/
public static Student findStu(int id){
Student stu=null;
Connection conn =null;
PreparedStatement ps=null;
ResultSet resultSet =null;
try {
conn=JDBCUtils.getConn();
String sql="select * from stu where id=?";
ps = conn.prepareStatement(sql);
ps.setInt(1,id);
resultSet = ps.executeQuery();
while(resultSet.next()){
//如果有数据,就创建一个对象保存起来
stu=new Student();
stu.setId(resultSet.getInt("id"));
stu.setName(resultSet.getString("name"));
stu.setAge(resultSet.getInt("age"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.close(conn,ps,resultSet);
}
return stu;
}
/**测试查询所有学生的信息
* 返回一个学生集合
*/
public static List<Student> findAllStudent(){
List<Student> list=new ArrayList<>();
Connection conn =null;
Statement statement =null;
ResultSet resultSet =null;
try {
conn=JDBCUtils.getConn();
String sql="select * from stu ";
statement = conn.createStatement();
resultSet = statement.executeQuery(sql);
while(resultSet.next()){
//如果有数据,就创建一个对象保存起来
Student stu=new Student();
stu.setId(resultSet.getInt("id"));
stu.setName(resultSet.getString("name"));
stu.setAge(resultSet.getInt("age"));
//每一次获取的学生对象,保存在集合中
list.add(stu);
}
}catch (Exception e){
e.printStackTrace();
}finally{
JDBCUtils.close(conn,statement,resultSet);
}
//返回集合
return list;
}
}
当然这些只是简单的重构,但是开发起来确实提高了很多的效率,对于db.peoperties和工具类,下次使用时就可以直接拷贝过去,如果数据库改了,那么在db,properties中修改一下即可,根本不需要修改源代码。这样我们就可以专心在数据库的操作,这些相同代码部分我们抽取出来就好。
当然这只是我们自己的封装,其实开发人员早就有了更强大的封装方法,我们下一篇文件再介绍。
转载:https://blog.csdn.net/weixin_42142899/article/details/101686514