mybatis和hibernate对比
-
mapper.xml中可以写parameterType,不写可以自动判断
注意,集合list paramerter 可以是list,也可以是collection,这是别名,
int 别名是_int , short _short
mybatis动态代理流程:
从dao代理对象的方法,如图select..方法 ------------》找方法所在的接口IStudentDao------》根据接口全限定类名----》匹配mapper namespace----->根据方法名找mapper中id匹配
public class MyTest { private IStudentDao dao; private SqlSession sqlSession; @Before public void before() throws Exception { sqlSession = MyBatisUtil.getSqlSession(); dao = sqlSession.getMapper(IStudentDao.class); }
@Test
public void test01() {
// Student stu = new Student("四", 24, -1);
// Student stu = new Student("四", -1, -1);
Student stu = new Student("", -1, -1);
List<Student> students = dao.selectStudentsByConditionIf(stu);
for (Student student : students) {
System.out.println(student);
}
}
这种动态代理方式,底层会自动调用,所以返回值不能是map
要想是map,可以用不是动态代理创建实现类方式,返回所有对象,
selectMap,selectList只能用来返回所有对象,条件查询不可以,selectMap 是返货所有对象作为value,key是传入的值,然后通过get方法可以获取value
如果条件查询可以是selectone 也可以是selectlist
关联关系
1 指主表,多指从表 数据库而言
1指主表实体类,多从表实体类 java代码而言
这里所说的1对多,假设数据库表就是两表,1的一方,多的一方有外键,离开数据库,如果想前台查询1的一方,那么1的一方必须有多的一方域属性,然后就可以查询一的一方同时可以查询到一的一方包含多的一方,
这里的1对多,查询前者,可以查询到后者, 看到后者,
多对1也一样,表结构不会变,主外键关系都不变,多对1,是查询多的一方,可以查询到关联的一的一方,这里多的一方
mybatis 可以看到对方即有对方的属性,就称有单向关联关系,双向关联关系
反应到java代码上引用关系,反映到数据库表上是主外键关系
一方需要set不是List,set无序,不可重复
resultMapper在关联关系中位置不仅仅是解决属性和字段名称不一致,还可以封装域属性(就是关联属性set集合,可以通过查询此方可以看到的对方) resultType只能返回属性和字段名称一致的实体类对象,并且必须没有域属性才可以
1、第一种是多表联合查询
<!-- 当前的resultMap用于封装数据 --> <resultMap type="Country" id="countryMapper"> <id column="cid" property="cid"/> <result column="cname" property="cname"/> <collection property="ministers" ofType="Minister"> //1对多,从1方可以看到多的一方,可以查到多的一方,这时用collection(多的一方是集合) ,反过来从多的一方看1的一方,那么在多得一方有1的一方的域属性,配置用association(关联1的一方), <id column="mid" property="mid"/> <result column="mname" property="mname"/> </collection> </resultMap>
2、两个单表查询 ,先查要查询的表一次sql,再查查询表域属性表一次sql,两者关联起来
<mapper namespace="com.bjpowernode.dao.ICountryDao"> <select id="selectMinisterByCountryId" resultType="Minister"> select mid,mname ,countryId from minister where mid=#{abc}//abc可以任意,占位符,来自collection中的column,column中的值来自于查询表结果字段select cid,cname </select> <!-- 当前的resultMap用于封装数据 --> <resultMap type="Country" id="countryMapper"> <id column="cid" property="cid"/> <result column="cname" property="cname"/> <collection property="ministers" ofType="Minister" select="selectMinisterByCountryId" //查询域属性 set集合 id column="cid" //上面 查询域属性参数 > </collection> </resultMap> <select id="selectCountryById" resultMap="countryMapper"> //只查询单表,表中的域属性set ,可以再写一次sql查询 select cid,cname from country where cid=#{xxx} </select> </mapper>
这里的type ,resultType
都是简单类名,是因为在主配置文件中包别名
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 注册属性文件 --> <properties resource="jdbc.properties"/> <!-- 指定实体类的别名 --> <typeAliases> <!-- 指定包中所有类的别名为当前类的简单类名 --> 简单类名就是类名,不带包,就是java文件名,和全限定类名不一样,它是带包的 <package name="com.bjpowernode.beans"/> //意思这个包下所有的class都用简单类名 </typeAliases> <!-- 注册运行环境 --> <environments default="mySqlEM"> <environment id="mySqlEM"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!-- 注册映射文件 -->
要求:这样注册映射文件使用包名替代的,需要下面几个条件:映射文件名是:如IstudentMapper.xml映射文件名就是IstudentMapper
这三个条件不是mapper动态代理的,一直搞混,mapper动态代理也必须要求第三条,这样通过方法名找到dao接口再找到对应的namespace再是mapper sql 的id
![](https://img2018.cnblogs.com/blog/1382212/201811/1382212-20181114163424120-1942556494.png)
<mappers> <!-- <mapper resource="com/bjpowernode/dao/mapper.xml"/> --> <package name="com.bjpowernode.dao"/> </mappers> </configuration>
自关联是1对多,又有相同的属性,所以是自关联,像树就是自关联,自关联的域属性就是自身,底部是调用了递归思想
---------