十九剧蚣、Spring Boot使用JdbcTemplate

1、添加數(shù)據(jù)源

既然要使用JdbcTemplate牧挣,就需要添加jdbc的依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

2醒陆、連接數(shù)據(jù)源浸踩,以mysql為例:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

3、在src/main/resources/application.properties中配置數(shù)據(jù)源信息

注意:其中driver-class可以不寫统求,Spring Boot會(huì)自動(dòng)從url中解析使用的數(shù)據(jù)源類

Spring Boot默認(rèn)采用tomcat-jdbc連接池检碗,如果需要C3P0,DBCP码邻,Druid等作為連接池折剃,需要加入相關(guān)依賴以及配置,這里不作說(shuō)明像屋,采用默認(rèn)配置即可怕犁。

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=...
spring.datasource.password=...

底層默認(rèn)使用tomcat-jdbc連接池,所以在默認(rèn)情況下會(huì)創(chuàng)建一個(gè)基于Tomcat連接池的DataSource,并注入到Spring IOC容器中奏甫。

abstract class DataSourceConfiguration {

    @SuppressWarnings("unchecked")
    protected <T> T createDataSource(DataSourceProperties properties,
            Class<? extends DataSource> type) {
        return (T) properties.initializeDataSourceBuilder().type(type).build();
    }

