NamedParameterJdbcTemplate来自其自己的Mapper内部的用法

时间:2016-03-05 18:55:00

标签: java mysql spring spring-mvc

我是Spring的新手,我使用spring mvc构建一个连接到mysql db的简单网页,但是我得到了空指针,我尝试使用NamedParameterJdbcTemplate查询另一个NamedParameterJdbcTemplate目前正在执行

通过此bean配置(spring-web-servlet.xml)创建的db定义

<bean id="dataSource" destroy-method="close"
    class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url"
        value="jdbc:mysql://#{systemEnvironment[OPENSHIFT_MYSQL_DB_HOST]}:#{systemEnvironment[OPENSHIFT_MYSQL_DB_PORT]}/#{systemEnvironment[OPENSHIFT_APP_NAME]}" />
    <property name="username"
        value="#{systemEnvironment[OPENSHIFT_MYSQL_DB_USERNAME]}" />
    <property name="password"
        value="#{systemEnvironment[OPENSHIFT_MYSQL_DB_PASSWORD]}" />
    <property name="initialSize" value="3" />
</bean>

这个配置类(SpringDBConfig.java)

@Configuration
public class SpringDBConfig {
    @Autowired
    DataSource dataSource;

    @Bean
    public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
        return new NamedParameterJdbcTemplate(dataSource);
    }
}

首先,我的数据库是这种

