发表于: 2017-05-23 11:48:19

2 1845


今日目标:对参数major的响应,以及student/name/的实现。

步骤1:

考虑到学员同名的情况,对Mapper进行了修改,现在根据姓名查询的返回结果是list。


在尝试更新值的时候遇到了问题:只想更新某个字段的时候,其他字段的值应该是null,但是设计表的时候值写了非空(就算可以是空也不能更新为空啊)。。

然后接触到动态SQL这个神器。。但是在编写DynaSqlProvider类的时候,导入包import org.apache.ibatis.jdbc.SQL却报错……


然后查阅到http://www.cnblogs.com/hitandrew/p/5802208.html,似乎可以直接在Mapper类里用script标签加入动态SQL?

于是Update的sql语句成了这样……

  1. @Update("<script> " +
  2.                "update signup" +
  3.                "update_at = (UNIX_TIMESTAMP(now())*1000" +
  4.                    "<set>" +
  5.                        "<if test=\"name != null\">name=#{name},</if>"+
  6.                        "<if test=\"qq != null\">price=#{qq},</if>" +
  7.                        "<if test=\"major != null\">price=#{major},</if>" +
  8.                        "<if test=\"start_date != null\">price=#{start_date},</if>" +
  9.                        "<if test=\"school != null\">price=#{school},</if>" +
  10.                        "<if test=\"onlineclass != null\">price=#{onlineclass},</if>" +
  11.                        "<if test=\"onlineno != null\">price=#{onlineno},</if>" +
  12.                        "<if test=\"diarylink != null\">price=#{diarylink},</if>" +
  13.                        "<if test=\"aim != null\">price=#{aim},</if>" +
  14.                        "<if test=\"recommender != null\">price=#{recommender},</if>" +
  15.                        "<if test=\"censor != null\">price=#{censor},</if>" +
  16.                        "<if test=\"wherefrom != null\">price=#{wherefrom},</if>" +
  17.                    "</set>" +
  18.                "where id = #{id}" +
  19.            "</script>")
  20. }




步骤2:

写好根据姓名查询的方法之后,启动Tomcat初始化失败,检查之后发现

  1. @RequestMapping(value = "/student/{name}", method = RequestMethod.GET)

里面的value我给想当然的写成了"/student/#{name}"。


尝试查询的时候还是失败,发现是由于接口中的name是中文。

打印name的时候是乱码:

http://blog.csdn.net/whyistao/article/details/50678605


转换编码之后出现了更诡异的错误。。

