springboot jdbc配合hibernate使用,jdbcTemplate查询结果可根据@Column 映射

本文介绍了在SpringBoot项目中,如何将Hibernate与JdbcTemplate结合使用,并着重解决了当数据库字段非驼峰命名时,查询结果映射到Bean时的问题。通过重写BeanPropertyRowMapper实现字段的正确映射。
摘要由CSDN通过智能技术生成

项目中用的是hibernate作为dao层,但是使用hibernate进行sql查询总觉得不方便,于是又整合了jdbcTemplate,但是如果字段不是驼峰命名就无法正确映射,研究一番,找到下面这个办法:重写BeanPropertyRowMapper


/**
 * @Author: ZFY
 * @Date: 2018/10/29 19:18
 * @Description: 由org.springframework.jdbc.core.BeanPropertyRowMapper改造,扩展注解映射
 * 优先使用驼峰命名映射,找不到映射的则根据注解{@link Column}映射
 */
public class PropertyAnnotationRowMapper<T> implements RowMapper<T> {
   

    /** Logger available to subclasses */
    protected final Log logger = LogFactory.getLog(getClass());

    /** The class we are mapping to */
    private Class<T> mappedClass;

    /** Whether we're strictly validating */
    private boolean checkFullyPopulated = false;

    /** Whether we're defaulting primitives when mapping a null value */
    private boolean primitivesDefaultedForNullValue = false;

    /** ConversionService for binding JDBC values to bean properties */
    private ConversionService conversionService = DefaultConversionService.getSharedInstance();

    /** Map of the fields we provide mapping for */
    private Map<String, PropertyDescriptor> mappedFields;
    /** 注解到类属性值的映射 */
    private Map<String, PropertyDescriptor> mappedAnnotation;

    /** Set of bean properties we provide mapping for */
    private Set<String> mappedProperties;


    /**
     * Create a new {@code BeanPropertyRowMapper} for bean-style configuration.
     * @see #setMappedClass
     * @see #setCheckFullyPopulated
     */
    public PropertyAnnotationRowMapper() {
   
        initialize(mappedClass);
    }

    /**
     * Create a new {@code BeanPropertyRowMapper}, accepting unpopulated
     * properties in the target bean.
     * <p>Consider using the {@link #newInstance} factory method instead,
     * which allows for specifying the mapped type once only.
     * @param mappedClass the class that each row should be mapped to
     */
    public PropertyAnnotationRowMapper(Class<T> mappedClass) {
   
        initialize(mappedClass);
    }

    /**
     * Create a new {@code BeanPropertyRowMapper}.
     * @param mappedClass the class that each row should be mapped to
     * @param checkFullyPopulated whether we're strictly validating that
     * all bean properties have been mapped from corresponding database fields
     */
    public PropertyAnnotationRowMapper(Class<T> mappedClass, boolean checkFullyPopulated) {
   
        initialize(mappedClass);
        this.checkFullyPopulated = checkFullyPopulated;
    }


    /**
     * Set the class that each row should be mapped to.
     */
    public void setMappedClass(Class<T> mappedClass) {
   
        if (this.mappedClass == null) {
   
            initialize(mappedClass);
        }
        else {
   
            if (this.mappedClass != mappedClass) {
   
                throw new InvalidDataAccessApiUsageException("The mapped class can not be reassigned to map to " +
                        mappedClass + " since it is already providing mapping for " + this.mappedClass);
            }
        }
    }

    /**
     * Get the class that we are mapping to.
     */
    public final Class<T> getMappedClass() {
   
        return this.mappedClass;
    }

    /**
     * Set whether we're strictly validating that all bean properties have been mapped
     * from corresponding database fields.
     * <p>Default is {@code false}, accepting unpopulated properties in the target bean.
     */
    public void setCheckFullyPopulated(boolean checkFullyPopulated) {
   
        this.checkFullyPopulated = checkFullyPopulated;
    }

    /**
     * Return whether we're strictly validating that all bean properties have been
     * mapped from corresponding database fields.
     */
    public boolean isCheckFullyPopulated() {
   
        return this.checkFullyPopulated;
    }

    /**
     * Set whether we're defaulting Java primitives in the case of mapping a null value
     * from corresponding database fields.
     * <p>Default is {@code false}, throwing an exception when nulls are mapped to Java primitives.
     */
    public void setPrimitivesDefaultedForNullValue(boolean primitivesDefaultedForNullValue) {
   
        this.primitivesDefaultedForNullValue = primitivesDefaultedForNullValue;
    }

    /**
     * Return whether we're defaulting Java primitives in the case of mapping a null value
     * from corresponding database fields.
     */
    public boolean isPrimitivesDefaultedForNullValue() {
   
        return this.primitivesDefaultedForNullValue;
    }

    /**
     * Set a {@link ConversionService} for binding JDBC values to bean properties,
     * or {@code null} for none.
     * <p>Default is a {@link DefaultConversionService}, as of Spring 4.3. This
     * provides support for {@code java.time} conversion and other special types.
     * @since 4.3
     * @see #initBeanWrapper(BeanWrapper)
     */
    public void setConversionService(ConversionService conversionService) {
   
        this.conversionService = conversionService;
    }

    /**
     * Return a {@link ConversionService} for binding JDBC values to bean properties,
     * or {@code null} if none.
     * @since 4.3
     */
    public ConversionService getConversionService() {
   
        return this.conversionService;
    }


    /**
     * Initialize the mapping meta-data for the given class.
     * @param mappedClass the mapped class
     */
    protected void initialize(Class<T> mappedClass) {
   
        this.mappedClass = mappedClass;
        this.mappedFields = new HashMap<String, PropertyDescriptor>();
        this.mappedProperties = new HashSet<String>();
        //添加根据注解映射的代码
        this.mappedAnnotation = new HashMap<String,PropertyDescriptor>();
        PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass);
        for (PropertyDescriptor pd : pds) {
   
            if (pd.getWriteMethod() != null) {
   
                this.mappedFields.put(lowerCaseName(pd.getName()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值