JDBC操作封装

JDBC操作封装

文件结构如下:

在这里插入图片描述

代码如下:
//对应数据库的user表格,这个类的成员名必须和数据库的属性名相同,或者和sql语句的别名相同。
import java.util.Date;

public class User {
	private int id;
	private String username;
	private Date birthday;
	//sql.Date是util.Date的子类,这里直接运用多态来接收。
	private String sex;
	private String address;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + username + ", birthday=" + birthday + ", sex=" + sex + ", address=" + address
				+ "]";
	}
	public User(int id, String username, Date birthday, String sex, String address) {
		super();
		this.id = id;
		this.username = username;
		this.birthday = birthday;
		this.sex = sex;
		this.address = address;
	}
	public User() {
		super();
	}
	
}
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

//获得connection数据库连接的工具类,可以创建和关闭JDBC相关对象。
public class JDBCUtils {
	public static Connection getConnection() throws Exception {
		InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
		//采用读取配置文件的方式去创建,增加的程序的灵活性,拓展性。
		Properties pros = new Properties();
		pros.load(is);		
		String url = pros.getProperty("url");
		String user = pros.getProperty("user");
		String password = pros.getProperty("password");	
		Class.forName(pros.getProperty("driverClass"));
		Connection conn = DriverManager.getConnection(url, user, password);
		return conn;
	}
	