    /**
     * Tomcat Pool DataSource configuration.
     */
    @ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true)
    static class Tomcat extends DataSourceConfiguration {

        //創(chuàng)建一個(gè)基于Tomcat連接池的DataSource的Bean
        //由于底層使用Tomcat連接池戈轿,在不引入外部數(shù)據(jù)連接池的jar包之前,默認(rèn)使用Tomcat的DataSource
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.tomcat")
        public org.apache.tomcat.jdbc.pool.DataSource dataSource(
                DataSourceProperties properties) {
            org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(
                    properties, org.apache.tomcat.jdbc.pool.DataSource.class);
            DatabaseDriver databaseDriver = DatabaseDriver
                    .fromJdbcUrl(properties.determineUrl());
            String validationQuery = databaseDriver.getValidationQuery();
            if (validationQuery != null) {
                dataSource.setTestOnBorrow(true);
                dataSource.setValidationQuery(validationQuery);
            }
            return dataSource;
        }

    }

    /**
     * Hikari DataSource configuration.
     */
    @ConditionalOnClass(HikariDataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
    static class Hikari extends DataSourceConfiguration {

        //創(chuàng)建基于hikari的DataSource的Bean
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.hikari")
        public HikariDataSource dataSource(DataSourceProperties properties) {
            return createDataSource(properties, HikariDataSource.class);
        }

    }

    /**
     * DBCP DataSource configuration.
     *
     * @deprecated as of 1.5 in favor of DBCP2
     */
    @ConditionalOnClass(org.apache.commons.dbcp.BasicDataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp.BasicDataSource", matchIfMissing = true)
    @Deprecated
    static class Dbcp extends DataSourceConfiguration {

        //創(chuàng)建基于dbcp的DataSource的Bean
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.dbcp")
        public org.apache.commons.dbcp.BasicDataSource dataSource(
                DataSourceProperties properties) {
            org.apache.commons.dbcp.BasicDataSource dataSource = createDataSource(
                    properties, org.apache.commons.dbcp.BasicDataSource.class);
            DatabaseDriver databaseDriver = DatabaseDriver
                    .fromJdbcUrl(properties.determineUrl());
            String validationQuery = databaseDriver.getValidationQuery();
            if (validationQuery != null) {
                dataSource.setTestOnBorrow(true);
                dataSource.setValidationQuery(validationQuery);
            }
            return dataSource;
        }

    }

    /**
     * DBCP DataSource configuration.
     */
    @ConditionalOnClass(org.apache.commons.dbcp2.BasicDataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp2.BasicDataSource", matchIfMissing = true)
    static class Dbcp2 extends DataSourceConfiguration {

        //創(chuàng)建基于dbcp2的DataSource的Bean
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.dbcp2")
        public org.apache.commons.dbcp2.BasicDataSource dataSource(
                DataSourceProperties properties) {
            return createDataSource(properties,
                    org.apache.commons.dbcp2.BasicDataSource.class);
        }
    }
    
    /**
     * Generic DataSource configuration.
     */
    @ConditionalOnMissingBean(DataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type")
    static class Generic {

        //可以在配置文件中通過(guò)spring.datasource.type指定外部的dataSource類型阵子,并創(chuàng)建基于該type的DataSource的Bean
        @Bean
        public DataSource dataSource(DataSourceProperties properties) {
            return properties.initializeDataSourceBuilder().build();
        }

    }
}

4思杯、使用JdbcTemplate操作數(shù)據(jù)庫(kù)

SpringBoot中的 JdbcTemplate 是自動(dòng)配置的,可以直接使用 @Autowired 或者 @Resource 來(lái)注入到需要的類中挠进。

JdbcTemplateAutoConfiguration

@Configuration
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
//在DataSourceAutoConfiguration自動(dòng)配置類完成后再進(jìn)行自動(dòng)配置該類JdbcTemplateAutoConfiguration
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class JdbcTemplateAutoConfiguration {

    private final DataSource dataSource;

    public JdbcTemplateAutoConfiguration(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    //創(chuàng)建一個(gè)JdbcTemplate的Bean
    @Bean
    @Primary
    @ConditionalOnMissingBean(JdbcOperations.class)
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(this.dataSource);
    }

    @Bean
    @Primary
    @ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
        return new NamedParameterJdbcTemplate(this.dataSource);
    }

}

JdbcTemplateAutoConfiguration類中會(huì)創(chuàng)建一個(gè)JdbcTemplate的Bean色乾,所以在使用的時(shí)候可以直接注入。

DataSourceAutoConfiguration

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
//啟動(dòng)DataSourceProperties配置類
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {

    private static final Log logger = LogFactory
            .getLog(DataSourceAutoConfiguration.class);

    @Bean
    @ConditionalOnMissingBean
    public DataSourceInitializer dataSourceInitializer(DataSourceProperties properties,
            ApplicationContext applicationContext) {
        //根據(jù)配置文件屬性創(chuàng)建DataSource的初始化器
        return new DataSourceInitializer(properties, applicationContext);
    }
    
    //...
}

[圖片上傳失敗...(image-febd30-1556178324854)]

DataSourceInitializer

class DataSourceInitializer implements ApplicationListener<DataSourceInitializedEvent> {
    private final DataSourceProperties properties;
    private final ApplicationContext applicationContext;
    private DataSource dataSource;
    private boolean initialized = false;
    DataSourceInitializer(DataSourceProperties properties,
            ApplicationContext applicationContext) {
        this.properties = properties;
        this.applicationContext = applicationContext;
    }
    @PostConstruct
    public void init() {
        //當(dāng)DataSourceProperties初始化完成后
        if (!this.properties.isInitialize()) {
            logger.debug("Initialization disabled (not running DDL scripts)");
            return;
        }
        if (this.applicationContext.getBeanNamesForType(DataSource.class, false,
                false).length > 0) {
            //獲取DataSource的bean
            this.dataSource = this.applicationContext.getBean(DataSource.class);
        }
        if (this.dataSource == null) {
            logger.debug("No DataSource found so not initializing");
            return;
        }
        //執(zhí)行schema腳本
        runSchemaScripts();
    }


    private void runSchemaScripts() {
        //查看全局配置文件中是否有spring.datasource.schema
        List<Resource> scripts = getScripts("spring.datasource.schema",
                this.properties.getSchema(), "schema");
        if (!scripts.isEmpty()) {
            String username = this.properties.getSchemaUsername();
            String password = this.properties.getSchemaPassword();
            runScripts(scripts, username, password);
            try {
                this.applicationContext
                        .publishEvent(new DataSourceInitializedEvent(this.dataSource));
                // The listener might not be registered yet, so don't rely on it.
                if (!this.initialized) {
                    //執(zhí)行數(shù)據(jù)插入腳本
                    runDataScripts();
                    this.initialized = true;
                }
            }
            catch (IllegalStateException ex) {
                logger.warn("Could not send event to complete DataSource initialization ("
                        + ex.getMessage() + ")");
            }
        }
    }


    @Override
    public void onApplicationEvent(DataSourceInitializedEvent event) {
        if (!this.properties.isInitialize()) {
            logger.debug("Initialization disabled (not running data scripts)");
            return;
        }
        // NOTE the event can happen more than once and
        // the event datasource is not used here
        //如果初始化完成后领突,執(zhí)行數(shù)據(jù)插入
        if (!this.initialized) {
            runDataScripts();
            this.initialized = true;
        }
    }


    private void runDataScripts() {
        List<Resource> scripts = getScripts("spring.datasource.data",
                this.properties.getData(), "data");
        String username = this.properties.getDataUsername();
        String password = this.properties.getDataPassword();
        runScripts(scripts, username, password);
    }


    private List<Resource> getScripts(String propertyName, List<String> resources,
            String fallback) {
        if (resources != null) {
            //如果配置了暖璧,則從指定的資源文件中加載腳本
            return getResources(propertyName, resources, true);
        }
        //如果未配置,則使用classpath*:schema-all.sql或者classpath*:schema.sql作為腳本名君旦,其中platform默認(rèn)為all
        String platform = this.properties.getPlatform();
        List<String> fallbackResources = new ArrayList<String>();
        fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
        fallbackResources.add("classpath*:" + fallback + ".sql");
        return getResources(propertyName, fallbackResources, false);
    }


    private List<Resource> getResources(String propertyName, List<String> locations,
            boolean validate) {
        List<Resource> resources = new ArrayList<Resource>();
        for (String location : locations) {
            for (Resource resource : doGetResources(location)) {
                if (resource.exists()) {
                    resources.add(resource);
                }
                else if (validate) {
                    throw new ResourceNotFoundException(propertyName, resource);
                }
            }
        }
        return resources;
    }


    private Resource[] doGetResources(String location) {
        try {
            SortedResourcesFactoryBean factory = new SortedResourcesFactoryBean(
                    this.applicationContext, Collections.singletonList(location));
            factory.afterPropertiesSet();
            return factory.getObject();
        }
        catch (Exception ex) {
            throw new IllegalStateException("Unable to load resources from " + location,
                    ex);
        }
    }


    private void runScripts(List<Resource> resources, String username, String password) {
        if (resources.isEmpty()) {
            return;
        }
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.setContinueOnError(this.properties.isContinueOnError());
        populator.setSeparator(this.properties.getSeparator());
        if (this.properties.getSqlScriptEncoding() != null) {
            populator.setSqlScriptEncoding(this.properties.getSqlScriptEncoding().name());
        }
        for (Resource resource : resources) {
            populator.addScript(resource);
        }
        DataSource dataSource = this.dataSource;
        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
            dataSource = DataSourceBuilder.create(this.properties.getClassLoader())
                    .driverClassName(this.properties.determineDriverClassName())
                    .url(this.properties.determineUrl()).username(username)
                    .password(password).build();
        }
        DatabasePopulatorUtils.execute(populator, dataSource);
    }
}       List<Resource> scripts = getScripts("spring.datasource.schema",
                this.properties.getSchema(), "schema");
        if (!scripts.isEmpty()) {
            String username = this.properties.getSchemaUsername();
            String password = this.properties.getSchemaPassword();
            runScripts(scripts, username, password);
            try {
                this.applicationContext
                        .publishEvent(new DataSourceInitializedEvent(this.dataSource));
                // The listener might not be registered yet, so don't rely on it.
                if (!this.initialized) {
                    //執(zhí)行數(shù)據(jù)插入腳本
                    runDataScripts();
                    this.initialized = true;
                }
            }
            catch (IllegalStateException ex) {
                logger.warn("Could not send event to complete DataSource initialization ("
                        + ex.getMessage() + ")");
            }
        }
    }


    @Override
    public void onApplicationEvent(DataSourceInitializedEvent event) {
        if (!this.properties.isInitialize()) {
            logger.debug("Initialization disabled (not running data scripts)");
            return;
        }
        // NOTE the event can happen more than once and
        // the event datasource is not used here
        //如果初始化完成后澎办,執(zhí)行數(shù)據(jù)插入
        if (!this.initialized) {
            runDataScripts();
            this.initialized = true;
        }
    }


    private void runDataScripts() {
        List<Resource> scripts = getScripts("spring.datasource.data",
                this.properties.getData(), "data");
        String username = this.properties.getDataUsername();
        String password = this.properties.getDataPassword();
        runScripts(scripts, username, password);
    }


    private List<Resource> getScripts(String propertyName, List<String> resources,
            String fallback) {
        if (resources != null) {
            //如果配置了,則從指定的資源文件中加載腳本
            return getResources(propertyName, resources, true);
        }
        //如果未配置金砍,則使用classpath*:schema-all.sql或者classpath*:schema.sql作為腳本名局蚀,其中platform默認(rèn)為all
        String platform = this.properties.getPlatform();
        List<String> fallbackResources = new ArrayList<String>();
        fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
        fallbackResources.add("classpath*:" + fallback + ".sql");
        return getResources(propertyName, fallbackResources, false);
    }


    private List<Resource> getResources(String propertyName, List<String> locations,
            boolean validate) {
        List<Resource> resources = new ArrayList<Resource>();
        for (String location : locations) {
            for (Resource resource : doGetResources(location)) {
                if (resource.exists()) {
                    resources.add(resource);
                }
                else if (validate) {
                    throw new ResourceNotFoundException(propertyName, resource);
                }
            }
        }
        return resources;
    }


    private Resource[] doGetResources(String location) {
        try {
            SortedResourcesFactoryBean factory = new SortedResourcesFactoryBean(
                    this.applicationContext, Collections.singletonList(location));
            factory.afterPropertiesSet();
            return factory.getObject();
        }
        catch (Exception ex) {
            throw new IllegalStateException("Unable to load resources from " + location,
                    ex);
        }
    }


    private void runScripts(List<Resource> resources, String username, String password) {
        if (resources.isEmpty()) {
            return;
        }
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.setContinueOnError(this.properties.isContinueOnError());
        populator.setSeparator(this.properties.getSeparator());
        if (this.properties.getSqlScriptEncoding() != null) {
            populator.setSqlScriptEncoding(this.properties.getSqlScriptEncoding().name());
        }
        for (Resource resource : resources) {
            populator.addScript(resource);
        }
        DataSource dataSource = this.dataSource;
        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
            dataSource = DataSourceBuilder.create(this.properties.getClassLoader())
                    .driverClassName(this.properties.determineDriverClassName())
                    .url(this.properties.determineUrl()).username(username)
                    .password(password).build();
        }
        DatabasePopulatorUtils.execute(populator, dataSource);
    }
}

