手动模拟dbutils

目录结构如下,后面给出相应的实现代码

代码中已经做了非常详细的注释,这里不做解释,直接贴代码

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>day02_eesy_dbassit</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>

        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
    </dependencies>
</project>
  • c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/mybatis</property>
		<property name="user">root</property>
		<property name="password">1234</property>
		<property name="acquireIncrement">5</property>
		<property name="initialPoolSize">10</property>
		<property name="minPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</default-config>
</c3p0-config>
  • C3P0Util
package com.dgut.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
 * C3P0
 *
 */
public class C3P0Util {
	private static ComboPooledDataSource ds = new ComboPooledDataSource();
	public static DataSource getDataSource(){
		return ds;
	}
	public static Connection getConnection() throws SQLException{
		return ds.getConnection();
	}
	public static void main(String[] args) {
		System.out.println(getDataSource());
	}
}
  • ResultSetHandler接口
package com.dgut.handler;
import java.sql.ResultSet;
/**
 * 结果集封装的接口
 */
public interface ResultSetHandler {

    /**
     * 结果集封装的方法
     * @param rs
     * @return
     */
    Object handle(ResultSet rs);
}
  • ResultSetHandler接口的实现类BeanHandler
package com.dgut.handler.impl;
import com.dgut.handler.ResultSetHandler;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
/**
 * 结果集封装的具体实现类。
 * 此类实现的是把一个结果集rs的内容封装到一个指定的实体类对象中
 * 使用要求:
 *      实体类中的属性必须和表中的列名一致(sql语句查询出来的列名一致)
 */
