搭建数据框架:
导入连接池jar包:
<c3p0-config>
<default-config>
<!--配置连接池初识的连接数-->
<property name="initialPoolSize">10</property>
<!--配置最大连接数-->
<property name="maxPoolSize">25</property>
<!--配置最小连接数-->
<property name="minPoolSize">5</property>
<!--配置驱动-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!--配置URL-->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/geekhome</property>
<!--配置连接数据库的用户名-->
<property name="user">root</property>
<!--配置密码-->
<property name="password">tjhilu</property>
</default-config>
</c3p0-config>
用户类:
public class User {
private int userId;
private String userName;
private String password;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
用户数据操作类:
public class UserDao {
/**
* 添加用户
* @param user
*/
public void add(User user){
JdbcUtil.executeUpdate("insert into users(username,password) values(?,?)", new Object[]{user.getUserName(),user.getPassword()});
}
public User findUserByName(String userName){
List<User> list = JdbcUtil.executeQuery("select userId,userName,password from users " +
"where userName=?",new Object[]{userName},User.class);
if(!list.isEmpty()){
return list.get(0);
}
return null;
}
}
员工类:
public class Emp {
private String firstName;
private double salary;
private Date hireDate;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
}
数据访问辅助类,封装数据连接与关闭:
/**
* 数据访问辅助类,封装数据连接与关闭
*/
public class JdbcHandler {
//数据池:用dataSource进行接收,是为了以后更换数据池类型
private static DataSource dataSource;
static{
//初始化数据池
dataSource = new ComboPooledDataSource();
}
/**
* 打开数据库连接
* @return
*/
public static Connection openConnection(){
Connection con = null;
if(dataSource != null){
try {
con = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
return con;
}
/**
* 关闭数据库对象
* @param con
* @param pstmt
* @param rs
*/
public static void close(Connection con, PreparedStatement pstmt, ResultSet rs){
try {
if(rs != null){
rs.close();
}
if(pstmt != null){
pstmt.close();
}
if(con != null){
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
方便获取结果集的一些数据: 获取结果集的列名称、根据列的名称查找属性、将属性的首字母转换大写
public class JdbcCommonUtil {
/**
* 获取结果集的列名称
* @param metaData
* @return 将列的名称封装成一个String集合,返回出去
*/
public static String[] getColumnNames(ResultSetMetaData metaData){
String[] array = null;
try {
//根据列的数量创建数组
array = new String[metaData.getColumnCount()];
for(int i = 0; i < array.length; i++){
//获取数据列的原名称 FIRST_NAME
//array[i] = metaData.getColumnName(i+1);
//获取数据列的标签名,标签名会随着别名进行更改,会将最终的名称改为as的别名firstname
array[i] = metaData.getColumnLabel(i+1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return array;
}
/**
* 根据列的名称查找属性
* @param columnName
* @param fields
* @return
*/
public static Field findField(String columnName,Field[] fields){
for (Field field : fields) {
//判断属性名称是否相同:对属性名进行遍历,与传入的列名进行比较,如果一致,返回这个属性
if(field.getName().equalsIgnoreCase(columnName)){
return field;
}
}
return null;
}
/**
* 将属性的首字母转换大写
* @param fieldName
* @return
*/
public static String parseUpperField(String fieldName){
return (char)(fieldName.charAt(0)-32)+fieldName.substring(1);
}
}
数据库访问工具类,封装了数据常用的增删改查的操作方法:
/**
* 数据库访问工具类,封装了数据常用的增删改查的操作方法
*/
public class JdbcUtil {
/**
* 用于处理数据增删改
* @param sql 执行的SQL语句
* @param params 注入至SQL语句占位符的值(参数不是必须的)
* @return
*/
public static int executeUpdate(String sql,Object[] params){
int resultCount = -1;
Connection con = JdbcHandler.openConnection();
PreparedStatement pstmt = null;
if(con != null){
try {
pstmt = con.prepareStatement(sql);
//判断是否需要注入参数
if(params != null){
//注入参数
for(int i = 0; i < params.length; i++){
//判断每个参数的类型
//可以直接用Object就不用判断每个参数的class类型了
Object param = params[i];
// if(param.getClass() == Integer.class || param.getClass() == int.class){
// pstmt.setInt(i+1, (int)param);
// }
// else if(param.getClass() == Float.class || param.getClass() == float.class){
// pstmt.setFloat(i+1, (float)param);
// }
// else if(param.getClass() == String.class){
// pstmt.setString(i+1, param.toString());
// }
pstmt.setObject(i+1, param);
}
}
//执行SQL语句:要在if外面进行执行,因为参数可能为null
resultCount = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭数据库:不管try里面的结果如何,都要关闭数据库连接
JdbcHandler.close(con, pstmt, null);
}
}
return resultCount;
}
/**
* 查询行
* @param sql
* @param params
* @param objClass 数据表映射类的Class
* @return
*/
public static <T> List<T> executeQuery(String sql,Object[] params,Class<T> objClass){
List<T> list = new ArrayList();
//获取连接
Connection con = JdbcHandler.openConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
if(con != null){
try {
//创建预处理器
pstmt = con.prepareStatement(sql);
//判断参数是否存在
if(params != null){
//注入参数
for(int i = 0; i < params.length; i++){
pstmt.setObject(i+1, params[i]);
}
}
//执行查询,获得结果集
rs = pstmt.executeQuery();
//获取结果集的元数据
ResultSetMetaData metaData = rs.getMetaData();
//反射获取对象的所有属性:要调用declareFields才能将私有的属性也获取出来
Field[] fields = objClass.getDeclaredFields();
//解析结果集的数据结构,获得结果集的列名
String[] columnNames = JdbcCommonUtil.getColumnNames(metaData);
//迭代结果集
while(rs.next()){
//将实体类实例化:通过无参构造方法创建对象
T t = objClass.newInstance();
//获取每列的值
//遍历通说结果集获取的列名,将列名与属性名进行比较,如果查找到有相对应的属性则将列值赋给属性
for (String columnName : columnNames) {
//System.out.println("列名:"+columnName);
//根据列名查找属性:传入当前遍历的列名和属性名集合
Field field = JdbcCommonUtil.findField(columnName,fields);
if(field != null){
//获取属性的类型
Class fieldClass = field.getType();
//声明列值
Object value = null;
//根据属性类型调用结果集中对应的get方法
if(fieldClass == String.class){
value = rs.getString(columnName);
}
else if(fieldClass == double.class || fieldClass == Double.class){
value = rs.getDouble(columnName);
}
else if(fieldClass == float.class || fieldClass == Float.class){
value = rs.getFloat(columnName);
}
else if(fieldClass == int.class || fieldClass == Integer.class){
value = rs.getInt(columnName);
}
else if(fieldClass == Date.class){
value = rs.getTimestamp(columnName);
}
//System.out.println(value);
//查找相应的setter方法(通过setter方法的名称进行查找setter方法,直接将列值写入),将列值写入
// System.out.println("属性名:"+field.getName());
// System.out.println("set"+JdbcCommonUtil.parseUpperField(field.getName()));
Method method = objClass.getMethod("set"+JdbcCommonUtil.parseUpperField(field.getName()),fieldClass);
//执行setter方法:invoke第一个参数是调用方法的对象是哪个对象,第二个参数是要传入的值
method.invoke(t,value);
}
else{
//未找到属性抛出异常:抛出自定义异常
throw new MappingFieldNotFoundException();
}
}
//System.out.println("---------------------------");
//将实体对象添加至集合
list.add(t);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e){
e.printStackTrace();
}
catch(InvocationTargetException e){
e.printStackTrace();
}
}
//关闭数据库
return list;
}
}
自定义异常:
/**
* 映射属性未找到异常
*/
public class MappingFieldNotFoundException extends RuntimeException {
//如果没有找到相对应的属性和列名,则抛出异常
public MappingFieldNotFoundException() {
super("映射的属性未找到!");
}
}
测试类:
package com.igeek.test;
import com.igeek.dao.UserDao;
public class Test {
public static void main(String[] args) {
//测试修改信息的方法
JdbcUtil.executeUpdate("update users set password=?", new Object[]{"111"});
JdbcUtil.executeUpdate("delete from users where userid=108", null);
JdbcUtil.executeUpdate("update users set " +
"birthday=? where userid=?", new Object[]{new Date(),2});
//测试查询信息的方法
List<User> list = JdbcUtil.executeQuery("select userid,username,password from users", null, User.class);
//循环打印查找的结果
for (User user : list) {
System.out.println(user.getUserId()+"\t"+user.getUserName()+"\t"+user.getPassword());
}
//测试查询信息的方法:列名和属性名称不一致时,用as修改列名方便和属性名进行匹配
List<Emp> list = JdbcUtil.executeQuery("select first_name as firstname,salary,hire_date as hireDate " +
"from emp where department_id=?", new Object[]{50}, Emp.class);
for (Emp emp : list) {
System.out.println(emp.getFirstName()+"\t"+emp.getSalary()+"\t"+emp.getHireDate());
}
//通过用户操作类进行查询单行数据
UserDao userDao = new UserDao();
//新建一个用户
User user = new User();
user.setUserName("testName");
user.setPassword("000");
userDao.add(user);
//测试查询单行数据
User user = userDao.findUserByName("testName");
if(user != null){
System.out.println(user.getUserId()+"\t"+user.getPassword());
}
}
}