DataSourceConfiguration

? 底層默認(rèn)使用tomcat-jdbc連接池,所以在默認(rèn)情況下會(huì)創(chuàng)建一個(gè)基于Tomcat連接池的DataSource捞魁,并注入到Spring IOC容器中至会。

abstract class DataSourceConfiguration {
    @SuppressWarnings("unchecked")
    protected <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
        return (T) properties.initializeDataSourceBuilder().type(type).build();
    }
    /**
     * Tomcat Pool DataSource configuration.
     */
    @ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true)
    static class Tomcat extends DataSourceConfiguration {
        //創(chuàng)建一個(gè)基于Tomcat連接池的DataSource的Bean
        //由于底層使用Tomcat連接池离咐,在不引入外部數(shù)據(jù)連接池的jar包之前谱俭,默認(rèn)使用Tomcat的DataSource
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.tomcat")
        public org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties properties) {
            org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(properties, org.apache.tomcat.jdbc.pool.DataSource.class);
            DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());
            String validationQuery = databaseDriver.getValidationQuery();
            if (validationQuery != null) {
                dataSource.setTestOnBorrow(true);
                dataSource.setValidationQuery(validationQuery);
            }
            return dataSource;
        }
    }
    /**
     * Hikari DataSource configuration.
     */
    @ConditionalOnClass(HikariDataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
    static class Hikari extends DataSourceConfiguration {
        //創(chuàng)建基于hikari的DataSource的Bean
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.hikari")
        public HikariDataSource dataSource(DataSourceProperties properties) {
            return createDataSource(properties, HikariDataSource.class);
        }
    }
    /**
     * DBCP DataSource configuration.
     *
     * @deprecated as of 1.5 in favor of DBCP2
     */
    @ConditionalOnClass(org.apache.commons.dbcp.BasicDataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp.BasicDataSource", matchIfMissing = true)
    @Deprecated
    static class Dbcp extends DataSourceConfiguration {
        //創(chuàng)建基于dbcp的DataSource的Bean
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.dbcp")
        public org.apache.commons.dbcp.BasicDataSource dataSource(DataSourceProperties properties) {
            org.apache.commons.dbcp.BasicDataSource dataSource = createDataSource(properties, org.apache.commons.dbcp.BasicDataSource.class);
            DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());
            String validationQuery = databaseDriver.getValidationQuery();
            if (validationQuery != null) {
                dataSource.setTestOnBorrow(true);
                dataSource.setValidationQuery(validationQuery);
            }
            return dataSource;
        }
    }
    /**
     * DBCP DataSource configuration.
     */
    @ConditionalOnClass(org.apache.commons.dbcp2.BasicDataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp2.BasicDataSource", matchIfMissing = true)
    static class Dbcp2 extends DataSourceConfiguration {
        //創(chuàng)建基于dbcp2的DataSource的Bean
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource.dbcp2")
        public org.apache.commons.dbcp2.BasicDataSource dataSource(DataSourceProperties properties) {
            return createDataSource(properties,org.apache.commons.dbcp2.BasicDataSource.class);
        }
    }
    /**
     * Generic DataSource configuration.
     */
    @ConditionalOnMissingBean(DataSource.class)
    @ConditionalOnProperty(name = "spring.datasource.type")
    static class Generic {
        //可以在配置文件中通過(guò)spring.datasource.type指定外部的dataSource類型,并創(chuàng)建基于該type的DataSource的Bean
        @Bean
        public DataSource dataSource(DataSourceProperties properties) {
            return properties.initializeDataSourceBuilder().build();
        }
    }
}

SpringBoot默認(rèn)支持:

  • org.apache.tomcat.jdbc.pool.DataSource
  • com.zaxxer.hikari.HikariDataSource
  • org.apache.commons.dbcp.BasicDataSource
  • org.apache.commons.dbcp2.BasicDataSource

上面講到DataSourceInitializerApplicationListener類型的監(jiān)聽器

它的作用主要有:

? i)宵蛀、runSchemaScripts();運(yùn)行建表語(yǔ)句

