这里写自定义目录标题
简单增删改查遇到问题(2022/1/4)
入职第一天写的增删改查遇到的问题。
代码controller层
//controller层
package com.ds.travel.biz.patrol.zx.controller;
import com.ds.travel.biz.patrol.zx.entity.AmContractBasic;
import com.ds.travel.biz.patrol.zx.service.AmContractBasicService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/test")
public class AmContractBasicController {
@Resource
private AmContractBasicService amContractBasicService;
// 全部查询
@RequestMapping("/selectAll")
public List<AmContractBasic> selectAll(){
return amContractBasicService.selectAll();
}
// id查询
@RequestMapping("/selectId")
public AmContractBasic selectAllById(@RequestParam("id") Integer id){
return amContractBasicService.selectAllById(id);
}
// 根据id物理删除
@RequestMapping("/delete")
public void delete(@RequestParam("id") Integer id){
amContractBasicService.delete(id);
}
// 根据id逻辑删除
@RequestMapping("isDelete")
public void isDelete(@RequestParam("id") Integer id){
amContractBasicService.IsDelete(id);
}
// 添加
@RequestMapping("/insert")
public void insert(){
AmContractBasic amContractBasic = new AmContractBasic();
// amContractBasic.setContract_code("张三李四");
amContractBasicService.insert(amContractBasic);
}
// 修改
@RequestMapping("/updateId")
public void update(@RequestParam("id") Integer id){
AmContractBasic amContractBasic = amContractBasicService.selectAllById(id);
amContractBasic.setRemark("王五王五");
amContractBasicService.update(amContractBasic);
}
}
service接口
package com.ds.travel.biz.patrol.zx.service;
import com.ds.travel.biz.patrol.zx.entity.AmContractBasic;
import java.util.List;
public interface AmContractBasicService {
List<AmContractBasic> selectAll();
AmContractBasic selectAllById(Integer id);
void delete(Integer id);
void insert(AmContractBasic amContractBasic);
void update(AmContractBasic amContractBasic);
void IsDelete(Integer id);
}
serviceImpl实现类
package com.ds.travel.biz.patrol.zx.service.Impl;
import com.ds.travel.biz.patrol.zx.dao.AmContractBasicMapper;
import com.ds.travel.biz.patrol.zx.entity.AmContractBasic;
import com.ds.travel.biz.patrol.zx.service.AmContractBasicService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class AmContractBasicServiceImpl implements AmContractBasicService {
@Resource
private AmContractBasicMapper amContractBasicMapper;
@Override
public List<AmContractBasic> selectAll() {
return amContractBasicMapper.selectAll();
}
@Override
public AmContractBasic selectAllById(Integer id) {
return amContractBasicMapper.selectAllById(id);
}
@Override
public void delete(Integer id) {
amContractBasicMapper.delete(id);
}
@Override
public void insert(AmContractBasic amContractBasic) {
amContractBasicMapper.insert(amContractBasic);
}
@Override
public void update(AmContractBasic amContractBasic) {
amContractBasicMapper.update(amContractBasic);
}
@Override
public void IsDelete(Integer id) {
amContractBasicMapper.IsDelete(id);
}
}
daoMapper映射接口
package com.ds.travel.biz.patrol.zx.dao;
import com.ds.travel.biz.patrol.zx.entity.AmContractBasic;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.stereotype.Repository;
import java.util.List;
//@MapperScan("com.ds.travel.biz.patrol.zx.dao")
@Repository
public interface AmContractBasicMapper{
List<AmContractBasic> selectAll();
AmContractBasic selectAllById(Integer id);
void delete(Integer id);
void insert(AmContractBasic amContractBasic);
void update(AmContractBasic amContractBasic);
void IsDelete(Integer id);
}
mapper.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ds.travel.biz.patrol.zx.dao.AmContractBasicMapper">
<!--List<AmContractBasic> selectAll();-->
<select id="selectAll" resultType="com.ds.travel.biz.patrol.zx.entity.AmContractBasic">
select * from am_contract_basic
</select>
<!--AmContractBasic selectAllById(Integer id);-->
<select id="selectAllById" parameterType="integer" resultType="com.ds.travel.biz.patrol.zx.entity.AmContractBasic">
select * from am_contract_basic where id = #{id}
</select>
<!--void delete(Integer id);-->
<delete id="delete" parameterType="integer">
delete from am_contract_basic where id = #{id}
</delete>
<!--void insert(AmContractBasic amContractBasic);-->
<insert id="insert" parameterType="com.ds.travel.biz.patrol.zx.entity.AmContractBasic" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `travel`.`am_contract_basic` (`id`, `company_id`, ...) VALUES (null, 1, '2', ...)
</insert>
<!--void update(AmContractBasic amContractBasic);-->
<update id="update" parameterType="com.ds.travel.biz.patrol.zx.entity.AmContractBasic">
update am_contract_basic
set company_id = #{companyId,jdbcType=BIGINT},
contract_type = #{contractType,jdbcType=VARCHAR},
.......
where id = #{id,jdbcType=BIGINT}
</update>
<!--void IsDelete(Integer id,Integer delete);-->
<update id="IsDelete" parameterType="integer">
update am_contract_basic set is_delete = 1 where id = #{id}
</update>
</mapper>
entity实体类
package com.ds.travel.biz.patrol.zx.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class AmContractBasic implements Serializable {
/**
* 自增主键
*/
private Long id;
/**
* 所属公司
*/
private Long companyId;
..........
}
## pom.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ds.travel</groupId>
<artifactId>ds-travel-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>ds-travel-biz-patrol</artifactId>
<version>${project.version}</version>
<dependencies>
<dependency>
<groupId>com.jt.sjzx</groupId>
<artifactId>jt-common-spring</artifactId>
</dependency>
<dependency>
<groupId>com.ds.travel</groupId>
<artifactId>ds-travel-biz-sys</artifactId>
</dependency>
</dependencies>
</project>
问题一
-
mapper文件找不到
-
[ 错误解决]
直接在AmContractBasicMapper文件中加入的@MapperScan("com.ds.travel.biz.patrol.zx.dao")
注解标记以为能添加进去,但实际上根本没用 -
[正确解决后]
在@EnableTransactionManagement
注解的启动类里面添加的@MapperScan("com.ds.travel.biz.patrol.zx.dao")
注解标记,这才将mapper接口加入组件管理
问题二
-
实体类未加入组件管理
-
[ 解决一]
实体类中添加TableName()注解和数据库对应的实体类名@TableName("am_contract_basic")
-
[解决二]
直接继承Serializable
public class AmContractBasic implements Serializable{ }
问题三
未将AmContractBasicMapper文件添加到组件管理
AmContractBasicMapper文件中加入
@Repository注解加入组件管理
问题四
获取insert和update的SQL语句
- 方式一
- 方式二
问题五
select查询Postman获取到的值为空
- 方式一
- 方式二
问题六
yml文件中SQL参数索引报错
- 解决
Mysql语句里面不能加注释,不然会报错
问题七
实际用从Navicat复制过来mysql的静态值不报错,但全部切换成#{}动态的获取值报错,将update的mysql语句参数修改为 id = #{id}…形式如下报错误
There is no getter for property named 'updateId' in 'class com.ds.travel.biz.patrol.zx.entity.AmContractBasic'
(类中没有名为“ updateid”的属性的 getter 方法)
- 错误原因
实体类中的成员变量与mysql语句的字段名不匹配 - 解决
重写了实体类中的
问题八
使用update实现数据的删除
- 解决
逻辑删除:update修改is_delete字段值 1是0否
问题九
传输JSON格式实体类给后台处理
public void trendsUpdate(@RequestBody AmContractBasic amContractBasic){
amContractBasicService.trendsUpdate(amContractBasic);
}
补充
- MySql的动态拼接
MyBatis动态SQL
是MyBatis框架中的特性之一,在一些组合查询页面需要根据用户输入的条件的不同,来生成不同的查询SQL语句,
在jdbc或者是其它类似框架中需要在代码中拼接SQL语句,导致容易出错,MyBatis动态SQL可以解决这种问题。
动态SQL标签与jstl标签相似,允许在xml中构建不同的SQL语句
常用:
value里面拼接字符串
<bind name="id" value="需要的值">
指定mybatis日志的具体实现
-
<!-- STDOUT_LOGGING在控制台输出 -->
<settings >
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
2.if标签
简单的条件判断逻辑,满足指定条件时,追加if标签内的语句块,不满足时,不追加
<select>
sql语句1
<if test = "条件表达式">
sql语句2
</if>
</select>
if标签最常见的使用在where字句部分,根据不同的情况追加不同的SQL语句
<select id="findEmpOne" parameterType="condition" resultMap="BaseResulMap">
select * from t_emp
<if test="name != null">
where e_name = #{name}
</if>
</select>
3.choose标签
相当于java的switch语句,基本上跟jstl中choose作用和用法是一致,通常与when和otherwise搭配使用
从上依次往下匹配,直到匹配到满足条件的结束,都不匹配就执行otherwise
格式:
<select>
SQL语句1
<choose>
<when test="条件表达式">
SQL语句2
<when>
<when test="条件表达式">
SQL语句3
<when>
.....
<otherwise>
SQL语句4
</otherwise>
</choose>
</select>
4.where标签
可以在<where>标签所在的位置输出一个where关键字,而且还可以将后面多余的and或者or关键字去除
格式:
<select>
select * from t_emp
<where>
<if test=" namme != null">
e_name = #{name}
</if>
<if test="salary != null">
and e_salary > #{salary}
</if>
<if test="deptno != null">
or e_deptno > #{deptno}
</if>
</where>
</select>
5.set标签
用在更新操作时,主要功能和where标签相似,主要是在<set>位置输出一个关键字,而且还可以去除内容结尾无关的逗号
格式:
<update>
update t_emp
<set>
<if test="name != null">
e_name = #{name},
</if>
<if test="salary != null">
e_salary = #{salary},
</if>
<if test="deptno != null">
e_deptno = #{deptno},
</if>
<set>
<if test="id != null">
where e_id = #{id}
</if>
</update>
6.trim标签
可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix
可以把包含内容首部的某些内容过滤(忽略) ,可以把包含内容尾部的某些内容过滤(忽略) ,对应属性prefixOverrides和suffixOverrides
<-- 等价于where标签 -->
<trim prefix="where" prefixOverrides("and|or")>
.....
<trim>
<-- 等价于set标签 -->
<trim prefix="set" suffixOverrides(",")>
.....
<trim>
7.foreach标签
实现循环逻辑,进行一个集合的迭代,主要用在构建in条件,
格式:
select * from t_emp where e_id in(1001,1002,1005);
<select>
select * from t_emp where e_id in
<foreach collection="集合" item="迭代变量" open="(" close=")" parator="," >
#{迭代变量}
</foreach>
</select>
foreach标签允许指定一个集合,声明集合项和索引变量,变量可以用在标签体内,它允许指定开始和关闭的字符串,在迭代项之间放置分隔符
insert into t_dept values(1,''),(2,''),(3,''),(4,'');
<insert>
insert into t_dept values
<foreach collection="集合或数组" item="dept" separator="," >
(#{dept.id},#{dept.name})
</foreach>
</insert>
注意:
方法形参前先用注解定义名称@Param("emps")
collection:(collection/list)或者(emps/pram1)
补充:
1.在xml文件中处理特殊符号
1).采用xml转义字符
< <
> &gr;
& &
' '
" "
空格
2).采用<![CDATA[]]>说明,将此内容不进行解析
<if test ="salary!=null">
//<![CSATA[and e_salary < #{salary}]]>
where e_salary <![CDATA[<]]> 30000
</if>
2.取值方式
#{}与${}
都是去取变量的值,但#{}是安全的,可以防止SQL注入,而且是预编译的
1.#{}
是预编译的,SQL语句中变量的值会替换成占位符
2.${}
不是预编译的,直接替换成变量的值,一般用于传入的参数是数据库对象时,如:表名,字段名
select * from t_emp were e_id = #{id};
select * from t_emp were e_id = ${id};
如果id参数值是1001,分别解析为
#{} -> select * from t_emp were e_id = ?;
${} -> select * from t_emp were e_id = 1001;
如果参数是String类型的"'id=1001'or'1=1'"这样的SQL注入
${} -> select * from t_emp were e_id = 'id=1001'or'1=1'
order by id -> 按照id字段排序
#{} -> order by 'id'
${} -> order by id