@BeforeEach注解
该注解的作用是在执行@Test方法前调用. 是测试方法提供的测试API.
关于mybatis参数问题说明
报错说明
规则: mybatis如果遇到多值传参时,默认条件是采用下标的方式获取数 据.
mybatis天生只支持单值传参,如果遇到多值的问题,则应该将多值封装 为单值.
参数知识总结
如果参数采用对象封装,则可以使用#{属性}取值.
如果参数有多个,可以封装为map实现参数的传递. 可以利用#{key}获取数据
也可以使用@Param将多个参数封装为map, 利用#{key}的方式获取数据
#号和$号用法
规则:
使用#{} 获取数据时,默认有预编译的效果.防止sql注入攻击.
mybatis使用#{}获取数据时,默认为数据添加一对""号.
当以字段名称为参数时,一般使用${},但是这样的sql慎用. 可能出现sql注入攻击问题
编辑测试方法
package com.jt.springboot_demo2_mybatis;
import com.jt.springboot_demo2_mybatis.mapper.DemoUserMapper;
import com.jt.springboot_demo2_mybatis.pojo.DemoUser;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TestMybatis2 {
private SqlSessionFactory sqlSessionFactory;
/**
* mybatis的核心 sqlSessionFacotry对象
* @BeforeEach:测试API中的注解,在执行@Test注解方法时,会提前执行!!!
*/
@BeforeEach
public void init() throws IOException {
//1,指定资源文件
//指定配置文件地址
String resource = "mybaits\\mybaits.config.xml";
//通过IO流 加载指定的配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//动态生成SqlSessionFactory
sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testMybatis01(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
List<DemoUser> list = demoUserMapper.findAll();
System.out.println(list);
sqlSession.close();
}
/**
* 作业:
* 1,查询name = "王昭君"的用户
* 2,查询sex = 女 and age > 18岁;两个条件
*/
@Test
public void testFindByName(){
//获取SqlSession 类比 数据库链接
//保证每个线程都能获取一个连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
String name = "王昭君";
//如果不能保证结果唯一,则使用List集合接收数据
//获取数据
List<DemoUser> list = demoUserMapper.findByName(name);
System.out.println(list);
//关闭资源
sqlSession.close();
}
@Test
public void testFindSA(){
//获取SqlSession 类比 数据库链接
//保证每个线程都能获取一个连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取接口
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
DemoUser user = new DemoUser();
user.setAge(18).setSex("女");
//获取数据
List<DemoUser> list = demoUserMapper.findSA(user);
System.out.println(list);
//关闭资源
sqlSession.close();
}
/**
* sex=女 and age > 18
* 方式2: @Param方式封装.
*/
@Test
public void testFindBySA2(){
//保证每个线程都能获取一个链接
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
String sex = "女";
int age = 18;
List<DemoUser> list = demoUserMapper.findBySA2(sex,age);
System.out.println(list);
sqlSession.close();
}
/**
* sex=女 and age > 18
* 方式3: map集合封装
*/
@Test
public void testFindBySA3(){
//保证每个线程都能获取一个链接
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("sex","女");
map.put("age",18);
List<DemoUser> list = demoUserMapper.findBySA3(map);
System.out.println(list);
sqlSession.close();
}
/**
* 需求:要求按照指定的age排序
* Sql: select * from demo_user order by age
* #和$ 的用法
*/
@Test
public void testFindOrder(){
//保证每个线程都能获取一个链接
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
String column = "age";
List<DemoUser> list = demoUserMapper.findOrder(column);
System.out.println(list);
sqlSession.close();
}
/**
* 需求:实现用户的入库操作
*/
@Test
public void testSaveUser(){
//保证每个线程都能获取一个链接
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
//数据库主键自增
DemoUser user = new DemoUser(null,"佛媛",99,"女");
int rows = demoUserMapper.saveUser(user);
if(rows > 0){
System.out.println("影响的行数"+rows);
//事务提交
sqlSession.commit();
}
sqlSession.close();
}
//1,把 id = 1 的数据 name 改为"守山大使" age = 5000
@Test
public void FindName(){
//保证每个线程都能获取一个链接
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
//数据库主键自增
DemoUser user = new DemoUser(null,"黑熊精",3000,"男");
int rows = demoUserMapper.findName(user);
if(rows > 0){
System.out.println("影响的行数"+rows);
//事务提交
sqlSession.commit();
}
sqlSession.close();
}
//2,将 name = "佛媛" 删除
@Test
public void FindDelect(){
//保证每个线程都能获取一个链接
SqlSession sqlSession = sqlSessionFactory.openSession();
DemoUserMapper demoUserMapper = sqlSession.getMapper(DemoUserMapper.class);
//数据库主键自增
String column = "name";
Object list = demoUserMapper.findDelect(column);
System.out.println(list);
sqlSession.close();
}
}
编辑业务接口
package com.jt.springboot_demo2_mybatis.mapper;
import com.jt.springboot_demo2_mybatis.pojo.DemoUser;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 说明:
* 1,根据面向接口开发的思想要定义一个Mapper接口
* 2,在接口中可以写接口方法,谁用谁去实现!!!
* 3,Mybatis中的实现类以xml文件的形式存在
*/
public interface DemoUserMapper {
//1,查询所有的表数据
public List<DemoUser> findAll();
DemoUser findOne(int id);
List<DemoUser> findByName(String name);
/* 1. 封装为实体对象 user对象
2. 更为常用的方式 Map集合
3. 如果传递的数据有多个,则可以使用注解@Param("sex") String sex 封装为Map.
*/
List<DemoUser> findSA(DemoUser user);
List<DemoUser> findBySA2(@Param("sex") String sex,@Param("age") int age);
List<DemoUser> findBySA3(Map<String, Object> map);
List<DemoUser> findOrder(String column);
int saveUser(DemoUser user);
int findName(DemoUser user);
String findDelect(String user);
}
编辑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">
<!--xml映射文件 必须与接口一对一绑定
namespace指定需要绑定的接口名称,不能重复-->
<mapper namespace="com.jt.springboot_demo2_mybatis.mapper.DemoUserMapper">
<!--实现接口中的方法
id 需要与接口中的绑定,一般复制粘贴
resultType 返回对象的包路径
规则:sql语句不要添加多余的;号 Oracle数据库不能添加;号
-->
<select id="findAll" resultType="com.jt.springboot_demo2_mybatis.pojo.DemoUser">
select * from demo_user
</select>
<!--
parameterType: 参数类型
mybatis中通过 #{} 获取参数
resultType: 返回值结果对象
-->
<select id="findOne" parameterType="int" resultType="com.jt.springboot_demo2_mybatis.pojo.DemoUser">
select *from demo_user where id = #{id}
</select>
<!-- 说明: parameterType其中的类型程序可以根据参数自动判断,所以可以省略不写 -->
<select id="findByName" resultType="com.jt.springboot_demo2_mybatis.pojo.DemoUser">
select * from demo_user where name = #{name }
</select>
<!--
查询sex=女 and age > 18岁
参数: DemoUser user 意图:传递属性的
规则: 如果传递的参数是对象,则通过#{属性} 可以直接获取数据.
-->
<select id="findSA" resultType="com.jt.springboot_demo2_mybatis.pojo.DemoUser">
select * from demo_user where age > #{age} and sex = #{sex}
</select>
<!--
如果参数被@Param("sex") String sex修饰
则#{参数key}即可获取数据
-->
<select id="findBySA2" resultType="com.jt.springboot_demo2_mybatis.pojo.DemoUser">
select * from demo_user where sex= #{sex} and age > #{age}
</select>
<!--
Map<String, Object> map
sex=女 age=18
规则: 如果参数是一个map集合,则通过#{key}获取数据.
-->
<select id="findBySA3" resultType="com.jt.springboot_demo2_mybatis.pojo.DemoUser">
select * from demo_user where sex= #{sex} and age > #{age}
</select>
<!-- 小结: 一般条件下能用#{}号,不用${}
-->
<select id="findOrder" resultType="com.jt.springboot_demo2_mybatis.pojo.DemoUser">
select * from demo_user order by ${column}
</select>
<!--
需求: 需要返回影响的行数.
mybatis执行"更新"操作时,自动的返回影响的行数
-->
<insert id="saveUser">
insert into demo_user value (null,#{name},#{age},#{sex})
</insert>
<!--
作业
1,把 id = 1 的数据 name 改为"守山大使" age = 5000
2,将 name = "佛媛" 删除
-->
<update id="findName">
update demo_user set name ="守山大使" , age = 5000 where id=1;
</update>
<select id="findDelect">
delete from demo_user where name ="佛媛"
</select>
</mapper>