(代码小白自我总结,仅供参考)
关键词:参数传递,sql注入,
映射文件mapper 下的namespace
是属性,属性的键必须小写,值一律是字符串
前期为了解决映射文件中命名空间相同的情况区分id,后期强制要求namespace的值是一个接口
传参(一个,多个)
1,单个:pojo(要求映射文件#中的名字必须和pojo属性完全一致)
接口,
//pojo Student select1(Student stu);
映射
<select id="select1" parameterType="student" resultType="Student"> select * from student where sid=#{sid} and sname=#{sname} </select>
测试
@Test public void select1(){ Student pojo = new Student(6, "子路"); SqlSession session = factory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); Student student = mapper.select1(pojo); System.out.println(student); }
2,单个map:有泛型<>(要求映射文件sql占位符中的名字必须和map参数中的key完全一致)
<haspmap相关代码>
map以key 和value为主
通过键找对应的值
接口
//map Student select2(Map<String,Object > m);
映射
<select id="select2" parameterType="map" resultType="Student"> select * from student where sid=#{aa} and sname=#{b} </select>
测试
@Test public void select2(){ Map<String,Object> map = new HashMap<>(); map.put("aa",6); map.put("b","子路"); SqlSession session = factory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); Student student = mapper.select2(map); System.out.println(student); }
3,单个collection(list,set)(要求映射文件中sql占位符的参数名称为collection或list数组,且下标从0 开始递增)
接口
//collection Student select3(Collection collection);
映射
<select id="select3" parameterType="collection" resultType="Student"> select * from student where sid=#{collection} and sname=#{list} </select>
当映射占位符中的参数名称为x,y,运行报错,显示aviliable[collection,list]
所以改为collection,list;
测试
@Test public void select3(){ Collection collection = new ArrayList(); collection.add(6); collection.add("子路"); SqlSession session = factory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); Student student = mapper.select3(collection); System.out.println(student); }
发现只能识别两个数组,没有数据取出
因为collection中数据是从0 开始放到数据库的,所以修改映射文件sql占位符参数名称
<select id="select3" parameterType="collection" resultType="Student"> select * from student where sid=#{collection[0]} and sname=#{collection[1]} </select>
4,array(在映射文件中占位符的参数名称为array数组,下表从0开始递增)
5,单个基本数据类型 int,double等映射文件中的参数名称随意,只要符合规范
6,单个引用数据类型Integer,String
//接口
//array
Student select4(Object[] array);
//int double
Student select5(int a);
//多条数据查询
List<Student> select6(Integer sid,String sname);
//换成$
List<Student> select7(String stu);
//映射
<select id="select4" parameterType="collection" resultType="Student">
select * from student
where sid=#{array[0]} and sname=#{array[1]}
</select>
<select id="select5" parameterType="_int" resultType="Student">
select * from student
where sid=#{dog}
</select>
<select id="select6" resultType="Student">
select * from student
where sid=#{arg0} and sname=#{arg1}
</select>
<select id="select7" parameterType="String" resultType="Student">
select * from student
order by ${param2} desc
</select>
//测试
@Test
public void select4(){
Object[] arr=new Object[]{6,"子路"};
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = mapper.select4(arr);
System.out.println(student);
}
@Test
public void select5(){
int dog = 3;
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = mapper.select5(dog);
System.out.println(student);
}
@Test
public void select6(){
int sid=6;
String sname="子路";
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> students = mapper.select6(sid,sname);
System.out.println(students);
}
7,多个参数(映射文件中sql占位符参数名称arg0,arg1或param1,param2)
接口
List<Student> select6(String sname);
映射文件
<select id="select6" resultType="Student">
select * from student where sid=#{param1} and sname=#{param2}
</select>
测试
@Test
public void select7(){
SqlSession session = factory.openSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> students = mapper.select7("sid");
System.out.println(students);
}
面试题:sql注入:'or' 1'='1
select* from user where account='aaa' and pwd=123;
该语句中包含子句:select from ;where ;=;
where条件里,等号左边可以不是列名
对于此sql语句,首先select选择到user表,然后游标定在第一条语句,where后的表达式返回值若不为真则抛弃;为真,即输出该条语句;
select * from user where account='aaa' and pwd= ''or'1'='1';
发现可查询到所有用户信息
原理:account='aaa' and pwd= ''or'1'='1';or之前的单引号和前面的单引号自动匹配成对,使or关键字生效,从而使or之后变成字符1=字符1;值为真;即执行查询语句。
如何预防sql注入:
1,将特殊字符单引号 ' ' 和等号 = 替换掉;
2,限制输入的长度,如密码只能输入6位;
3,对于mybatis,映射文件中mysql语句#{}换成${};
4,对于JDBC,选择使用prepareStatement而并不是statement
hsahset,arraylist区别
hashset实现set接口,arraylist实现list接口
顺序:hashset存储的元素是无序的,arraylist存放顺序和添加顺序是一致的
重复:hashset不能存储相同的元素, arraylist可以存放相同的数据
面试题:#和$符号的区别
$只用在变化的表,order by
select * from user order by 列名(列序号) //不写默认asc(升序) ;desc(降序)
接口
List<Student> select7(String stu);
映射
<select id="select7" parameterType="String" resultType="Student"> select * from student order by ${param2} desc </select>
测试
@Test public void select7(){ SqlSession session = factory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> students = mapper.select7("sid"); System.out.println(students); }