Spring JDBC 框架中, 绑定 SQL 参数的另一种选择:具名参数(named parameter)

使用spring的jdbcTemplate-----使用具名参数

在JDBC用法中,SQL参数是用占位符?表示,并且受到位置的限制,定位参数的问题在于,一旦参数的位置发生变化,必须改变参数的绑定,在Spring JDBC中,绑定SQL参数的另一种选择是使用具名参数,SQL具名参数是按照名称绑定,而不是位置绑定。

什么是具名参数?

具名参数: SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代

具名参数只在 NamedParameterJdbcTemplate 中得到支持。(SImpleJdbcTemplate已过时了)

NamedParameterJdbcTemplate内部包含了一个JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能干,NamedParameterJdbcTemplate相对于JdbcTemplate主要增加了参数可以命名的功能。

如何配置?

applicationContext.xml里的配置

<!-- 配置jdbc模板类 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置 NamedParameterJdbcTemplate,该对象可以使用具名参数。
    但它没有无参构造器,所以必须为其制定构造参数,这里指定的是出c3p0数据源
    -->
    <bean id="namedParameterJdbcTemplate"
        class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"></constructor-arg>
    </bean>

实例:

public class BaseService {

    // JdbcTemplate 对象作为构造器参数初始化
    @Autowired
    protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    /**
     * 数据查询
     *
     * @param sql
     * @param object
     * @return
     */
    @SuppressWarnings("rawtypes")
    public List<?> query(String sql, Object object) {

        // BeanPropertySqlParameterSource封装了一个JavaBean对象,通过JavaBean对象属性来决定命名参数的值
        SqlParameterSource source = new BeanPropertySqlParameterSource(object);

        @SuppressWarnings("unchecked")
        // BeanPropertyRowMapper自动将一行数据映射到指定类的实例中 它首先将这个类实例化,然后通过名称匹配的方式,映射到属性中去
        List<?> list = namedParameterJdbcTemplate.query(sql, source, new BeanPropertyRowMapper(object.getClass()));
        return list;
    }

    /**
     * 数据添加、删除、修改
     *
     * @param sql
     * @param object
     * @return
     */
    @SuppressWarnings("unchecked")
    public int excute(String sql, Object object) {
        if (object != null) {
            // 判断类型
            if (object instanceof Map) {
                return namedParameterJdbcTemplate.update(sql, (Map<String, ?>) object);
            } else {
                BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(object);
                // 返回对象
                return namedParameterJdbcTemplate.update(sql, source);
            }
        } else {
            return namedParameterJdbcTemplate.getJdbcOperations().update(sql);
        }
    }

    /**
     * 查询记录数
     *
     * @param sql
     * @param object
     * @return
     */
    public int queryCount(String sql, Object object) {
        BeanPropertySqlParameterSource source = null;
        if (object != null) {
            source = new BeanPropertySqlParameterSource(object);
        }
        return namedParameterJdbcTemplate.queryForObject(sql, source, Integer.class);
    }}

NamedParameterJdbcTemplate类是基于JdbcTemplate类,并对它进行了封装从而支持命名参数特性。

NamedParameterJdbcTemplate主要提供以下三类方法:execute方法、query及queryForXXX方法、update及batchUpdate方法。

1)NamedParameterJdbcTemplate初始化:可以使用DataSource或JdbcTemplate 对象作为构造器参数初始化;

2)insert into test(name) values(:name):其中“:name”就是命名参数;

3) update(insertSql, paramMap):其中paramMap是一个Map类型,包含键为“name”,值为“name5”的键值对,也就是为命名参数设值的数据;

4)query(selectSql, paramMap, new RowCallbackHandler()……):类似于JdbcTemplate中介绍的,唯一不同是需要传入paramMap来为命名参数设值;

5)update(deleteSql, paramSource):类似于“update(insertSql, paramMap)”,但使用SqlParameterSource参数来为命名参数设值,此处使用MapSqlParameterSource实现,其就是简单封装java.util.Map。

NamedParameterJdbcTemplate类为命名参数设值有两种方式:java.util.Map和SqlParameterSource:

1)java.util.Map:使用Map键数据来对于命名参数,而Map值数据用于设值;

2)SqlParameterSource:可以使用SqlParameterSource实现作为来实现为命名参数设值,默认有MapSqlParameterSource和BeanPropertySqlParameterSource实现;MapSqlParameterSource实现非常简单,只是封装了java.util.Map;而BeanPropertySqlParameterSource封装了一个