? ii)昆著、runDataScripts();運(yùn)行插入數(shù)據(jù)的sql語(yǔ)句

默認(rèn)只需要將文件命名為:

? schema-*.sql 用于建表操作

? data-*.sql 用于數(shù)據(jù)操作

? 默認(rèn)規(guī)則:schema.sql或者schema-all.sql

自定義規(guī)則:spring.datasource.schema=[classpath:department.sql]

最后使用JdbcTemplate操作數(shù)據(jù)庫(kù),就類似在Spring框架中使用JdbcTemplate一樣术陶,這里就不再累贅了凑懂。

附上代碼:

User實(shí)體類:

public class User implements Serializable {

    private Integer uid;
    private String uname;
    private int uage;

    //getter和setter
}

User控制器:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    @PostMapping("/")
    public String insertUser(User user){
        int count = userService.insertUser(user);
        if(count != 1){
            return "error";
        }else{
            return "success";
        }
    }

    @GetMapping("/{uid}")
    public User getUserById(@PathVariable Integer uid){
        User user = userService.getUserById(uid);

        return user;
    }

    @GetMapping("/")
    public List<User> getAllUsers(){
        return userService.getAllUsers();
    }

    @PutMapping("/{uid}")
    public String updateUserById(@PathVariable Integer uid, User user){
        return userService.updateUserById(uid, user) == 1 ? "success" : "error";
    }

    @DeleteMapping("/{uid}")
    public String deleteUserById(@PathVariable Integer uid){
        return userService.deleteUserById(uid) == 1 ? "success" : "error";
    }
}

