MyBatis配置文件完成增删改查
案例:完成品牌数据的增删改查操作
要完成的功能清单:
- 查询
- 添加
- 修改
- 删除
准备环境
CREATE TABLE tb_brand (
id INT PRIMARY KEY auto_increment,
brand_name VARCHAR ( 20 ),
company_name VARCHAR ( 20 ),
ordered INT,
description VARCHAR ( 100 ),
`status` INT );
INSERT INTO tb_brand ( brand_name, company_name, ordered, description, `status` )
VALUES
( '三只松鼠', '三只松鼠股份有限公司', 5, '好吃', 0 ),
( '华为', '华为技术有限公司', 100, '华为致力于构建万物互联的智能世界', 1 ),
( '小米', '小米技术有限公司', 50, 'are you ok', 1 );
select id,brand_name, company_name, ordered, description, `status` from tb_brand;
package com.ityc.pojo;
public class Brand {
private Integer id ;
private String brandName;
private String companyName ;
private Integer ordered;
private String description;
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Integer getOrdered() {
return ordered;
}
public void setOrdered(Integer ordered) {
this.ordered = ordered;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
return "Brand{" +
"id=" + id +
", brandName='" + brandName + '\'' +
", companyName='" + companyName + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
- 测试用例
- 安装MyBatisX插件
- 打开Setting–>打开Plugins–>搜索MyBatisX,安装
- 作用:xml和接口方法相互跳转,根据接口方法生成statement
MyBatis完成增删改查
查询
查询所有数据
-
编写接口方法:Mapper接口
package com.ityc.mapper;
import com.ityc.pojo.Brand;
import java.util.List;
public interface BrandMapper {
public List<Brand> selectALL();
}
-
编写sql语句:SQL映射文件: <?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.ityc.mapper.BrandMapper">
<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>
</mapper>
-
执行方法,测试 package com.ityc.test;
import com.ityc.mapper.BrandMapper;
import com.ityc.pojo.Brand;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisTest {
@Test
public void testSelectAll() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectALL();
System.out.println(brands);
sqlSession.close();
}
}
总结:
- MyBatis操作需要三步:编写接口方法–编写sql–执行方法
- 实体类属性名 与数据库列表名 不一致,不能自动封装数据
- 起别名
- resultMap:定义完成不一致属性名与列名的映射
查看详情功能
-
编写接口方法 Mapper接口
Brand selectById(int id);
参数:id 结果:Brand -
编写SQL语句:sql映射文件 <select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id = #{id};
</select>
-
执行方法:测试 @Test
public void testSelectById() throws IOException {
int id =2;
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
Brand brand = mapper.selectById(id);
System.out.println(brand);
sqlSession.close();
}
总结:
-
参数占位符
1. #{} 会替换为?,用来防止sql注入
2. ${} 拼 sql ,会存在sql注入问题
3.使用时机:
*参数传递的时候:#{}
*表明 列名不固定能使用 ${} 但是只要使用${}就一定存在sql注入问题
*sql语句特殊字符的处理
1. 转义字符
2.CDATA区
条件查询
1.多条件查询
-
编写接口方法Mapper接口 参数:所有查询条件 结果:list
List<Brand> selectByCondition(@Param("status") int status,@Param("companyName") String companyName,@Param("brandName") String brandName);
List<Brand> selectByCondition(Brand brand);
List<Brand> selectByCondition(Map map);
-
编写SQL语句:sql映射文件 <select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName};
</select>
-
执行方法,测试
@Test
public void testSelectByCondition() throws IOException {
int status =1;
String companyName = "华为";
String brandName = "华为";
companyName ="%"+ companyName +"%";
brandName ="%"+ brandName +"%";
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectByCondition(status, companyName, brandName);
System.out.println(brands);
sqlSession.close();
}
@Test
public void testSelectByCondition() throws IOException {
int status =1;
String companyName = "华为";
String brandName = "华为";
companyName ="%"+ companyName +"%";
brandName ="%"+ brandName +"%";
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectByCondition(brand);
System.out.println(brands);
sqlSession.close();
}
总结:
-
SQL语句设置多个参数有几种方式 1.散装的参数:如果方法中有多个参数,需要使用@Param(“SQL参数占位符名称”) 2.对象的参数:对象属性名称要和参数占位符名称一致 3.Map集合参数:要保证sql中的参数名和map集合的键的名称对应上,即可设置成功 -
出现bug,因为用户不会吧全部的3个空都填上,而不填全的话我们代码就会查出空值,
2.单条件动态查询
-
从多个条件中选择一个 choose(when,otherwise):选择,类似于java中的switch语句
<select id="selectByConditionSingle" 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 brand !=''">
brand_name like #{brandName}
</when>
//保底的otherwise,当用户一个都不选时执行
<otherwise>
1=1
</otherwise>
</choose>
测试类 @Test
public void testSelectByConditionSingle() throws IOException {
int status =1;
String companyName = "华为";
String brandName = "华为";
companyName ="%"+ companyName +"%";
brandName ="%"+ brandName +"%";
Brand brand = new Brand();
brand.setStatus(status);
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectByConditionSingle(brand);
System.out.println(brands);
sqlSession.close();
}
添加
步骤
- 编写接口方法
-
参数:除了id以外的所有数据 -
结果void
void add(Brand brand);
-
编写SQL语句:sql映射文件
<insert id="add">
insert into tb_brand(brand_name, company_name, ordered, description, status)
values(#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
-
执行方法,测试
@Test
public void testAdd() throws IOException {
int status =1;
String companyName = "旺旺碎冰";
String brandName ="旺旺";
String description = "给你哦破";
int ordered =100;
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.add(brand);
sqlSession.commit();
sqlSession.close();
}
MyBatis事务
-
openSession():开启事务,进行增删改操作后需要使用sqlSession.commit();手动提交事务 -
openSession(true):可以设置为自动提交事务(关闭事务) -
添加----主键返回 在数据添加成功后,需要获取插入数据库数据的主键的值
<insert id="add" useGeneratedKeys="true" keyProperty="id"></insert>
比如:添加订单和订单项 1.添加订单 2.添加订单项,订单项中需要设置所属订单的id
修改
修改全部字段
步骤:
1.编写接口方法Mapper
void update(Brand brand);
2.编写sql语句:sql映射文件
<update id="update">
update tb_brand
set brand_name= #{brandName},
company_name = #{companyName},
ordered = #{ordered},
description = #{description},
status = #{status}
where id =#{id};
</update>
3.执行方法,测试
@Test
public void testUpdate() throws IOException {
int status = 1;
String companyName = "旺旺碎冰";
String brandName ="哇哇哇哇哇哇哇哇哇哇哇";
String description = "给你哦破";
int ordered =200;
int id =5;
Brand brand = new Brand();
brand.setId(id);
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.update(brand);
sqlSession.commit();
sqlSession.close();
}
修改动态字段
因为上面的修改方法会修改所有字段,如果其他字段不填写就会被改为null,太过死板,所以就需要动态sql。
步骤:
1.编写接口方法Mapper
2.编写sql语句:sql映射文件
<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 ">
status = #{status}
</if>
</set>
where id = #{id};
</update>
3.执行方法,测试
删除功能
删除单个
步骤:
1.编写接口方法Mapper
2.编写sql语句:sql映射文件
<delete id="deleteByid">
delete from tb_brand where id = #{id};
</delete>
3.执行方法,测试
@Test
public void testDeleteByid() throws IOException {
int id= 5;
Brand brand = new Brand();
brand.setId(id);
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.deleteByid(id);
sqlSession.commit();
sqlSession.close();
}
批量删除
步骤:
1.编写接口方法Mapper
//批量删除
//使用@Param 注解来改变Map集合的默认key的名称
void deleteByids(@Param("ids") int[] ids);
2.编写sql语句:sql映射文件
<!--批量删除-->
<delete id="deleteByids">
delete from tb_brand
where id
in(
<foreach collection="ids" item="id" separator=",">
#{id}
</foreach>
);
</delete>
3.执行方法,测试
//批量删除功能
@Test
public void testDeleteByids() throws IOException {
int []ids ={6,7,8};
//封装对象
Brand brand = new Brand();
//1 获取 SqlSessionFaction对象
//加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 获取mapper 接口的代理对象
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4.执行方法
mapper.deleteByids(ids);
//手动提交事务
sqlSession.commit();
//5.释放资源
sqlSession.close();
}
动态SQL
-
SQL语句会随着用户的输入或者外部条件的变化而变化,我们称为动态SQL -
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。 -
MyBatis对动态sql有很强大的支撑 -
if:判断参数是否有值:使用test属性进行条件判断,存在问题第一个条件不需要逻辑运算符 -
choose(when,otherwise) -
trim(where,set):where标签替换关键词where,帮我们解决if中存在的问题 -
foreach
例:
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
<where>
<if test="status !=null">
and status = #{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>
</select>
|