JavaBean对象,通过JavaBean对象属性来决定命名参数的值。

/**
 * 用户 服务类接口实现
 */
@Service
public class IUserServiceImpl extends BaseService implements IUserService {

    public final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(IUserServiceImpl.class);

    /**
     * 查询用户
     */
    @Override
    public Object queryUser(String sql, Object object) {
        User user = new User();
        sql = "select suser as username,spassword as password,tcreatetime as createtime,cisenabled as enabled,cauthorize as authorize from sys_user";     
        // String sqls = "select suser as username,spassword as password,tcreatetime as createtime,cisenabled as enabled,cauthorize as authorize from sys_user where suser like ‘%:username%‘";
        // 替换掉sql语句的条件
        // sqls = sqls.replace(":username", user.getUsername());
        @SuppressWarnings("unchecked")
        List<User> list = (List<User>) query(sql, user);

        return list;
    }

    /**
     * 添加用户
     */
    @Override
    public MsgBean addUser(User user) {
        MsgBean msg = new MsgBean();
        try {
            String sql = " insert into sys_user (suser,spassword,tcreatetime,cisenabled,cauthorize) values(:username,:password,:createtime,:enabled,:authorize)";
            // 添加新用户是自动取得时间
            // user.setCreatetime(DateUtil.getCurDate(null));
            excute(sql, user);
            msg.setFlag(true);
            msg.setText("ok");
        } catch (Exception e) {
            logger.error("出错的原因。。。" + e.getMessage());
        }
        return msg;
    }

    /**
     * 修改用户
     */
    @Override
    public MsgBean updateUser(User user) {
        MsgBean msg = new MsgBean();
        try {
            String sql = " update sys_user set spassword=:password,tcreatetime=:createtime,cisenabled=:enabled,cauthorize=:authorize where suser=:username";
            excute(sql, user);
            msg.setFlag(true);
            msg.setText("ok");
        } catch (Exception e) {
            logger.error("出错的原因。。。" + e.getMessage());
        }
        return msg;
    }

    /**
     * 删除用户
     */
    @Override
    public MsgBean deleteUser(String username) {
        MsgBean msg = new MsgBean();
        try {
            String sql = "delete from sys_user where suser =‘:username‘";
            if (username != null && username.length() != 0) {
                sql = sql.replace(":username", username);
            }else {
                msg.setFlag(false);
                 msg.setText("未知原因,删除失败");
                 return msg;
            }
            excute(sql, null);
            msg.setFlag(true);
            msg.setText("ok");
        } catch (Exception e) {
            logger.error("出错的原因。。。" + e.getMessage());
        }
        return msg;
    }
}

User是用户实体类,MsgBean工具实体类里面有flag和text两个参数,又来输出信息的

/**
 * 用户控制层
 */
@Controller
public class UserController {
    private static final Log logger = LogFactory.getLog(UserController.class);

    @Autowired
    private IUserService userService;

    /**
     * 用户查询
     *
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping("/queryuser")
    public Object queryUserList(HttpServletRequest request, HttpServletResponse response) {

        User user = new User();
        // 模糊查询传来的值
        // String username = request.getParameter("username");
        // // 判断字符串是否为空
        // if (StringUtil.isBlank(username)) {
        // // 若为空替换为空字符串
        // username = "";
        // }
        // user.setUsername(username);

        Object obj = userService.queryUser(null, user);
        return obj;
    }

    /**
     * 用户添加
     *
     * @param user
     * @return
     */
    @ResponseBody
    @RequestMapping("/adduser")
    public MsgBean addUser(User user) {
        MsgBean msg = null;
        try {
            msg = userService.addUser(user);
        } catch (Exception e) {
            logger.error("出错的原因 :" + e.getMessage());
        }
        return msg;

    }

    /**
     * 用户修改
     *
     * @param user
     * @return
     */
    @ResponseBody
    @RequestMapping("/updateuser")
    public MsgBean updateUser(User user) {
        MsgBean msg = null;
        try {
            msg = userService.updateUser(user);
        } catch (Exception e) {
            logger.error("出错的原因 :" + e.getMessage());
        }
        return msg;
    }

    /**
     * 用户删除
     *
     * @param username
     * @return
     */
    @ResponseBody
    @RequestMapping("/deleteuser")
    public MsgBean deleteUser(@RequestParam("username") String username) {
        MsgBean msg = null;
        try {
            msg = userService.deleteUser(username);
        } catch (Exception e) {
            logger.error("出错的原因 :" + e.getMessage());
        }
        return msg;
    }
}