User業(yè)務(wù)層接口:

public interface IUserService {

    int insertUser(User user);

    User getUserById(Integer id);

    List<User> getAllUsers();

    int updateUserById(Integer uid, User user);

    int deleteUserById(Integer uid);
}

User業(yè)務(wù)層接口實(shí)現(xiàn)類:

@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private IUserDao userDao;

    @Override
    public int insertUser(User user) {
        return userDao.insertUser(user);
    }

    @Override
    public User getUserById(Integer id) {
        return userDao.getUserById(id);
    }

    @Override
    public List<User> getAllUsers() {
        return userDao.getAllUsers();
    }

    @Override
    public int updateUserById(Integer uid, User user) {
        return userDao.updateUserById(uid, user);
    }

    @Override
    public int deleteUserById(Integer uid) {
        return userDao.deleteUserById(uid);
    }
}

User持久層接口:

public interface IUserDao {

    int insertUser(User user);

    User getUserById(Integer id);

    List<User> getAllUsers();

    int updateUserById(Integer uid, User user);

    int deleteUserById(Integer uid);
}

User持久層接口實(shí)現(xiàn)類:

@Repository
public class UserDaoImpl implements IUserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int insertUser(User user) {
        return jdbcTemplate.update("insert into user values(null, ?, ?)", user.getUname(), user.getUage());
    }

    @Override
    public User getUserById(Integer id) {
        Object[] params = {id};
        return jdbcTemplate.queryForObject("select * from user where uid=?", params, new UserRowMapper());
    }

    @Override
    public List<User> getAllUsers() {
        return jdbcTemplate.query("select * from user", new UserRowMapper());
    }

    @Override
    public int updateUserById(Integer uid, User user) {
        StringBuilder sb = new StringBuilder();
        List<Object> params = new ArrayList<>();
        boolean isUpdate = false;

        if (user != null) {
            sb.append("update user set ");

            if (user.getUname() != null && !"".equals(StringUtils.trimWhitespace(user.getUname()))) {
                isUpdate = true;
                sb.append(" uname = ?,");
                params.add(StringUtils.trimWhitespace(user.getUname()));
            }
            if (user.getUage() != 0) {
                isUpdate = true;
                sb.append(" uage = ?,");
                params.add(user.getUage());
            }
        }

        if (isUpdate) {
            sb.deleteCharAt(sb.length() - 1);

            sb.append(" where uid = ? ");
            params.add(user.getUid());
            return jdbcTemplate.update(sb.toString(), params.toArray());
        } else {
            return 0;
        }

    }

    @Override
    public int deleteUserById(Integer uid) {
        return jdbcTemplate.update("delete from user where uid = ?", uid);
    }
}

