操作
public interface IStudentDao {
void insertStudent(Student student); //插入学生
void insertStudentCacheId(Student student); //插入学生并且将数据库id值赋值给学生对象的id
void deleteStudentById(int id); //删除学生
void updateStudent(Student student); //修改学生
List<Student> selectAllStudents(); //查询学生
Map<String , Object> selectAllStudentsMap(); //返回map形式
Student selectStudentById(int id); //根据id查学生
List<Student> selectStudentByName(String name); //根据姓名查询
}
插入学生并且将数据库id值赋值给学生对象的id
<insert id="insertStudentCacheId">
insert into student(name, age, score) values(#{name}, #{age}, #{score})
<selectKey resultType="int" keyProperty="id" order="AFTER">
<!-- select @@identity -->
select last_insert_id()
</selectKey>
</insert>
resultType表示:select @@identity或select last_insert_id()的返回值的数据类型
keyProperty表示:将select @@identity或select last_insert_id()的返回值赋值给的实体类的属性
order表示:id的生成和insert语句执行的先后顺序关系,mysql是先执行insert语句,后生成id,插入到id字段中,oracle相反,before表示先生成id
删除学生
<delete id="deleteStudentById">
delete from student where id=#{xxx}
</delete>
这里的#{}中的内容可以随意,在此处表示仅仅是一个占位符
修改
<update id="updateStudent">
update student set name=#{name}, age=#{age}, score=#{score} where id=#{id}
</update>
因为传过来的参数是一个student,所以这里的#{}不表示占位符,里面的内容应该是student对象的属性
查询返回List
<select id="selectAllStudents" resultType="Student">
select id, name, age, score from student
</select>
对于查询来说不需要事务的提交,而且查询返回的是一个list可以直接用selectList,由于不用传递参数,所以只需要写一个参数即可。
resultType表示:将查询的结果封装成的数据类型
查询返回Map
public Map<String, Object> selectAllStudentsMap() {
Map<String, Object> map = new HashMap<>();
try {
sqlSession = MyBatisUtil.getSqlSession();
map = sqlSession.selectMap("selectAllStudents", "name");
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
return map;
}
selectMap的第二个参数只能是查询出来的对象的属性
根据id查询
public Student selectStudentById(int id) {
Student student;
try {
sqlSession = MyBatisUtil.getSqlSession();
student = sqlSession.selectOne("selectStudentById", id);
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
return student;
}
注意是:selectOne
根据姓名查询
<select id="selectStudentByName" resultType="Student">
<!-- select id, name, age, score from student where name like concat('%', #{xxx}, '%') -->
select id, name, age, score from student where name like '%' #{xxx} '%'
<!-- select id, name, age, score from student where name like '%${value}%' -->
</select>
推荐使用第二行,第一行和第二行的方式都是预编译,第三行的方式是字符串的拼接,效率低,存在SQL注入的问题,不推荐使用
字段名与属性名不一致问题
该问题出现的原因是:框架会根据我们查询出来的内容给我们自动封装成实体类对象,底层是采用反射的机制来实现的,根据在sql映射中select后的字段生成对应的set方法,然后将查询出来的内容用set方法设置,如果字段名与属性名不一致,就会导致set方法生成错误,也就不能成功封装到实体类对象中,需要注意的是:这种问题会出现在查询时,对增删改没有影响
解决方式一:起别名,在需要查询的字段后面起一个名称为属性的别名
<select id="selectAllStudents" resultType="Student">
select tid id, tname name, tage age, score from student
</select>
解决方式二:将查询结果resultType改为resultMap
<resultMap type="Student" id="StudentMapper">
<id column="tid" property="id"/>
<result column="tname" property="name"/>
<result column="tage" property="age"/>
</resultMap>
<select id="selectAllStudents" resultMap="StudentMapper">
select tid, tname, tage, score from student
</select>
type表示将查询的结果要封装成的数据类型
Mapper动态代理
多查询条件问题
方式一:使用Map作为进行封装
@Test
public void test01() {
Map<String, Object> map = new HashMap<>();
map.put("nameCon", "张");
map.put("ageCon", 27);
List<Student> students = dao.selectByConditon(map);
for (Student student : students) {
System.out.println(student);
}
sqlsession.commit();
}
<select id="selectByConditon" resultType="Student">
select id, name, age, score
from student
where name like '%' #{nameCon} '%'
and age > #{ageCon}
</select>
方式二:使用参数的索引号
@Test
public void test02() {
List<Student> students = dao.selectByIndex("张", 27);
for (Student student : students) {
System.out.println(student);
}
sqlsession.commit();
}
<select id="selectByIndex" resultType="Student">
select id, name, age, score
from student
where name like '%' #{arg0} '%'
and age > #{arg1}
</select>
#{}中可以放什么内容
1)参数对象的属性
2)随意内容,此时#{}是一个占位符
3)参数为map时的key
4)参数为map时,若key所对应的value为对象,则可将对象的属性放入
5)参数的索引号