上2篇博客写了如何带参查询和动态sql查询。下面说一说怎么进行添加,修改,删除操作。
添加:
步骤还是一样,现在Mapper中定义好相应接口。
void add(brand brand);
然后按着option,在按俩次回车,就可以在Mapper.xml文件中生成对应的方法:
<insert id="add">
insert into sql_store.customers (city,points,first_name,last_name,address,state)
value (#{city},#{points},#{firstName},#{lastName},#{address},#{state})
</insert>
然后就是对应的 测试方法:
@Test
public void add() throws IOException {
//接收参数
String city="a";
int points=12;
String firstName="B";
String lastName="S";
String address="A";
String state="C";
//手动处理参数
//city="%"+city+"%";
//firstName="%"+firstName+"%";
//封装对象
brand brand=new brand();
// brand.setId(id);
brand.setCity(city);
brand.setPoints(points);
brand.setFirstName(firstName);
brand.setLastName(lastName);
brand.setAddress(address);
brand.setState(state);
//1.获取SqlSessionFactory。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//传入参数true,改为自动提交事务
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3.获取Mapper接口的代理对象
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
//4.执行方法
brandMapper.add(brand);
Integer id1 = brand.getId();
System.out.println(id1);
//提交事务
sqlSession.commit();
//5.释放资源
sqlSession.close();
}
在idea执行add操作,要添加提交事务的步骤:sqlSession.commit? 否则就算在idea显示执行成功,在数据库表中也不会显示任何变化。提交事务有2种方式:? 一种就是sqlSession.commit;? ?另一种是SqlSession sqlSession = sqlSessionFactory.openSession(true);传入true参数表示自动提交事务。
? 另外如果我们想执行添加操作的同时返回生成的主键id,目前的代码是无法实现该功能的,因为在写sql语句时,我们没有写关于主键id的任何语句。
我们只需要稍微改一下
<insert id="add" useGeneratedKeys="true" keyProperty="id">
insert into sql_store.customers (city,points,first_name,last_name,address,state)
value (#{city},#{points},#{firstName},#{lastName},#{address},#{state})
</insert>
useGeneratedKeys="true" keyProperty="id" 用于设置主键返回 keyProperty后的id为brand中的实体属性,不是数据库中的字段 。
这样我们就可以返回添加新数据的对应主键id了。
修改操作:
? 修改全部:接口方法
int update(brand brand);
接口方法返回值可以为void,也可以是int,我设置成int 是想返回修改的行数。
sql语句
? ?1、修改全部,如果修改过程中若未声明该字段的值,则默认修改为null。
<update id="update">
update sql_store.customers
set city =#{city},
points=#{points},
first_name=#{firstName},
last_name=#{lastName},
address=#{address},
state=#{state}
where customer_id=#{id}
</update>
? ?2、动态修改,只需要其中的部分条件,未声明要修改的不变。
<update id="update">
update sql_store.customers
<!--set-->
<set>
<if test="city!=null and city!=''">
city =#{city},
</if>
<if test="points!=null">
points=#{points},
</if>
<if test="firstName!=null and firstName!=''">
first_name=#{firstName},
</if>
<if test="lastName!=null and lastName!=''">
last_name=#{lastName},
</if>
<if test="address!=null and address!=''">
address=#{address},
</if>
<if test="state!=null and state!=''">
state=#{state}
</if>
</set>
where customer_id=#{id}
</update>
不用<set>标签,用set,这样写有俩个问题,问题一:逗号问题,如果最后一个if不存在,那么sql语句最后会多一个逗号,导致报错
问题二:如果set中的所有if都不存在,那么set也就没存在的必要了
解决办法 用<set>标签代替set。
测试方法
@Test
public void update() throws IOException {
//接收参数
int id=16;
String city="a";
int points=32;
String firstName="Q";
String lastName="S";
String address="E";
String state="C";
//手动处理参数
//city="%"+city+"%";
//firstName="%"+firstName+"%";
//封装对象
brand brand=new brand();
brand.setCity(city);
brand.setPoints(points);
brand.setFirstName(firstName);
brand.setLastName(lastName);
brand.setAddress(address);
brand.setState(state);
brand.setId(id);
//1.获取SqlSessionFactory。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//传入参数true,改为自动提交事务
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3.获取Mapper接口的代理对象
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
//4.执行方法
int count = brandMapper.update(brand);
System.out.println(count);
//提交事务
sqlSession.commit();
//5.释放资源
sqlSession.close();
}
删除操作
? 单个删除
? ? 接口方法
void deleteById(int id);
? ?sql语句
<delete id="deleteById">
delete from sql_store.customers
where customer_id=#{id}
</delete>
测试方法
@Test
public void deleteById() throws IOException {
//接收参数
int id=16;
//1.获取SqlSessionFactory。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//传入参数true,改为自动提交事务
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3.获取Mapper接口的代理对象
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
//4.执行方法
brandMapper.deleteById(id);
//提交事务
sqlSession.commit();
//5.释放资源
sqlSession.close();
}
? 批量删除,这时候接口方法中不能只传一个id了,需要传入一个id的数组
? ?接口方法
void deleteByIds(int[] ids);
? sql语句
<delete id="deleteByIds">
delete from sql_store.customers
where customer_id
in
<foreach collection="array" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
? ? ? ?foreach标签:collection为数组名,item为元素,separator为多个元素之间的分隔符。
? ? ? ? ? ? ?separator不可省略,当数组中存在多个元素时,元素之间需要用逗号分隔,sql语句才不会报错。open 为foreach开头以什么开头 ?close 为foreach结尾以什么结尾。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???mybatis会将数组参数封装成一个Map,map是键值对的集合。
? ? ? ? ? ? ? ? ? ? ? ? 默认:array=数组 ? array为key
? ? ? ? ? ? ? ? ? ? ? ? 如果collection不想用array,使用@Param注解将接口方法参数改为void deleteByIds(@Param("ids") int[] ids);这时collection就可以用自己定义的方法了。
测试方法
@Test
public void deleteByIds() throws IOException {
//接收参数
int[] ids={18,19};
//1.获取SqlSessionFactory。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//传入参数true,改为自动提交事务
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3.获取Mapper接口的代理对象
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
//4.执行方法
brandMapper.deleteByIds(ids);
//提交事务
sqlSession.commit();
//5.释放资源
sqlSession.close();
}
上面讲的都是怎么写xml配置文件来执行sql语句,其实还有一个更加简单的方法来执行sql语句,那就是用注解。使用注解就不需要写xml配置文件了:
查询@Select(“”),添加@Insert(“”),修改@Update(“”),删除@Delete(“”)。
sql语句写在括号中。
@Select("select * from sql_store.customers where customer_id=#{customer_id}")
brand selectByIdBrand(int id);
然后直接写测试方法
@Test
public void selectByIdBrand() throws IOException {
//接收参数
//1.获取SqlSessionFactory。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//传入参数true,改为自动提交事务
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3.获取Mapper接口的代理对象
brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
//4.执行方法
brand brand = brandMapper.selectByIdBrand(1);
System.out.println(brand);
//5.释放资源
sqlSession.close();
}
我们可以发现测试方法并没发生什么变化。
但是注解只适合来完成简单的功能,配置文件完成复杂的功能。