User數(shù)據(jù)映射類:

public class UserRowMapper implements RowMapper<User> {
    @Override
    public User mapRow(ResultSet resultSet, int i) throws SQLException {
        User user = new User();
        user.setUid(resultSet.getInt("uid"));
        user.setUname(resultSet.getString("uname"));
        user.setUage(resultSet.getInt("uage"));
        return user;
    }
}

本節(jié)使用Restful風(fēng)格進(jìn)行編寫,大概知道Restful格式即可梧宫,此處不多講述接谨。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市塘匣,隨后出現(xiàn)的幾起案子脓豪,更是在濱河造成了極大的恐慌,老刑警劉巖忌卤,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扫夜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)笤闯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門堕阔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人颗味,你說(shuō)我怎么就攤上這事超陆。” “怎么了脱衙?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵侥猬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我捐韩,道長(zhǎng)退唠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任荤胁,我火速辦了婚禮瞧预,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仅政。我一直安慰自己垢油,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布圆丹。 她就那樣靜靜地躺著滩愁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辫封。 梳的紋絲不亂的頭發(fā)上硝枉,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音倦微,去河邊找鬼妻味。 笑死,一個(gè)胖子當(dāng)著我的面吹牛欣福,可吹牛的內(nèi)容都是我干的责球。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拓劝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼雏逾!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起郑临,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤栖博,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后牧抵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笛匙,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侨把,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妹孙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秋柄。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蠢正,靈堂內(nèi)的尸體忽然破棺而出骇笔,到底是詐尸還是另有隱情,我是刑警寧澤嚣崭,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布笨触,位于F島的核電站,受9級(jí)特大地震影響雹舀,放射性物質(zhì)發(fā)生泄漏芦劣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一说榆、第九天 我趴在偏房一處隱蔽的房頂上張望虚吟。 院中可真熱鬧,春花似錦签财、人聲如沸串慰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邦鲫。三九已至,卻和暖如春神汹,著一層夾襖步出監(jiān)牢的瞬間庆捺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工慎冤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疼燥,地道東北人沧卢。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓蚁堤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親但狭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子披诗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容