CREATE TABLE `TIPOSREGALO` (
  `TIPOREGALO_ID` varchar(50) NOT NULL,
  `DESCRIPCION` varchar(5000) NOT NULL,
  `URLFOTO` varchar(255) NOT NULL, 
  PRIMARY KEY (`TIPOREGALO_ID`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8;

CREATE TABLE `REGALOS` (
  `REGALO_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `TIPOREGALO_ID` varchar(50) NOT NULL,
  `TITULO` varchar(50) NOT NULL,
  `DESCRIPCION` varchar(5000) NOT NULL,
  `URLFOTO` varchar(255) NOT NULL, 
  `PRECIO` integer unsigned NOT NULL,
  PRIMARY KEY (`REGALO_ID`) USING BTREE,
  FOREIGN KEY (`TIPOREGALO_ID`) REFERENCES `TIPOSREGALO`(`TIPOREGALO_ID`) 
) ENGINE=INNODB DEFAULT CHARSET=utf8;

我的DAO从控制器那里调用

@RequestMapping(value = "/gift/{id}", method = RequestMethod.GET)
public String giftdetail(@PathVariable("id") int regalo_id, Model model) {
    model.addAttribute("regalo", regaloService.findById(regalo_id));
    return "weddinglist/gift";
}

RegaloService方法是

@Override
public Regalo findById(int id) {
    return regaloDao.findById(id);
}

regaloDao是

 @Repository
    public class RegaloDaoImpl implements RegaloDao {

        private final Logger logger = LoggerFactory.getLogger(RegaloDaoImpl.class);

        NamedParameterJdbcTemplate namedParameterJdbcTemplate;

        @Autowired
        public void setNamedParameterJdbcTemplate(
                NamedParameterJdbcTemplate namedParameterJdbcTemplate)
                throws DataAccessException {
            this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
        }

        @Override
        public Regalo findById(Integer regalo_id) {
            logger.debug("findById() id: \"{}\"", regalo_id);

            Map<String, Object> params = new HashMap<String, Object>();
            params.put("regalo_id", regalo_id);

            String sql = "SELECT * FROM REGALOS WHERE REGALO_ID=:regalo_id";

            Regalo result = null;
            try {
                result = namedParameterJdbcTemplate.queryForObject(sql, params,
                        new RegaloMapper());
            } catch (EmptyResultDataAccessException e) {
                // do nothing, return null
            }
            return result;
        }
    ...

        private static final class RegaloMapper implements RowMapper<Regalo> {

            private final Logger logger = LoggerFactory
                .getLogger(RegaloMapper.class);

            public Regalo mapRow(ResultSet rs, int rowNum) throws SQLException {


                Regalo regalo = new Regalo();
                regalo.setRegalo_id(rs.getInt("REGALO_ID"));

                TipoRegaloDao tipoRegaloDao = new TipoRegaloDaoImpl();
                regalo.setTiporegalo(tipoRegaloDao.findById(rs
                        .getString("TIPOREGALO_ID")));

                regalo.setTitulo(rs.getString("TITULO"));
                regalo.setDescripcion(rs.getString("DESCRIPCION"));
                regalo.setUrlfoto(rs.getString("URLFOTO"));
                regalo.setPrecio(rs.getInt("PRECIO"));
                return regalo;
            }
        }
    }

如您所见,调用regalo.setTiporegalo(tipoRegaloDao.findById(rs.getString(&#34; TIPOREGALO_ID&#34;)));当前者对queryForObject的调用没有完成时,在Mapper中生成,然后执行转到TipoRegaloDaoImpl.findById()并尝试调用一个空的namedParameterJdbcTemplate对象

@Repository
public class TipoRegaloDaoImpl implements TipoRegaloDao {

    private final Logger logger = LoggerFactory
            .getLogger(TipoRegaloDaoImpl.class);

    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    public void setNamedParameterJdbcTemplate(
            NamedParameterJdbcTemplate namedParameterJdbcTemplate)
            throws DataAccessException {
        logger.debug("setNamedParameterJdbcTemplate() namedParameterJdbcTemplate: \"{}\"", namedParameterJdbcTemplate);
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
    }

    @Override
    public TipoRegalo findById(String tiporegalo_id) {
        logger.debug("findById() id: \"{}\"", tiporegalo_id);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("tiporegalo_id", tiporegalo_id);

        String sql = "SELECT * FROM TIPOSREGALO WHERE TIPOREGALO_ID=:tiporegalo_id";

        TipoRegalo result = null;
        try {
            result = namedParameterJdbcTemplate.queryForObject(sql, params,
                        new TipoRegaloMapper());

            logger.debug("findById() result: \"{}\"", result);


        } catch (EmptyResultDataAccessException e) {
            logger.error("findById() Resultado vacio, excepcion " + e);
            // do nothing, return null
        } catch (Exception e) {
            logger.error("findById() No se que ha pasado aqui, excepcion " + e);
            // do nothing, return null
        }
        return result;
    }
 ....

queryForObject失败并出现nullpointerexception

任何线索?

由于

1 个答案:

答案 0 :(得分:1)

Add-Type -Path "Serilog.dll"
#Add-Type -Path "Serilog.Sinks.Seq.dll"
#Add-Type -Path "Serilog.Sinks.EventLog.dll"
Add-Type -Path "serilog.sinks.elasticsearch.dll"
Add-Type -Path "Serilog.FullNetFx.dll"
Add-Type -Path "Elasticsearch.Net.dll"
#Add-Type -Path "Serilog.Extras.AppSettings.dll"
#Add-Type -Path "Serilog.Extras.Timing.dll"

$config = New-Object -TypeName "Serilog.LoggerConfiguration"
[Serilog.Configuration.LoggerSinkConfiguration]$ConfigSink = $config.WriteTo

<#
[Serilog.Log]::Logger = [Serilog.LoggerConfigurationFullNetFxExtensions]::RollingFile
                                ($ConfigSink,
                                "C:\Logs\Log-{Date}.txt",
                        ([Serilog.Events.LogEventLevel]::Verbose), "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}", $null, 10000000, 15).CreateLogger()
#>

$config.CreateLogger()

[Serilog.Log]::Logger = [Serilog.LoggerConfigurationElasticsearchExtensions]::Elasticsearch($ConfigSink, "http://192.168.1.125:9200", "custom-index-{0:yyyy.MM}", "asdd"),
                        ([Serilog.Events.LogEventLevel]::Verbose), "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}", $null, 10000000, 15).CreateLogger()

[Serilog.Log]::Information("Logging starte");

这会创建一个TipoRegaloDaoImpl,并且永远不会初始化它的TipoRegaloDao tipoRegaloDao = new TipoRegaloDaoImpl(); 。 Spring只能自动装配自己创建的bean。不是您使用namedParameterJdbcTemplate创建的。在RegaloDaoImpl中注入TipoRegaloDao(并使映射器成为内部类而不是嵌套的静态类,以允许它访问该字段)。

如果您使用构造函数注入而不是字段注入,那么您永远不会遇到此问题,因为很明显TipoRegaloDaoImpl需要一个namedParameterJdbcTemplate:它将是其构造函数参数之一。但总的来说,每次使用new创建Spring bean时,都会出错。