DAO设计模式从开始到实现-详细到你不可思议

读配置文件

配置文件名为jdbc.properties

在这里插入图片描述

  1. 创建dataSource和ThreadLock【】

    private static DataSource dataSource;
    private static final ThreadLocal<Connection> ts = new ThreadLocal<>();
    
  2. 读取配置文件【】

    InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
    
  3. 加载配置没见【】

    Properties ps = new Properties();
    ps.load(is);
    
  4. 联接datasource【】

    dataSource = DruidDataSourceFactory.createDataSource(ps);
    
书写工具方法jdbcutil
interface jdbcutil{

    public static Connection getConnection();//获取数据库连接

    public static PreparedStatement createPreparedStatement(String sql, Object... params) ;//由于PreparedStatement 既有预加载的性能可以提高速度,但是由于加载sql语句是insertinto tb_user values(?,?,?,...);的形式,故需要将params里面的值一一赋值;

    public static ResultSet executeQuery(String sql, Object... params);//获取数据库数据的方法,返回结果集 (ResultSet);

    public static int executeUpdate(String sql, Object... params);//数据库增删改的操作,返回值是一个影响数据库行数的值;

    public static void releaseConnection();//关闭连接,实际是将数据库连接归还数据池

}

实体类

public class JdbcUtil implement jdbcutil{
	private JdbcUtil() {
	}

	private static DataSource dataSource;
	private static final ThreadLocal<Connection> ts = new ThreadLocal<>();
	static {
		try {
			InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
			Properties ps = new Properties();
			ps.load(is);
			dataSource = DruidDataSourceFactory.createDataSource(ps);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
//数据库增删改的操作,返回值是一个影响数据库行数的值;
	public static int executeUpdate(String sql, Object... params) {
		try {
			return createPreparedStatement(sql, params).executeUpdate();
		} catch (

		Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}
    //获取数据库数据的方法,返回结果集 
	public static ResultSet executeQuery(String sql, Object... params) {

		try {

			return createPreparedStatement(sql, params).executeQuery();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}
//由于PreparedStatement 既有预加载的性能可以提高速度,但是由于加载sql语句是insertinto tb_user values(?,?,?,...);的形式,故需要将params里面的值一一赋值;
	public static PreparedStatement createPreparedStatement(String sql, Object... params) {
		try {
			Connection conn = getConnection();
			PreparedStatement ps = conn.prepareStatement(sql);
			if (params != null && params.length > 0)
				for (int i = 0; i < params.length; i++)
					ps.setObject(i + 1, params[i]);
			return ps;
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}

// 获取连接的方法
	public static Connection getConnection() {
		Connection res = ts.get(); 
		if (res == null) {
			try {
				res = dataSource.getConnection(); 
				ts.set(res); 
			} catch (Exception e) {
				throw new RuntimeException(e.getMessage());
			}
		}
		return res;
	}

// 释放连接的方法
	public static void releaseConnection() {
		Connection conn = ts.get(); 
		if (conn != null) {
			try {
				conn.close(); 
				ts.remove(); 
			} catch (Exception e) {
				throw new RuntimeException(e.getMessage());
			}
		}
	}
}
DAO模式
  1. basedao接口dao类//定义数据库基本功能的接口【】

    public interface IBaseDao<T extends Serializable> {
        public int save(T t);  
        public int delete(T t); 
        public int update(T t); 
        public List<T> findByExample(T t);//第一步获取调用new对象的Class反射类队形,以便于寻找数据库里面对应的表,进行数据操作
                private Class<T> clazz;
                public BaseDaoImpl() {
                    Class<? extends IBaseDao> clz = this.getClass();
                    Type type = clz.getGenericSuperclass();
                    // ParameterizedType参数化类型,即泛型
                    ParameterizedType p = (ParameterizedType) type;
                    // getActualTypeArguments获取参数化类型的数组,泛型可能有多个
                    clazz = (Class) p.getActualTypeArguments()[0];
                    System.out.println(clazz);
                 }
    //第二步建立list集合来记录T类型里面的值,主要作用是为了给sql语句里面的参数(?)进行替换赋值
                List<Object> params = new ArrayList<>();
    //第三步利用反射获取实体类里面的属性,
                Field[] fs = clazz.getDeclaredFields();
    //第四步建立需要的sql语句,并根据第三获取属性里面的值;
                StringBuilder sb = new StringBuilder("select * from tb_");
                sb.append(clazz.getSimpleName().toLowerCase()).append(" where 1=1 ");
                for (int i = 1; i < fs.length; i++) {
                    Field f = fs[i];
                    f.setAccessible(true);
                    Object val = f.get(obj);
                    if (val != null) {
                        sb.append(" and ").append(f.getName()).append("=? ");
                        params.add(val);
                    }
                 }
                ResultSet rs = JdbcUtil.executeQuery(sb.toString(), params.toArray());
    //第五步根据结果集返回数据库里面的数据,利用反射,进行赋值返回到list
                while (rs.next()) {
                    ResultSetMetaData rsmd = rs.getMetaData();
                    T t = clazz.newInstance(); 
                    for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                        String fieldName = rsmd.getColumnLabel(i); 
                        Field f = clazz.getDeclaredField(fieldName); 
                        f.setAccessible(true);
                        f.set(t, rs.getObject(i)); 
                    }
                    res.add(t);
                 }
                 rs.close();}
    
  2. basedaolmp实现basedao的dao类//实现定义数据库基本功能的类

    public abstract class BaseDaoImpl<T extends Serializable> implements IBaseDao<T> {
        
    }
    
  3. userdao实体dao类//实现basedao接口功能并且含有自己独有的功能的具体接口

    public interface IUserDao extends IBaseDao<User>{
    	//如果有userDao中需要添加的特殊方法,声明在这里
    	}
    
  4. userdaoImp实现实体类的dao类//实现具体类的功能的实现类

    public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao {
    	// 如果有特殊方法,则在这里实现,实际上通用的CRUD方法已经从BaseDao中继承
    }
    
  5. (User)具体类//注意要和数据库表的类名要一样

    public class User implements Serializable {
    	private static final long serialVersionUID = 4118906006740949960L;
    	private Long id;
    	private String username;
    	private String password;
    }
    
  6. factorydao工厂类//在一个类的时候就可以不要这个,但是当有多个实体dao类的时候就需要这个工厂类

public class DaoFactory {
	public static UserDaoImpl getUserDao1(String clzz) {
		String key = clzz;
		switch (key) {
		case "user":
			return new UserDaoImpl();
		case "book":
			return new bookDaoImpl();
		default:
			return null;
		}
	}
}	

7.测试类

IUserDao iuse = DaoFactory.getUserDao1("user");
User user = new User();
iuse.save(user);
iuse.delete(user);
iuse.update(user);
List list = iuse.findByExample(user);
System.out.println(list);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值