斷續踹了兩三天,搞定使用Annotation配置Data Tier,作為Spring-Security驗證來源。一樣用jdbc.properties對定義連線資訊,和applicationContext.xml放同一處可以被classpath找到,是故在applicationContext.xml設定如下:
接著設定DataSource的Bean,在AppConfig內容如下:
public class AppConfig { private static Logger logger = LoggerFactory.getLogger(AppConfig.class); private @Value("#{jdbcProperties.driverClassName}") String driverClass; private @Value("#{jdbcProperties.url}") String jdbcUrl; private @Value("#{jdbcProperties.username}") String username; private @Value("#{jdbcProperties.password}") String password;
@Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(this.driverClass); dataSource.setUrl(this.jdbcUrl); dataSource.setUsername(this.username); dataSource.setPassword(this.password); logger.debug("init dataSource"); return dataSource; } }
|
AppConfig上頭沒放@Component,照樣被Spring找到@Bean,而@Value是讀jdbc.properties內容載入後面的String變數,jdbcProperties對映到applicationContext.xml的<util:properties>標籤的id屬性,而jdbcProperties.後面接的屬性即是jdbc.properties的key name。
接著是寫Dao去引用AppConfig的Data Source @Bean,我是繼承Spring-Security的UserDetailsService當DAO用:
@Repository public class UserDetailsServiceImpl implements UserDetailsService { private static Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class); private SimpleJdbcTemplate simpleJdbcTemplate; @Autowired public void init(DataSource datasource) { this.simpleJdbcTemplate = new SimpleJdbcTemplate(datasource); logger.debug("init: after new JdbcTemplate"); } public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { String sql = "select * from accounts where username=? "; RowMapper<UserDetails> mapper = new ParameterizedRowMapper<UserDetails>() { public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException { String username = rs.getString("username"); String password = rs.getString("password"); logger.debug("id/pwd=" + username + "/" + password); UserDetailsImpl user = new UserDetailsImpl(username, password); return user; } }; UserDetails user = this.simpleJdbcTemplate.queryForObject(sql, mapper, username); if (user == null) throw new UsernameNotFoundException(username + " not found!"); return user; } } |
類別宣告為@Repository,效果和@Component一樣,除了是標明為DAO功能外,還真不知和@Component有哪裡不同。也許不同處就再下面的@Autowired後接的method,它傳入一個DataSource的參數,正是來自dataSource @Bean注入的。而使用Composited模式放JdbcTemplate是Spring3官方文件所建議的Best Practices,因為是使用SimpleJdbcTemplate,較之JdbcTempalte語法乾淨,從第三個參數起可帶無不限個數的參數。
simpleJdbcTemplate.queryForObject(SQL字串, RowMapper實作, …)
留言列表