1.属性名和字段名不一致
- 使用别名
<select id="selectAllStudents" resultType="Student"><!-- 需要定义resultType --> select tid id,tname name,tage age,score from student </select>
- 使用结果映射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"><!-- 需要定义resultType --> select tid ,tname ,tage ,score from student </select>
- Test
2.Mapper动态代理
我们知道,Mybatis实现增删改查需要进行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"> <mapper namespace="com.ryanxu.dao.IStudentDao"> <select id="selectById" resultType="Student"> select id,name,age,score from student where id = #{id} </select> </mapper>
上面的配置表示我们在命名空间com.ryanxu.dao.IStudentDao下定义一个ID为selectById的查询操作,其操作结果集为Student,对应的语句为select id,name,age,score from student where id = #{id}
那么在实际使用时,我们可以采用如下形式:
1 public Student selectStudentById(int id) { 2 Student student = null; 3 try { 4 sqlSession = MyBatisUtils.getSqlSession(); 5 student = sqlSession.selectOne("selectById", id); 6 } finally{ 7 if(sqlSession != null){ 8 sqlSession.close(); 9 } 10 } 11 return student; 12 }
这种方式有很明显的缺点就是通过字符串去调用标签定义的SQL,第一容易出错,第二是当XML当中的id修改过以后你不知道在程序当中有多少个地方使用了这个ID,需要手工查找并一一修改。
在Mybatis的新版本中做了一些改进,支持这种方式调用:定义一个接口 方法名,参数需要与XML定义保持一致。
- 动态代理的实现
- 把dao的实现类删除掉
注意这里的 namespace必须对应着map接口的全类名
<?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.ryanxu.dao.IStudentDao"> <select id="selectById" resultType="Student"> select id,name,age,score from student where id = #{id} </select> </mapper>
3.Test
1 public class MyTest { 2 3 private IStudentDao dao; 4 private SqlSession sqlSession; 5 6 @Before 7 public void before(){ 8 sqlSession = MyBatisUtils.getSqlSession(); 9 dao = sqlSession.getMapper(IStudentDao.class); 10 } 11 /*因为需要关闭sqlSession 所以需要After*/ 12 @After 13 public void after(){ 14 if(sqlSession != null){ 15 sqlSession.close(); 16 } 17 } 18 @Test 19 public void testSelectAllStudents(){ 20 List<Student> students = dao.selectAllStudents(); 21 for (Student student : students){ 22 System.out.println(student); 23 } 24 } 25 }
同时增删改需要添加sqlSession.commit
这样以来当我们修改了XML的ID以后,只需要修改接口中的方法就可以了,编译器会在其他使用该接口的地方报错,很容易进行修改。
3.多查询条件无法整体接受问题的解决
- 在dao中定义方法
- mapper中写sql语句
<select id="selectStudentsByCondition" resultMap="studentMapper"> select tid,tname,tage,score from student where tname like '%' #{0} '%' and tage > #{1} </select> <!-- #{}中可以放什么内容? 1)参数对象的属性 2)随意内容,此时的#{}是个占位符 3)参数为map时的key 4)参数为map时,若key所对应的value为对象,则可将该对象的属性方法 5)参数的索引号 -->
- Test
4.动态SQL
- <if/>标签
<select id="selectStudentByCondition2" resultType="Student"> select id,name,age,score from student where 1=1 <if test="name!=null and name!='' "> and name like '%' #{name} '%' </if> <if test="age > 0"> and age > #{age} </if> </select>
- Test
- <where/>标签
引入:成千上万条的数据不用where条件的话,那么效率会大大降低,所以有<where/>标签
<select id="selectStudentsByCondition2" resultType="Student"> select id,name,age,score from student <where> <if test="name!=null and name!='' "> and name like '%' #{name} '%' </if> <if test="age > 0"> and age > #{age} </if> </where> </select>
如果只有一个条件会把and自动去掉的 所以一般都加上and
- <choose/>标签
跟jstl中的<choose/>一样,跟switch也是一样的,这标签里只能包含多个<when/>和一个<otherwise/>
<select id="selectStudentsByConditionChoose" resultType="Student"> select id,name,age,score from student <where> <choose> <when test="name!=null and name!=''"> and name like '%' #{name} '%' </when> <when test="age > 0"> and age > #{age} </when> <otherwise> 1 = 2 </otherwise> </choose> </where> </select>
- Test
- <foreach/>标签--遍历数组
<select id="selectStudentsByForEach1" resultType="Student"> select id,name,age,score from student <if test="array.length > 0"> where id in <!-- for(Student student : students) item 就相当于是 student--> <foreach collection="array" item="myid" open="(" close=")" separator=","> #{myid} </foreach> </if> </select>
- Test
- <foreach/>标签--遍历泛型为基本类型的List
<select id="selectStudentsByForEach2" resultType="Student"> select id,name,age,score from student <if test="list.size > 0"> where id in <foreach collection="list" item="myid" open="(" close=")" separator=","> #{myid} </foreach> </if> </select>
- Test
- <foreach/>标签--遍历泛型为自定义类型的List
<select id="selectStudentsByForEach3" resultType="Student"> select id,name,age,score from student <if test="list.size > 0"> where id in <foreach collection="list" item="stu" open="(" close=")" separator=","> #{stu.id} </foreach> </if> </select>
- Test
- <sql/>标签
<sql id="selectColumns"> id,name,age,score </sql> <select id="selectStudentsBySqlFragment" resultType="Student"> select <include refid="selectColumns"/> from student <if test="list.size > 0"> where id in <foreach collection="list" item="stu" open="(" close=")" separator=","> #{stu.id} </foreach> </if> </select>
- Test