Controller类中根据名字查询学生的方法:

  1. @RequestMapping(value = "/student/{name}", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
  2.    @ResponseBody
  3.    public ModelAndView getStudentsByName(@PathVariable String name,@RequestParam(value = "pn", required = false, defaultValue = "1") Integer pn) throws IOException{
  4.        //一句话Mapper
  5.        //疑问:每个方法里都要写一个Mapper,看起来复用性比较低,后期是不是可以用Spring插进来。。
  6.        StudentMapper mapper = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
  7.                .openSession().getMapper(StudentMapper.class);
  8.        List<Student> list = new ArrayList<Student>();
  9.        //使用PathVariable注解将RequestMapping里#{name}传入方法体内,并且作为参数传入mapper,取回list
  10.        System.out.println(name);
  11.        list = mapper.listByName(name,(pn - 1) * 10, pn * 10);
  12.        //传回结果list
  13.        ModelAndView mav = new ModelAndView("student");
  14.        JSONArray json = new JSONArray();
  15.        json.put(list);
  16.        mav.addObject("msg", json);
  17.        return mav;
  18.    }


Mapper中根据名字查询的方法(完全照抄Major那一段)


  1.    // 根据专业分页查询
  2.    @Select("select * from signup where major= #{major} limit #{start},#{count}")
  3.    public List<Student> listByMajor(String major, @Param("start") int start, @Param("count") int count);
  4.    // 根据姓名查询
  5.    @Select("select * from signup where name= #{name} limit #{start},#{count}")
  6.    public List<Student> listByName(String name, @Param("start") int start, @Param("count") int count);

然后报错:

### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'name' not found. Available parameters are [0, start, count, param3, param1, param2]

(之前根据Major查询的接口没有测试,测试发现也报了相同的错。)

查阅资料:

http://blog.csdn.net/w86440044/article/details/29363067

似乎只能用序号?

根据分页查询传入的参数,试用@Param注解进行注明。

下午的计划:实现使用put/patch方法更新学生信息,以及使用post方法添加学生。

试了一下postman发现,之前Get方法里,students.jsp我画蛇添足的加了ContentType为HTML,导致无法正常解析……


写post的时候遇到个解决不了的问题……

Controller方法:

  1. @RequestMapping(value = "/students", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
  2.    @ResponseBody
  3.    public ModelAndView addStudent(@RequestBody Student student) throws IOException{
  4.        // 指定mapper
  5.                StudentMapper mapper = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
  6.                        .openSession().getMapper(StudentMapper.class);
  7.                ModelAndView mav = new ModelAndView("students");
  8.                JSONObject jo = new JSONObject();
  9.                int flag = mapper.add(student);
  10.                if(flag>0){
  11.                    jo.put("Success", "true");
  12.                    jo.put("Added", flag);
  13.                }else{
  14.                    jo.put("Success", "false");
  15.                    jo.put("Added", flag);
  16.                }
  17.                mav.addObject("msg", jo);
  18.                return mav;
  19.    }

Mapper中添加数据的方法:

  1. // 添加
  2.    @Insert("INSERT INTO signup VALUES "
  3.            + "(UNIX_TIMESTAMP(now())*1000,UNIX_TIMESTAMP(now())*1000,null,#{name},#{qq},#{major},#{start_date},"
  4.            + "#{school},#{onlineclass},#{onlineno},#{diarylink}," + "#{aim},#{recommender},#{censor},#{wherefrom})")
  5.    public int add(Student student);

完事用POSTMan测试的时候, 报415错误。。

在搜索的时候给的解决方案基本是:

开启注解;

添加Jackson包的依赖;

Mapper中加入produces = "application/json;charset=UTF-8";

全试了一遍并没有解决……



检查了半天,网上有说Spring3.1之后会自动加入转换器的bean,无需手动配置。

之前添加JSON包是直接复制的别人的代码,我自己去mvnrepository找一段试试?

  1. <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
  2.        <dependency>
  3.            <groupId>com.fasterxml.jackson.core</groupId>
  4.            <artifactId>jackson-databind</artifactId>
  5.            <version>2.8.8</version>
  6.        </dependency>
  7.        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
  8.        <dependency>
  9.            <groupId>com.fasterxml.jackson.core</groupId>
  10.            <artifactId>jackson-core</artifactId>
  11.            <version>2.8.8</version>
  12.        </dependency>
  13.        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
  14.        <dependency>
  15.            <groupId>com.fasterxml.jackson.core</groupId>
  16.            <artifactId>jackson-annotations</artifactId>
  17.            <version>2.8.8</version>


成功的装配出了对象并且拿到了属性。。

在Controller中注释掉操作数据库的语句,直接将对象的属性作为值加到返回的json里:

  1.    @RequestMapping(value = "/students", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
  2.    @ResponseBody
  3.    public ModelAndView addStudent(@RequestBody Student student) throws IOException{
  4.        // 指定mapper
  5.                StudentMapper mapper = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
  6.                        .openSession().getMapper(StudentMapper.class);
  7.                ModelAndView mav = new ModelAndView("students");
  8.                JSONObject jo = new JSONObject();
  9.                jo.put("Student", student.getAim());
  10. //                int flag = mapper.add(student);
  11. //                
  12. //                if(flag>0){
  13. //                    jo.put("Success", "true");
  14. //                    jo.put("Added", flag);
  15. //                }else{
  16. //                    jo.put("Success", "false");
  17. //                    jo.put("Added", flag);
  18. //                }
  19.                mav.addObject("msg", jo);
  20.                return mav;

但是数据库里并没有发现最后一条记录……尝试手动插入记录,发现自增id跳过了一个。

接着查错……


这次的错误想必是出现在了Mapper里,那么对数据库做什么,会产生一个不显示但是占用了自增id的记录呢。。


联想到之前查询的时候没有返回值,是由于Spring里的参数没有传给Mybatis的Mapper,尝试修改Mapper中的方法:

  1. public int add(@Param("student") Student student);

报错

### Error updating database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'name' not found. Available parameters are [student, param1]

好像不能自动使用对象的值……?

把sql语句中的值改为student.属性,和之前一样,产生了一条看不见的记录。


  1.    // 添加
  2.    @Insert("INSERT INTO signup VALUES "
  3.            + "(UNIX_TIMESTAMP(now())*1000,UNIX_TIMESTAMP(now())*1000,null,#{student.name},#{student.qq},#{student.major},#{student.start_date},"
  4.            + "#{student.school},#{student.onlineclass},#{student.onlineno},#{student.diarylink}," + "#{student.aim},#{student.recommender},#{student.censor},#{student.wherefrom})")
  5.    public int add(@Param("student") Student student);

尝试修改一条student.name为student.getName(),报错:

### Error updating database.  Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'getName()' in 'class com.qhs.rest.bean.Student'


这意思是不用画蛇添足,用变量名就会自动调用bean的getter方法?

可是为什么会产生这种看不到的,却占用了自增id的记录呢……


后续:为了这个错误,去学习了查看MySQL的日志。。

这玩意的确出现在了日志里……


手动复制SQL语句执行,报错:No database selected


仔细一看 INSERT INTO signup VALUES

我没在表名前后加`符号…………

好的 改完之后404,手动小黄脸再见


重启Eclipse又能正常访问了,然后又变成添加失败,占用自增id。。


  1. C:\Program Files (x86)\MySQL\MySQL Server 5.5\bin\mysqld, Version: 5.5.15 (MySQL Community Server (GPL)). started with:
  2. TCP Port: 3306, Named Pipe: MySQL
  3. Time                 Id Command    Argument
  4. 170524  0:05:07      145 Query    INSERT INTO `signup` VALUES (UNIX_TIMESTAMP(now())*1000,UNIX_TIMESTAMP(now())*1000,null,'韩立','12345566','JAVA工程师','20110101','凡人修仙传','123','456','www.baidu.com','渡劫升仙','忘语','忘语','起点中文网')
  5. 170524  0:05:20      152 Connect    root@localhost on 学员报名
  6.          152 Query    /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect'
  7.          153 Connect    root@localhost on 学员报名
  8.          154 Connect    root@localhost on 学员报名
  9.          153 Query    /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect'
  10.          152 Query    SHOW WARNINGS
  11.          154 Query    /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect'
  12.          152 Query    /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
  13.          153 Query    SHOW WARNINGS
  14.          152 Query    SHOW COLLATION
  15.          153 Query    /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
  16.          153 Query    SHOW COLLATION
  17.          154 Query    SHOW WARNINGS
  18.          154 Query    /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
  19.          154 Query    SHOW COLLATION
  20.          152 Query    SET NAMES utf8
  21.          152 Query    SET character_set_results = NULL
  22.          152 Query    SET autocommit=1
  23.          152 Query    SELECT @@session.tx_isolation
  24.          153 Query    SET NAMES utf8
  25.          153 Query    SET character_set_results = NULL
  26.          153 Query    SET autocommit=1
  27.          153 Query    SELECT @@session.tx_isolation
  28.          152 Query    SET autocommit=0
  29.          154 Query    SET NAMES utf8
  30.          154 Query    SET character_set_results = NULL
  31.          154 Query    SET autocommit=1
  32.          154 Query    SELECT @@session.tx_isolation
  33.          152 Query    INSERT INTO `signup` VALUES (UNIX_TIMESTAMP(now())*1000,UNIX_TIMESTAMP(now())*1000,null,'韩立','12345566','JAVA工程师','20110101','凡人修仙传','123','456','www.baidu.com','渡劫升仙','忘语','忘语','起点中文网')
  34. 170524  0:05:35      145 Quit

尝试贴了一下日志……上面下面的SQL语句我在线比较了,完全相同,但是上面一句是手动运行,然后就成功了。。


而用get方法调用select语句完全没有问题……


啊啊啊啊啊啊啊啊啊啊啊(已疯)


2017年5月24日08:12:22更新:昨晚有人提点我是不是事务没有提交,今天尝试改写,成功。

  1. SqlSession session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
  2.                        .openSession();
  3.                StudentMapper mapper = session.getMapper(StudentMapper.class);
  4.                ModelAndView mav = new ModelAndView("students");
  5.                JSONObject jo = new JSONObject();
  6.                int flag = mapper.add(student);
  7.                session.commit();




返回列表 返回列表
评论

    分享到