public class BeanHandler implements ResultSetHandler {
    private Class domainClass;
    public BeanHandler(Class domainClass) {
        this.domainClass = domainClass;
    }
    /**
     * 把rs的内容封装到domainClass所表示的类中
     * @param rs
     * @return
     */
    @Override
    public Object handle(ResultSet rs) {
        try {
            //1.创建一个实体类对象
            Object bean = domainClass.newInstance();
            //2.判断是否有结果集
            if(rs.next()){
                //3.得到结果集rs中所有的列名
                //要想得到列名,得先得到结果集的源信息
                ResultSetMetaData rsmd = rs.getMetaData();
                //得到源信息之后,还要得到有多少列
                int columnCount = rsmd.getColumnCount();
                //遍历列数
                for(int i=1;i<=columnCount;i++){
                    //得到每列的名称
                    String columnName = rsmd.getColumnName(i);
                    //列名其实就是实体类的属性名称,于是就可以使用列名得到实体类中属性的描述器
                    PropertyDescriptor pd = new PropertyDescriptor(columnName,domainClass);//实体类中定义的私有类成员和它的get以及set方法
                    //获取属性的写入方法(set方法)
                    Method method = pd.getWriteMethod();
                    //获取当前列名所对应的值
                    Object columnValue = rs.getObject(columnName);
                    //通过执行写方法把得到的值给属性赋上
                    method.invoke(bean,columnValue);
                }
            }
            //4.返回
            return bean;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}
  • ResultSetHandler接口的实现类BeanListHandler
package com.dgut.handler.impl;
import com.dgut.handler.ResultSetHandler;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
public class BeanListHandler implements ResultSetHandler {
    private Class domainClass;
    public BeanListHandler(Class domainClass) {
        this.domainClass = domainClass;
    }
    /**
     * 把rs的内容封装到domainClass所表示的类中
     * @param rs
     * @return
     */
    @Override
    public Object handle(ResultSet rs) {
        try {
            List list = new ArrayList<>();
            //2.判断是否有结果集
            while(rs.next()){
                //1.创建一个实体类对象
                Object bean = domainClass.newInstance();
                //3.得到结果集rs中所有的列名
                //要想得到列名,得先得到结果集的源信息
                ResultSetMetaData rsmd = rs.getMetaData();
                //得到源信息之后,还要得到有多少列
                int columnCount = rsmd.getColumnCount();
                //遍历列数
                for(int i=1;i<=columnCount;i++){
                    //得到每列的名称
                    String columnName = rsmd.getColumnName(i);
                    //列名其实就是实体类的属性名称,于是就可以使用列名得到实体类中属性的描述器
                    PropertyDescriptor pd = new PropertyDescriptor(columnName,domainClass);//实体类中定义的私有类成员和它的get以及set方法
                    //获取属性的写入方法(set方法)
                    Method method = pd.getWriteMethod();
                    //获取当前列名所对应的值
                    Object columnValue = rs.getObject(columnName);
                    //通过执行写方法把得到的值给属性赋上
                    method.invoke(bean,columnValue);
                }
                //把封装好的对象加入到集合中
                list.add(bean);
            }
            //4.返回
            return list;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}
  • 实体类Account
package com.dgut.domain;
import java.io.Serializable;
/**
 * 账户的实体类
 */
public class Account implements Serializable {
    private Integer id;
    private String name;
    private Float money;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Float getMoney() {
        return money;
    }
    public void setMoney(Float money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}
  • 工具类dbassit
package com.dgut.dbassit;
import com.dgut.handler.ResultSetHandler;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
 * 封装的工具类
 */
public class DBAssit {
    private DataSource dataSource;
    public DBAssit(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    /**
     * 执行增删改的方法
     * @param sql
     * @param params
     * @return
     */
    public int update(String sql,Object... params){
        Connection conn = null;
        PreparedStatement pstm = null;
        try {
            //1.得到连接
            conn = dataSource.getConnection();
            //2.使用连接和参数的sql语句创建预处理对象
            pstm = conn.prepareStatement(sql);
            //3.得到sql语句参数的源信息(有几个参数,都什么类型等等)
            ParameterMetaData pmd = pstm.getParameterMetaData();
            //4.判断语句中参数的个数和方法参数params的个数是否一致,不一致肯定没法执行
            int parameterCount = pmd.getParameterCount();//参数的个数(问号的个数)
            if(parameterCount > 0) {
                if (params == null) {
                    throw new NullPointerException("没有sql语句执行必须的参数");
                }
                if (params.length != parameterCount) {
                    throw new RuntimeException("传入的参数个数和语句所需的参数个数不一致,语句无法执行");
                }
            }
            //5.给sql语句的参数赋值
            for(int i=0;i<parameterCount;i++){
                pstm.setObject(i+1,params[i]);
            }
            //6.执行语句
            int res = pstm.executeUpdate();
            //7.返回执行结果
            return res;
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            release(conn,pstm,null);
        }
    }

    public  Object query(String sql, ResultSetHandler rsh, Object... params){
        Connection conn = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            //1.得到连接
            conn = dataSource.getConnection();
            //2.使用连接和参数的sql语句创建预处理对象
            pstm = conn.prepareStatement(sql);
            //3.得到sql语句参数的源信息(有几个参数,都什么类型等等)
            ParameterMetaData pmd = pstm.getParameterMetaData();
            //4.判断语句中参数的个数和方法参数params的个数是否一致,不一致肯定没法执行
            int parameterCount = pmd.getParameterCount();//参数的个数(问号的个数)
            if(parameterCount > 0) {
                if (params == null) {
                    throw new NullPointerException("没有sql语句执行必须的参数");
                }
                if (params.length != parameterCount) {
                    throw new RuntimeException("传入的参数个数和语句所需的参数个数不一致,语句无法执行");
                }
            }
            //5.给sql语句的参数赋值
            for(int i=0;i<parameterCount;i++){
                pstm.setObject(i+1,params[i]);
            }
            //6.执行语句
            rs = pstm.executeQuery();
            //7.返回执行结果
            return rsh.handle(rs);
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            release(conn,pstm,rs);
        }
    }

    private void release(Connection conn,PreparedStatement pstm,ResultSet rs){
        if(rs != null){
            try {
                rs.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        if(pstm != null){
            try {
                pstm.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
  • IAccountDao接口
package com.dgut.dao;
import com.dgut.domain.Account;
import java.util.List;
/**
 * 账户的持久层接口
 */
public interface IAccountDao {
    void save(Account account);
    void update(Account account);
    void delete(Integer accountId);
    Account findById(Integer accountId);
    List<Account> findAll();
}
  • IAccountDao接口的实现类AccountDaoImpl
package com.dgut.dao.impl;
import com.dgut.dao.IAccountDao;
import com.dgut.dbassit.DBAssit;
import com.dgut.domain.Account;
import com.dgut.handler.impl.BeanHandler;
import com.dgut.handler.impl.BeanListHandler;
import com.dgut.utils.C3P0Util;
import java.util.List;
/**
 * 账户的持久层操作
 */
public class AccountDaoImpl implements IAccountDao{
    private DBAssit dbAssit = new DBAssit(C3P0Util.getDataSource());
    @Override
    public void save(Account account) {
        dbAssit.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney());
    }
    @Override
    public void update(Account account) {
        dbAssit.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
    }
    @Override
    public void delete(Integer accountId) {
        dbAssit.update("delete from account where id=?",accountId);
    }
    @Override
    public Account findById(Integer accountId) {
        return (Account)dbAssit.query("select * from account where id = ?",new BeanHandler(Account.class),accountId);
    }
    @Override
    public List<Account> findAll() {
        return (List<Account>)dbAssit.query("select * from account",new BeanListHandler(Account.class));
    }
}
  •  测试类Test
package com.dgut;
import com.dgut.dao.IAccountDao;
import com.dgut.dao.impl.AccountDaoImpl;
import com.dgut.domain.Account;
import java.util.List;
/**
 * 测试
 */
public class Test {
    public static void main(String[] args) {
//        Account account = new Account();
//        account.setName("ccc");
//        account.setMoney(1234f);
        IAccountDao accountDao = new AccountDaoImpl();
//        accountDao.save(account);
//        Account account = accountDao.findById(1);
//        System.out.println(account);
        List<Account> accounts = accountDao.findAll();
        System.out.println(accounts);
    }
}
发布了93 篇原创文章 · 获赞 80 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_40391011/article/details/104190927
今日推荐