发表于: 2017-05-23 11:48:19
2 1844
今日目标:对参数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语句成了这样……
@Update("<script> " +
"update signup" +
"update_at = (UNIX_TIMESTAMP(now())*1000" +
"<set>" +
"<if test=\"name != null\">name=#{name},</if>"+
"<if test=\"qq != null\">price=#{qq},</if>" +
"<if test=\"major != null\">price=#{major},</if>" +
"<if test=\"start_date != null\">price=#{start_date},</if>" +
"<if test=\"school != null\">price=#{school},</if>" +
"<if test=\"onlineclass != null\">price=#{onlineclass},</if>" +
"<if test=\"onlineno != null\">price=#{onlineno},</if>" +
"<if test=\"diarylink != null\">price=#{diarylink},</if>" +
"<if test=\"aim != null\">price=#{aim},</if>" +
"<if test=\"recommender != null\">price=#{recommender},</if>" +
"<if test=\"censor != null\">price=#{censor},</if>" +
"<if test=\"wherefrom != null\">price=#{wherefrom},</if>" +
"</set>" +
"where id = #{id}" +
"</script>")
}
步骤2:
写好根据姓名查询的方法之后,启动Tomcat初始化失败,检查之后发现
@RequestMapping(value = "/student/{name}", method = RequestMethod.GET)
里面的value我给想当然的写成了"/student/#{name}"。
尝试查询的时候还是失败,发现是由于接口中的name是中文。
打印name的时候是乱码:
http://blog.csdn.net/whyistao/article/details/50678605
转换编码之后出现了更诡异的错误。。
Controller类中根据名字查询学生的方法:
@RequestMapping(value = "/student/{name}", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
@ResponseBody
public ModelAndView getStudentsByName(@PathVariable String name,@RequestParam(value = "pn", required = false, defaultValue = "1") Integer pn) throws IOException{
//一句话Mapper
//疑问:每个方法里都要写一个Mapper,看起来复用性比较低,后期是不是可以用Spring插进来。。
StudentMapper mapper = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
.openSession().getMapper(StudentMapper.class);
List<Student> list = new ArrayList<Student>();
//使用PathVariable注解将RequestMapping里#{name}传入方法体内,并且作为参数传入mapper,取回list
System.out.println(name);
list = mapper.listByName(name,(pn - 1) * 10, pn * 10);
//传回结果list
ModelAndView mav = new ModelAndView("student");
JSONArray json = new JSONArray();
json.put(list);
mav.addObject("msg", json);
return mav;
}
Mapper中根据名字查询的方法(完全照抄Major那一段)
// 根据专业分页查询
@Select("select * from signup where major= #{major} limit #{start},#{count}")
public List<Student> listByMajor(String major, @Param("start") int start, @Param("count") int count);
// 根据姓名查询
@Select("select * from signup where name= #{name} limit #{start},#{count}")
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方法:
@RequestMapping(value = "/students", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
@ResponseBody
public ModelAndView addStudent(@RequestBody Student student) throws IOException{
// 指定mapper
StudentMapper mapper = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
.openSession().getMapper(StudentMapper.class);
ModelAndView mav = new ModelAndView("students");
JSONObject jo = new JSONObject();
int flag = mapper.add(student);
if(flag>0){
jo.put("Success", "true");
jo.put("Added", flag);
}else{
jo.put("Success", "false");
jo.put("Added", flag);
}
mav.addObject("msg", jo);
return mav;
}
Mapper中添加数据的方法:
// 添加
@Insert("INSERT INTO signup VALUES "
+ "(UNIX_TIMESTAMP(now())*1000,UNIX_TIMESTAMP(now())*1000,null,#{name},#{qq},#{major},#{start_date},"
+ "#{school},#{onlineclass},#{onlineno},#{diarylink}," + "#{aim},#{recommender},#{censor},#{wherefrom})")
public int add(Student student);
完事用POSTMan测试的时候, 报415错误。。
在搜索的时候给的解决方案基本是:
开启注解;
添加Jackson包的依赖;
Mapper中加入produces = "application/json;charset=UTF-8";
全试了一遍并没有解决……
检查了半天,网上有说Spring3.1之后会自动加入转换器的bean,无需手动配置。
之前添加JSON包是直接复制的别人的代码,我自己去mvnrepository找一段试试?
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.8</version>
成功的装配出了对象并且拿到了属性。。
在Controller中注释掉操作数据库的语句,直接将对象的属性作为值加到返回的json里:
@RequestMapping(value = "/students", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
@ResponseBody
public ModelAndView addStudent(@RequestBody Student student) throws IOException{
// 指定mapper
StudentMapper mapper = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
.openSession().getMapper(StudentMapper.class);
ModelAndView mav = new ModelAndView("students");
JSONObject jo = new JSONObject();
jo.put("Student", student.getAim());
// int flag = mapper.add(student);
//
// if(flag>0){
// jo.put("Success", "true");
// jo.put("Added", flag);
// }else{
// jo.put("Success", "false");
// jo.put("Added", flag);
// }
mav.addObject("msg", jo);
return mav;
但是数据库里并没有发现最后一条记录……尝试手动插入记录,发现自增id跳过了一个。
接着查错……
这次的错误想必是出现在了Mapper里,那么对数据库做什么,会产生一个不显示但是占用了自增id的记录呢。。
联想到之前查询的时候没有返回值,是由于Spring里的参数没有传给Mybatis的Mapper,尝试修改Mapper中的方法:
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.属性,和之前一样,产生了一条看不见的记录。
// 添加
@Insert("INSERT INTO signup VALUES "
+ "(UNIX_TIMESTAMP(now())*1000,UNIX_TIMESTAMP(now())*1000,null,#{student.name},#{student.qq},#{student.major},#{student.start_date},"
+ "#{student.school},#{student.onlineclass},#{student.onlineno},#{student.diarylink}," + "#{student.aim},#{student.recommender},#{student.censor},#{student.wherefrom})")
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。。
C:\Program Files (x86)\MySQL\MySQL Server 5.5\bin\mysqld, Version: 5.5.15 (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: MySQL
Time Id Command Argument
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','渡劫升仙','忘语','忘语','起点中文网')
170524 0:05:20 152 Connect root@localhost on 学员报名
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'
153 Connect root@localhost on 学员报名
154 Connect root@localhost on 学员报名
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'
152 Query SHOW WARNINGS
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'
152 Query /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
153 Query SHOW WARNINGS
152 Query SHOW COLLATION
153 Query /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
153 Query SHOW COLLATION
154 Query SHOW WARNINGS
154 Query /* mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} ) */SELECT @@session.auto_increment_increment
154 Query SHOW COLLATION
152 Query SET NAMES utf8
152 Query SET character_set_results = NULL
152 Query SET autocommit=1
152 Query SELECT @@session.tx_isolation
153 Query SET NAMES utf8
153 Query SET character_set_results = NULL
153 Query SET autocommit=1
153 Query SELECT @@session.tx_isolation
152 Query SET autocommit=0
154 Query SET NAMES utf8
154 Query SET character_set_results = NULL
154 Query SET autocommit=1
154 Query SELECT @@session.tx_isolation
152 Query INSERT INTO `signup` VALUES (UNIX_TIMESTAMP(now())*1000,UNIX_TIMESTAMP(now())*1000,null,'韩立','12345566','JAVA工程师','20110101','凡人修仙传','123','456','www.baidu.com','渡劫升仙','忘语','忘语','起点中文网')
170524 0:05:35 145 Quit
尝试贴了一下日志……上面下面的SQL语句我在线比较了,完全相同,但是上面一句是手动运行,然后就成功了。。
而用get方法调用select语句完全没有问题……
啊啊啊啊啊啊啊啊啊啊啊(已疯)
2017年5月24日08:12:22更新:昨晚有人提点我是不是事务没有提交,今天尝试改写,成功。
SqlSession session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"))
.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
ModelAndView mav = new ModelAndView("students");
JSONObject jo = new JSONObject();
int flag = mapper.add(student);
session.commit();
评论