javaweb----dao重构实现
实体类,与数据库的字段映射。。。。。处理
package cn.edu.cque.mall.entity; import cn.edu.cque.mall.common.Column; import lombok.Data; import lombok.ToString; import java.util.Date; /** * @ClassName Product * @Description Product实体类 * @Author YoungWinter * @Date 2020/9/22 14:10 * @Version 1.0 **/ @Data @ToString public class Product { // ID @Column("pid") private String id; // 商品名称A @Column("pname") private String name; // 商品的市场价格 @Column("market_price") private Double marketPrice; // 商品的商城价格 @Column("shop_price") private Double shopPrice; // 商品的图片URL @Column("pimage") private String image; // 商品上架的时间 @Column("pdate") private Date createDate; // 是否热销 1 热销 0 不是热销 @Column("is_hot") private Integer isHot; // 商品的描述 @Column("pdesc") private String desc; // 是否上架 0 上架 1 下架 @Column("pflag") private Integer flag; // 商品的分类ID @Column("cid") private String cid; }
dao接口的抽象方法的注解sql,,注解对象的定义实现:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Path { String value(); }
dao层编写层接口,抽象方法加注解的方式体现。。。。。形成目标接口
SQL注解:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Sql { String value(); }
接口的具体内容:
package cn.edu.cque.mall.mapper; import cn.edu.cque.mall.common.Sql; import cn.edu.cque.mall.entity.Product; import java.util.List; /** * @ClassName ProductMapper * @Description TODO * @Author YoungWinter * @Date 2020/9/23 16:33 * @Version 1.0 **/ public interface ProductMapper { @Sql("select * from product where pid = ?") Product findById(String id); @Sql("select count(*) from product where cid = ?") int findTotalNumber(String cid); @Sql("select * from product where cid = ? limit ?, ?") List<Product> findListByCidAndPage(String cid, int index, int pageSize); @Sql("select * from product where is_hot = ? limit ?, ?") List<Product> findHot(int isHot, int index, int size); @Sql("select * from product order by pdate desc limit ?, ?") List<Product> findNews(int isHot, int index, int size); @Sql("select * from product where cid = ?") List<Product> findListByCid(String cid); }
然后就利用proxy动态代理技术,对方法增强。。。。。实现业务逻辑,实现 InvocationHandler 接口
package cn.edu.cque.mall.common; import cn.edu.cque.mall.entity.Product; import cn.edu.cque.mall.utils.DruidUtil; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import java.lang.reflect.*; import java.sql.ResultSet; import java.util.List; /** * @ClassName MapperHandler * @Description TODO * @Author YoungWinter * @Date 2020/9/23 16:12 * @Version 1.0 **/ public class MapperHandler implements InvocationHandler { private JdbcTemplate template = new JdbcTemplate(DruidUtil.getDataSource()); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 1 获取sql语句 String sql = method.getAnnotation(Sql.class).value(); // 2 获取返回值类型用于封装对象 Class returnType = method.getReturnType(); boolean isList = false; if (returnType.equals(List.class)) { // java.util.Map<cn.edu.cque.mall.entity.Category,String> isList = true; returnType = (Class)(((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0]); } // 3 使用JdbcTemplate去执行sql并返回结果 List list = template.query(sql, new ProductRowMapper(returnType), args); // 4 根据返回值类型返回结果 // 4.1 如果是List类型,直接返回 if (isList) return list; // 4.2 如果不是List类型,返回list的第一个元素 if (list != null && list.size() > 0) return list.get(0); return null; } // 将数据库中的数据封装成实体类的一个内部类 private class ProductRowMapper<T> implements RowMapper<T> { public ProductRowMapper(Class<T> entityClass) { this.entityClass = entityClass; } // 实体类类型 private Class<T> entityClass; @Override public T mapRow(ResultSet rs, int rowNum) { T t = null; try { t = entityClass.newInstance(); // 封装对象 // 找到属性的setter,然后将对应的列数据通过setter封装到实体类中 Field[] fields = entityClass.getDeclaredFields(); for (Field field : fields) { // name ---> setName() Method method = entityClass.getDeclaredMethod(getSetter(field.getName()), field.getType()); method.invoke(t, rs.getObject(field.getAnnotation(Column.class).value())); } } catch (Exception e) { e.printStackTrace(); } return t; } } private String getSetter(String name) { String first = String.valueOf(name.charAt(0)).toUpperCase(); String substring = name.substring(1); return "set" + first + substring; } }
处理器对象。。业务逻辑就是反射技术获取接口里面的注解与方法还有实体类的相关信息。。。。。然后调用getset方法数据结果集封装
具体看代码了解。。。。。
作者:隔壁老郭
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
Java入门到入坟
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南