1.Mybatis中的接口形式
在Mybatis中使用接口形式将通过代理对象调用方法,从而实现sql的执行
1)定义一个接口
package mapper; import java.util.List; import pojo.User; public interface UserMapper { public List<User> findAll(); }
2)是通过代理对象调用方法
//测试接口方式 @Test public void test04(){ SqlSession session = factory.openSession(); //获取接口对象 UserMapper userMapper = session.getMapper(UserMapper.class); System.out.println(userMapper.getClass()); List<User> userList = userMapper.findAll(); for (User user : userList) { System.out.println(user); } }
3)映射配置文件中,namespace的值是包名.接口名-->mapper.UserMapper
写sql标签的id为方法名 ---> findAll
<select id="findAll" resultType="User"> <include refid="selectUser"/> </select>
通过接口形式的原理:
当通过接口执行接口方法时,首先Mybatis会为接口创建代理对象.通过代理对象调用方法时,
首先会根据接口的类型mapper.UserMapper匹配
映射文件中的namespace.
如果匹配成功,之后接口方法匹配映射文件中的sql的ID,
如果匹配成功则调用sql语句完成操作.
2.手动封装结果集
需求:
当结果集中的字段的名称和对象属性名称不一致时(或者说pojo中存在自定义引用类型属性),则不能实现自动的映射.
解决方案:
将自动封装改成手动封装即 resultType 改成使用 resultMap 属性(一下是一对一的自关联查询)
1 <select id="findAll" resultMap="deptRm"> 2 select * from 3 dept_p d 4 left join 5 (select dept_id p_id,dept_name p_name from dept_p) p 6 on d.parent_id = p.p_id 7 order by dept_id 8 </select> 9 <resultMap type="Dept" id="deptRm" autoMapping="true"> 10 <id column="dept_id" property="deptId"/> 11 12 <association property="parentDept" javaType="Dept"> 13 <id column="p_id" property="deptId"/> 14 <result column="p_name" property="deptName"/> 15 </association> 16 </resultMap>
bean:
association:一般在实际开发中用于一个bean中存在另一个bean进行数据封装。
autoMapping:若存在引用类型属性时应该添加该属性后就会实现自动映射。
association中的property标识bean中的属性。
JavaType标识bean的全限定名称。
若出现部分不同时主键必须要设置,其他属性如果列名没有发生变化则不需要设置。
mybatis中如果操作的是单表,那么除主键之外,如果结果集中的字段的名称和属性名一致,可以自动完成映射.
3.一对一关联关系:
如果是多表关联查询,结果集中的字段名称和主对象中的属性名一致,可以通过autoMapping="true"实现自动映射.
一对一封装的具体实现过程:
要求:结果集中不允许出现同名字段,否则mybaits不能正确解析。
<!--一对一关联查询 --> <select id="oneTOne" resultMap="userOneTOne"> select * from user u left join userinfo info on u.id = info.user_id </select> <resultMap type="pojo.User" id="userOneTOne" autoMapping="true"> <!--主键封装 --> <id column="id" property="id"/> <!--一对一封装 --> <association property="info" javaType="pojo.UserInfo"> <id column="user_id" property="userId"/> <result column="tel" property="tel"/> <result column="qq" property="qq"/> </association> </resultMap>
一对一封装时 association 与javaType一起联用
4.一对多关联关系:
一对多关联封装时,需要使用集合进行封装。
<!--一对多关联封装--> <select id="oneTMore" resultMap="deptOneTMore"> select d.dept_id,d.dept_name,u.id,u.name,u.age,u.sex from dept d left join user u ON d.dept_id = u.dept_id </select> <resultMap type="pojo.Dept" id="deptOneTMore"> <!--主对象封装完成 --> <id column="dept_id" property="deptId"/> <result column="dept_name" property="deptName"/> <!--一对多关联封装 --> <collection property="userList" ofType="pojo.User"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="age" property="age"/> <result column="sex" property="sex"/> </collection> </resultMap>
一对多封装时 Collection 和 ofType 一起使用
5.多对多关联关系
多对多其实就是双向一对多。
<!-- 三表联查 --> <select id="findT_S" resultMap="t_s"> select * from (select t.t_id,t.t_name,t.t_sex,s_t.student_id from teacher t left join s_t on t.t_id = s_t.teacher_id)t left join student s on t.student_id = s.id </select> <resultMap type="pojo.Teacher" id="t_s"> <id column="t_id" property="tId"/> <result column="t_name" property="tName"/> <result column="t_sex" property="tSex"/> <!--多对多封装 --> <collection property="studentList" ofType="pojo.Student"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="age" property="age"/> </collection> </resultMap>
student 、teacher、s_t 关联表 --> 查询出了一个老师的全部学生