1.接口結合xml文件(相對於注解方式來說聯表方便)
2.字段與實體類屬性不匹配的處理
3.聯表查詢
一、接口結合xml文件
1.右鍵工程建議名為resources的Source Folder文件夾,用於存放config.xml、映射mappper包、properties文件
(經過編譯后文件內容都會在bin文件夾下)
2. dao包下建接口
1.映射文件下<mapper>標簽屬性namespace要和接口所在的包匹配 2.各操作標簽id要與接口中對應方法名一致==>作為接口的實現類 public interface RoleDao { public void addRole(Role role); public List<Role> selectById(@Param("min")int min,@Param("max")int max); } //@param注解參數命名,默認為[0, 1, param1, param2],見補充五 <?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.zhiyou100.yj.dao.OrderDao"> <insert id="addRole" parameterType="com.zhiyou100.yj.bean.Role"> insert into role(uname,description) values(#{uname},#{description}) </insert> <select id="selectById" resultType="com.zhiyou100.yj.bean.Role"> select * from role where id>#{min} and id<=#{max}; </select> </mapper>
3.測試
class RoleMapperTest { static SqlSession session=null; static RoleDao roleDao=null; @BeforeAll static void setUpBeforeClass() throws Exception { Reader reader = Resources.getResourceAsReader("config.xml"); SqlSessionFactory SessionFactory = new SqlSessionFactoryBuilder().build(reader); session = SessionFactory.openSession(); roleDao = session.getMapper(RoleDao.class); } @Test void testAddRole() { Role role=new Role("李大炳","助理"); roleDao.addRole(role); } @Test void testSelectById() { List<Role> roles = roleDao.selectById(3, 4); System.out.println(roles); } @AfterAll static void tearDownAfterClass() throws Exception { session.commit(); } }
補充一:接口結合xml如何實現參數傳入
直接傳參會報告以下異常: Error querying database. Cause:org.apache.ibatis.binding.BindingException: Parameter 'uname' not found. Available parameters are [0, 1, param1, param2] 這是由於mabatis把參數默認封裝到map中,它的鍵有兩種形式[0, 1, param1, param2] 解決這個問題有3種方法: 1、把參數改為Mybatis默認的參數[arg0, argX, param1, paramX](X對應參數個數); 2、把參數封裝為一個JavaBean,然后把接口參數改為這個JavaBean; 3、方法傳入map參數; 4、接口參數上使用@Param注解;(推薦)
二、字段名與實體類屬性不匹配
public class Role{ private int id; private String uname; private String description; } <update id="updateRole"> update role set role_uname=#{uname},role_description=#{description} where role_id=#{id} </update> 報錯:(查詢時不匹配屬性結果心顯示為null) org.apache.ibatis.binding.BindingException: Type interface com.zhiyou100.yj.dao.RoleDao is not known to the MapperRegistry. 方法一:為字段起別名以匹配實體類屬性 <select id="selectById" parameterType="int" resultType="com.zhiyou100.yj.bean.Role"> select role_uname name,role_description description,role_id id from role where role_id=#{id} </select> 方法二:resultMap屬性替換resultType屬性,並在resultMap中寫字段屬性對照關系 <select id="selectById" parameterType="int" resultMap="roleMap"> select * from role where role_id=#{id} </select> <resultMap type="com.zhiyou100.yj.bean.Role" id="roleMap"> <!-- type:表示那個實體類與表的對應關系,類比返回類型--> <id column="role_id" property="id"/> <result column="role_description" property="description"/> <result column="role_uname" property="name"/> </resultMap>
三、聯表查詢
1、多對一查詢;一對一查詢(一的一方作為另一方的屬性,查詢結果封裝到對象) //如每個班級對應一個班主任 2、一對多查詢(多的一方構成集合作為一的屬性,查詢結果封裝到集合) //如每個班級包含多個學生 1、多對一查詢;一對一查詢 public class Clazz { private int cId; private String cName; private int teacheId; private Teacher teacher; //關聯的是老師對象 private List<Student> students; //關聯的是學生對象集合 } public class Teacher { private int id; private String tName; } public class Student { private int sId; private String sName; private int classId; } <!-- 一對一聯表 --> <select id="selectClazzById" resultMap="ClazzMap"> select * from class c,teacher t where c.teacher_id=t.t_id and c_id=#{id} </select> <resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap"> <id column="c_id" property="cId"/> <result column="c_name" property="cName"/> <result column="teacher_id" property="teacheId"/> <!-- property:Teacher對象屬性 javaType:Teacher對象類型 --> <association property="teacher" javaType="com.zhiyou100.yj.bean.Teacher"> <id column="t_id" property="id"/> <result column="t_name" property="tName"/> </association> </resultMap> <!-- 一對一嵌套 --> <select id="selectClazzById2" resultMap="ClazzMap2"> select * from class where c_id=#{cid} <!--查詢班級id,根據查詢結果中獲得的班主任id進一步查詢--> </select> <resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap2"> <id column="c_id" property="cId"/> <result column="c_name" property="cName"/> <result column="teacher_id" property="teacheId"/> <!-- property:Teacher對象屬性 javaType:Teacher對象類型 select:對應進一步查詢語句的id(另一張表查詢) column:進一步查詢對應的條件字段(外鍵字段) --> <association property="teacher" javaType="com.zhiyou100.yj.bean.Teacher" select="selectTeacher" column="teacher_id"> </association> </resultMap> <!--寫法一:屬性字段不匹配,起別名--> <select id="selectTeacher" resultType="com.zhiyou100.yj.bean.Teacher"> select t_id id,t_name tName from teacher where t_id=#{teacher_id} </select> <!--寫法二:屬性字段不匹配,resultMap--> <select id="selectTeacher" resultMap="TeacherMap"> select * from teacher where t_id=#{teacher_id} </select> <resultMap type="com.zhiyou100.yj.bean.Teacher" id="TeacherMap" > <id column="t_id" property="id"/> <result column="t_name" property="tName"/> </resultMap> <!-- 一對多聯表 --> <select id="selectClazzById3" resultMap="ClazzMap3"> select * from class c,student s,teacher t where c.c_id=s.class_id and t.t_id=c.teacher_id and c.c_id=#{id}; </select> <resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap3"> <id column="c_id" property="cId"/> <result column="c_name" property="cName"/> <result column="teacher_id" property="teacheId"/> <association property="teacher" javaType="com.zhiyou100.yj.bean.Teacher"> <!--對象類型:teacher--> <id column="t_id" property="id"/> <result column="t_name" property="tName"/> </association> <collection property="students" ofType="com.zhiyou100.yj.bean.Student"> <!-- 集合類型:students;ofType:集合泛型的數據類型--> <id column="s_id" property="sId"/> <result column="s_name" property="sName"/> <result column="class_id" property="classId"/> </collection> </resultMap> <!-- 一對多嵌套 --> <select id="selectClazz4" resultMap="ClazzMap4"> select * from class where c_id=#{cid} </select> <resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap4"> <id column="c_id" property="cId" /> <result column="c_name" property="cName" /> <result column="teacher_id" property="teacheId" /> <association property="teacher" javaType="com.zhiyou100.yj.bean.Teacher" select="selectTeacher" column="teacher_id"> </association> <collection property="students" ofType="com.zhiyou100.yj.bean.Student" select="selectStudent" column="c_id"> </collection> </resultMap> <select id="selectTeacher" resultType="com.zhiyou100.yj.bean.Teacher"> select t_id id,t_name tName from teacher where t_id=#{teacher_id} </select> <select id="selectStudent" resultType="com.zhiyou100.yj.bean.Student"> select s_id sId,s_name sName,class_id classId from student where class_id=#{c_id} </select>
補充二:MyBatis中$與#的區別
$:解析時不會為內容添加"",是sql語句的拼接,存在sql注入危害 傳入的是列名或表名時,可以使用$ eg:如果value的值是anything' OR 'x'='x,那么sql語句就會是select * from user where name='anything' or 'x'='x' #:解析時會為內容添加"",采用占位符,傳遞過來的#{xxx}的內容會被轉義,然后替換掉"?"的內容 eg:select * from student where name='anything\' or \'x\'=\'x'
補充三:添加對象時如何把生產的id返回
<insert id="addRole" useGeneratedKeys="true" keyProperty="id">
insert into role(uname,description) values(#{uname},#{description})
</insert>