	public static void closeResource(Connection conn,PreparedStatement ps,ResultSet rs) {
		try {
			if(conn!=null) conn.close();
			if(ps!=null) ps.close();
			if(rs!=null) rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.test.JDBCutils.JDBCUtils;

//BaseDao类,增删改查操作的基本类,统一封装了增删改查的基本操作。
public class BaseDao {
	public int update(Connection conn,String sql,Object...args) {
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for(int i=0;i<args.length;i++) {
				ps.setObject(i+1, args[i]);
			}
			return ps.executeUpdate();
			//返回的是更新的行数
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JDBCUtils.closeResource(null, ps,null);
		}
		
		return 0;
	}
	
	//运行泛类,增强拓展性
	public <T> T getInstance(Connection conn,Class<T> clazz,String sql,Object...args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			for(int i=0;i<args.length;i++) {
				ps.setObject(i+1, args[i]);
			}
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			//获取元数据
			int count = rsmd.getColumnCount();
			//获取表格列数
			if(rs.next()) {
				T t = clazz.newInstance();
				//通过反射创建对象
				for(int i=0;i<count;i++) {
					Object value = rs.getObject(i+1);
					String column = rsmd.getColumnLabel(i+1);
					//获取指定列数的,列名。
					Field field = clazz.getDeclaredField(column);
					field.setAccessible(true);
					field.set(t, value);
					//通过反射修改对象的private属性。
				}
				return t;
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}finally {
			JDBCUtils.closeResource(null, ps,rs);
		}
		return null;
	}
	
	public <T> List<T> getForList(Connection conn,Class<T> clazz,String sql,Object...args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		List<T> list = new ArrayList<>();
		try {
			ps = conn.prepareStatement(sql);
			for(int i=0;i<args.length;i++) {
				ps.setObject(i+1, args[i]);
			}
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			
			int count = rsmd.getColumnCount();
			while(rs.next()) {
				T t = clazz.newInstance();
				for(int i=0;i<count;i++) {
					Object value = rs.getObject(i+1);
					String column = rsmd.getColumnLabel(i+1);
					Field field = clazz.getDeclaredField(column);
					field.setAccessible(true);
					field.set(t, value);
				}
				list.add(t);
			}
			return list;
			
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}finally {
			JDBCUtils.closeResource(null, ps,rs);
		}
		return list;
	}
	
	//针对特殊语言查询的方法,返回值根据语句不同而不同
	public <T> T getValue(Connection conn,String sql,Object...args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			for(int i=0;i<args.length;i++) {
				ps.setObject(i+1, args[i]);
			}
			rs = ps.executeQuery();
			if(rs.next()) {
				return (T)rs.getObject(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}finally {
			JDBCUtils.closeResource(null, ps,rs);
		}
		return null;
	}

}

import java.sql.Connection;
import java.util.List;

import com.test.transaction.User;
//定义接口类,来规范实现类的操作,不同表有不同的接口类,和不同的实现类
public interface UserDao {
	void insert(Connection conn,User user);
	void deletById(Connection conn,int id);
	void updateById(Connection conn,User user);
	User getById(Connection conn,int id);
	List<User> getAll(Connection conn);
	Long getCount(Connection conn);

}
import java.sql.Connection;
import java.util.List;

import com.test.transaction.User;
//定义实现类继承BaseDao基础类,实现不同表的接口
public class UserDaoImp extends BaseDao implements UserDao{

	@Override
	public void insert(Connection conn, User user) {
		String sql = "insert into user(id,username,birthday,sex,address) values(?,?,?,?,?)";
		update(conn,sql,0,user.getUsername(),user.getBirthday(),user.getSex(),user.getAddress());	
	}

	@Override
	public void deletById(Connection conn, int id) {
		String sql = "delete from user where id = ?";
		update(conn,sql,id);
	}

	@Override
	public void updateById(Connection conn, User user) {
		String sql = "update user set username=?,birthday=?,sex=?,address=? where id=?";
		update(conn,sql,user.getUsername(),user.getBirthday(),user.getSex(),user.getAddress(),user.getId());
		
	}

	@Override
	public User getById(Connection conn, int id) {
		String sql = "select * from user where id=?";
		return getInstance(conn,User.class,sql,id);
	}

	@Override
	public List<User> getAll(Connection conn) {
		String sql = "select * from user";
		return getForList(conn,User.class,sql);
	}

	@Override
	public Long getCount(Connection conn) {
		String sql = "select count(*) from user";
		return getValue(conn,sql);
	}
	
}

import static org.junit.jupiter.api.Assertions.fail;

import java.sql.Connection;
import java.util.Date;
import java.util.List;

import org.junit.jupiter.api.Test;

import com.test.JDBCutils.JDBCUtils;
import com.test.dao.UserDaoImp;
import com.test.transaction.User;

//测试类创建步骤,创建Junit测试类,指定要测试的类,每个方法单独测试。
class UserDAOImpTest {

	UserDaoImp imp = new UserDaoImp();
	
	@Test
	void testInsert() {
		Connection conn;
		try {
			conn = JDBCUtils.getConnection();
			User user = new User(1,"亚索",new Date(99892793L),"男","爱哦尼亚");
			imp.insert(conn, user);
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}

	@Test
	void testDeletById() {
		Connection conn;
		try {
			conn = JDBCUtils.getConnection();
			imp.deletById(conn, 8);
			conn.close();
			System.out.println("修改成功");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Test
	void testUpdateById() {
		fail("Not yet implemented");
	}

	@Test
	void testGetById() {
		fail("Not yet implemented");
	}

	@Test
	void testGetAll() {
		Connection conn;
		try {
			conn = JDBCUtils.getConnection();
			List<User> list = imp.getAll(conn);
			conn.close();
			for(User u:list) {
				System.out.println(u);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Test
	void testGetCount() {
		Connection conn;
		try {
			conn = JDBCUtils.getConnection();
			System.out.println(imp.getCount(conn));
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
//jdbc.properties配置文件
user=root
password=1171460872
url=jdbc:mysql://localhost:3306/mysqltest?useUnicode=true&characterEncoding=UTF8
driverClass=com.mysql.jdbc.Driver
//注意url的?后面内容。
/*添加的作用是:指定字符的编码、解码格式。

             例如:mysql数据库用的是gbk编码,而项目数据库用的是utf-8编码。这时候如果添加了useUnicode=true&characterEncoding=UTF-8 ,那么作用有如下两个方面:

1. 存数据时:

     数据库在存放项目数据的时候会先用UTF-8格式将数据解码成字节码,然后再将解码后的字节码重新使用GBK编码存放到数据库中。

2.取数据时:

     在从数据库中取数据的时候,数据库会先将数据库中的数据按GBK格式解码成字节码,然后再将解码后的字节码重新按UTF-8格式编码数据,最后再将数据返回给客户端。*/
部分结果展示:

在这里插入图片描述

学习心得:

1.了解了框架搭建的基本原理,与设计思路。如:泛类,接口,基础类,反射,配置文件等。
2.掌握了JDBC的基本应用。
3.学习使用单元测试。
4.当数据库和Java程序编码格式不同时,读写会出现乱码,解决方法就是要在配置文件的url中设置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值