mybatis实现对数据库的增删改查
实体类与数据库字段名称不匹配
数据库表的字段名称和实体类的属性名称不一致,则会导致不能自动封装数据,有以下两种解决方法:
1.起别名
在连接表的xml配置文件中,直接修改查询语句,在字段列表后面使用as别名的方式使pojo类的数据表文件和数据库内的名称一致即可解决,但是这样做会有一个缺点,不够灵活,可以使用sql片段的方式解决:
<mapper namespace="com.xiaohe.Mapper.BrandMapper">
<!--定义sql片段,名为brand_column-->
<sql id="brand_column">
id,brand_name as brandName,company_name as companyName,ordered,description,status
</sql>
<!--将*替换为sql片段的id-->
<select id="selectall" resultType="brand">
select
<include refid="brand_column"/>
from tb_brand;
</select>
</mapper>
2.使用resultmap
<resultMap id="brandResultMap" type="brand">
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<select id="selectall" resultMap ="brandResultMap">
select * from tb_brand;
</select>
此方法分为两步实现:
- 定义此映射的id与返回值类型,
- 使用result,或者id关键字使数据库中的列名与ide中的变量名关联起来,column代表列,property代表实体类的属性名,有几个列名属性名不一致就写几个
- 最后把select方法中的返回值类型修改为resultMap的id名
注意:如果是书写查询单条数据的方法,需要使用#{}占位符,java在编译的过程中这个符号相当于?,可以防止sql注入问题,同理${}会存在sql注入问题,有些特殊符号无法在xml中使用,如: <,这是因为<在xml语言中代表标签,这个时候需要用到CDATA区,将<写在CDATA区里即可
<!--演示占位符-->
<select id="selectById" resultMap ="brandResultMap">
select * from tb_brand where id = #{id};
</select>
<!--演示CDATA区-->
<select id="selectById" resultMap ="brandResultMap">
select * from tb_brand where id
<![CDATA[
<
]]>
#{id};
</select>
多模糊条件协同查询
和其他查询语句不同,模糊查询与条件查询在sql语言里有特殊的字符,如:%,查询多个字符,_,查询单个字符,所以需要事先处理好参数:
int id = 1;
String companyName = "小米";
String brandName = "小米";
companyName = "%"+companyName+"%";
brandName = "%"+brandName+"%";
随后通过在配置信息里定义好的sql语句进行查询:
<select id="SelectByCondition" resultMap ="brandResultMap">
select * from tb_brand
where status = #{status} and company_name like #{companyName} and brand_name like #{brandName}
</select>
需要注意的是,在模糊查询且有多个参数值需要连接时,可以使用mybatis提供的注解@Param,它可以帮助我们找到要连接的数据,使用方法如:
List<Brand>SelectByCondition(@Param("status") int status, @Param("companyName") String companyname,@Param("brandName") String brandName);
@Param(),()里面的值对应的是配置文件中的SQL占位符名称,以此标注参数对应的是哪个占位符
动态sql
在实际的业务中,用户可能不会直接填写三个条件进行判断,那么我们的程序就会出现问题,这个时候可以用动态sql的方式进行解决:
解决方式:在where条件后面加上一个if语句进行判断:
<select id="SelectByCondition" resultMap ="brandResultMap">
select * from tb_brand
where
<if test="status !=null">
status like #{status}
</if>
<if test="companyName !=null and companyName !='' ">
and company_name like #{companyName}
</if>
<if test="brandName !=null and brandName != '' ">
and brand_name like #{brandName};
</if>
</select>
但是这种方式有一个弊端,就是如果第一个条件用户不填写,那sql语句就不会成立,表达式会出现语法错误从而出现bug,解决方法1,在所有句式前面加上一个恒等式,如1=1,然后在所有条件开头前加上一个and,从而使任何情况,此句式都符合sql语句的语法避免Bug,解决方式2,使用
<select id="SelectByCondition" resultMap ="brandResultMap">
select * from tb_brand
<where>
<if test="status !=null">
status like #{status}
</if>
<if test="companyName !=null and companyName !='' ">
and company_name like #{companyName}
</if>
<if test="brandName !=null and brandName != '' ">
and brand_name like #{brandName};
</if>
</where>
单选择条件模糊查询
除此之外,有的业务要求可能会需要用到单选择,很明显以上方法不能解决实际问题,mybtis提供了一些标签可以帮助我们实现单选择业务
<select id="selectonebycondition" resultMap="brandResultMap">
select * from tb_brand
where
<choose>
<when test="status !=null">
status = #{status}
</when>
<when test="companyName !=null and companyName !='' ">
company_name like #{companyName}
</when>
<when test="brandName !=null and brandName != '' ">
brand_name like #{brandName}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</select>
mybatis添加数据
- 在对应的接口类里面定义方法
- 在接口对应的xml文件中编写对应的方法体
- 测试方法
<!--定义方法体-->
<insert id="addAll">
insert into tb_brand(brand_name,company_name,ordered,description,status)values(#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
public void testadd()throws IOException {
//1.加载Mybatis核心配置文件,获取sqlsessionFactory与设置添加进数据库的数据内容
int status = 1;
String companyName = "小米";
String brandName = "小米";
String descrption = "双剑华斩";
int ordered = 100;
Brand brand = new Brand();
brand.setStatus(status);
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setDescription(descrption);
brand.setOrdered(ordered);
String resource = "mybaits_config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取sqlsession对象,执行sql
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3.执行sqL
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.addAll(brand);
}
需要注意的是,mybatis默认是手动提交事务,在执行完mapper.addall方法后需要提交事务,使用sqlsession.commit();方法来提交,或者也可以把手动提交事务改成自动提交,有些时候还需要返回该订单的主键,但这个属性不能让用户去添加,就需要设置useGeneratedKeys="true" keyProperty="主键名称",这样就可以获取到主键Id了
<insert id="addAll" useGeneratedKeys="true" keyProperty="id">
insert into tb_brand(brand_name,company_name,ordered,description,status)values(#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
mybatis修改数据
<update id="update">
update tb_brand
<set>
<if test="brandName != null and brandName !='' ">
brand_name = #{brandName},
</if>
<if test="companyName != null and companyName !='' ">
company_name = #{companyName},
</if>
<if test="ordered != null ">
ordered = #{ordered},
</if>
<if test="description != null and description !='' ">
description = #{description},
</if>
<if test="status != null and status !='' ">
status = #{status},
</if>
where id = #{id};
</set>
</update>
set标签可以实现修改语句的动态sql
mybatis删除数据
可以分为单个删除与批量删除,单个删除语句为delete from 表名 where 条件,在配置文件里面定义好就可以,这里不多赘述,主要来记录批量删除的操作方法。
<delete id="deleteByIdInts">
delete from tb_brand where id in(
<foreach collection="ids" item="id" separator=",">
#{id}
</foreach>
);
</delete>
关于
-
collection:需要被遍历的对象,当抽象方法的参数只有1个且没有添加@Param注解时,如果参数类型是List集合,则取值为list,如果参数类型是数组,则取值为array;当抽象方法的参数超过1个,就一定添加了@Param注解,则取值为@Param注解配置的参数值;
-
item:遍历过程中的每一个元素数据,当前属性可以自定义值表示元素数据的名称,在
节点的子级,使用#{}占位符时,就可以使用这个名称来表示数据; -
separator:遍历生成的代码片段中,各元素数据之间的分隔符号;
-
open / close:遍历生成的代码片段的最左侧字符串/最右侧字符串
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!