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.手动封装结果集
需求:
当结果集中的字段的名称和对象属性名称不一致时,则不能实现自动的映射.
解决方案:
将自动封装改成手动封装即 resultType 改成使用 resultMap 属性
//将结果集实现手动封装映射 <select id="findMap" resultMap="userRM"> select id user_id,name ,age ,sex from user </select>
<!--type:表示封装的类型 --> <resultMap type="pojo.User" id="userRM"> <!--指定主键 必须写 --> <id column="user_id" property="id"/> <!-- <result column="user_name" property="name"/> <result column="user_age" property="age"/> <result column="user_sex" property="sex"/> --> </resultMap>
若出现部分不同时主键必须要设置,其他属性如果列名没有发生变化则不需要设置。
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 关联表 --> 查询出了一个老师的全部学生