上述代码写好后,可以运行,因为没有前端jsp文件,所以可以直接在访问的网址后面加上?然后打上参数

时间: 2024-12-25 21:34:20

Spring JDBC 框架中, 绑定 SQL 参数的另一种选择:具名参数(named parameter)的相关文章

spring jdbc框架

spring+jdbc 1.jdbc编程的特点: 模板编程 固定代码+动态的参数 spring产生dataSource JdbcTemplate{//模板编程 private DataSource dataSource; public void setDataSource(DataSource dataSource){ this.dataSource = dataSource; } public void update(String sql){ //产生链接 //产生Statement //执行

2014-07-30 MVC框架中对SQL Server数据库的访问

今天是在吾索实习的第16天.我自己主要学习了基于MVC框架的系统的开发时,对SQL Server数据库的相关访问.其步骤如下: 第一步,在Models文件夹中创建一个类,并命名为Movies.cs,如图1所示: 图1 第二步,在上述Movies.cs文件中的namespace MvcTest.Models{}中输入如下代码: 1 public class Movie 2 { 3 public int ID { get; set; } 4 public string Title { get; se

spring mvc框架中引入handlebars插件

本篇介绍引入spring mvc框架中引入handlebars.js插件最基本步骤 1.下载handlebars.js插件,并添加到项目中 2.下载handlebars依赖的jar包,添加到工程 红框中的是handlebars核心包,其他是handlebars依赖的工具包 3.在spring mvc配置文件springMvc-servlet.xml中添加handlebars视图解析器配置 1 <!-- VIEW RESOLVER --> 2 <bean id="handleba

Spring+MyBatis框架中sql语句的书写,数据集的传递以及多表关联查询

在很多Java EE项目中,Spring+MyBatis框架经常被用到,项目搭建在这里不再赘述,现在要将的是如何在项目中书写,增删改查的语句,如何操作数据库,以及后台如何获取数据,如何进行关联查询,以及MyBatis的分页问题. 首先先看看项目的架构,方便后边叙述. 这个项目中是一个Sping+MyBatis的完整demo(这边将页面没有展示.)这次的主题主要是后台数据处理逻辑.接下来为大家逐一介绍各个文件, org.config   Spring配置包括数据库的链接信息 org.control

CI框架中的SQL注入隐患

 0x00 在CI框架中,获取get和post参数是使用了$this->input类中的get和post方法. 其中,如果get和post方法的第二个参数为true,则对输入的参数进行XSS过滤,注意只是XSS过滤,并不会对SQL注入进行有效的防范. 例子: Controller中,定义一个shit方法,获取get数据: 指定了第二个参数为true: (1)XSS测试 (2)SQL注入测试 并不会对单引号进行处理. 例子在程式舞曲CMS中,该CMS是基于CI框架进行开发的CMS: 这里的变量

详述 Spring MVC 框架中拦截器 Interceptor 的使用方法

1 前言 昨天新接了一个需要,"拦截 XXX,然后 OOO",好吧,说白了就是要用拦截器干点事(实现一个具体的功能).之前,也在网络上搜了很多关于Interceptor的文章,但感觉内容都大同小异,而且知识点零零散散,不太方便阅读.因此,正好借此机会,整理一篇关于拦截器的文章,在此分享给大家,以供大家参考阅读. 2 拦截器 2.1 概念 Java 里的拦截器是动态拦截 action 调用的对象.它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也可以在一个

Java泛型在spring jdbc template中的类似应用

泛型的使用保证返回的对象类型的正确: package com.stono.gentest; import java.util.ArrayList; import java.util.List; public class StoryTeller { public static void main(String[] args) { List<Minstrel> story = StoryTemplate.getStory("select", new StoryI<Mins

Yii框架中的SQL用法

Yii框架的SQL User::find()->all(); //返回所有用户数据: User::findOne($id); //返回 主键 id=1 的一条数据: User::find()->where(['name' => 'ttt'])->one(); //返回 ['name' => 'ttt'] 的一条数据: User::find()->where(['name' => 'ttt'])->all(); //返回 ['name' => 'ttt'

Asp.Net MVC EF之一:使用Database类在EF框架中执行Sql语句

h4 { padding: 8px 5px; background-color: #32c5d2 } .start-box,.body { padding: 10px } .tit { font-size: 14px; font-weight: bold } div.content { line-height: 150%; font-weight: bold } .content { border: dashed 1px #999999; padding: 10px; background: #