mybatis面向接口编程
1.mybatis配置文件
<configuration>
<properties resource="db.properties"> </properties>
<typeAliases>
<package name="com.yc.po"></package>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/yc/dao/UserMapper.xml"/>
</mappers>
</configuration>
一:mybatis配置文件的解释:
1.mysql配置文件的引入:
<properties resource="db.properties"> </properties>
2.给com.yc.po这个包创别名,别名默认是类名首字母大小写均可;此处定义后,本项目下的xxmapper.xml中就可以使用别名,不用使用全路径;
<typeAliases>
<package name="com.yc.po"></package>
</typeAliases>
3.生态环境搭建 可为mysql 和oracle等 <environments default="development">
为选择哪种环境
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
4.配置mapper映射,resource代表xxmapper.xml 的路径,class 代表与xxmapper.xml映射的接口的全路径 package 中 name是接口包名的全路径.,此处是将xxmapper,xml与该配置联系起来,用于以后
inputStream=Resources.getResourceAsStream("mybatis-config.xml");
//创建sqlsessionfactory
factory=new SqlSessionFactoryBuilder().build(inputStream);
创建工厂时能加载到xxmapper.xml配置文件
<mappers>
<mapper resource="com/yc/dao/UserMapper.xml"/>
<mapper class="com.yc.dao.UserMapper"/>
<package name="com.yc.dao"/> <!-- 批量处理 -->
</mappers>
二:构建mapper映射
<mapper namespace="com.yc.dao.UserMapper">
<select id="findById" resultType="userPO">
select * from tb_user where usid= #{id}
</select>
<insert id="addUser" parameterType="UserPO">
insert into tb_user (uname,pwd) values(#{uname},#{pwd})
</insert>
</mapper>
1.命名空间:
<mapper namespace="com.yc.dao.UserMapper">
作用:
1.将sql进行隔离,每个mapper.xml对应一个命名空间
2.将命名空间设置为定义sql语句方法的定义接口的路径 就可以使用mapper代理找到该接口
2.方法类型
像 <select> </select>
对应查找 等等,id对应接口中方法名,resultType对应返回值类型,当返回值类型是包装类时查询的列名必须和包装类的属性名一致,完全不一致不创建对象接收数据,部分一致时创建对象接收相同数据,其他不同数据不接收,parameterType=“UserPO” 代表参数类型 ,#{} 设置参数 相当于预加载的占位符? 如果传入类型为基本数据类型{}里面的参数名自定义,但是如果是包装类必须为包装类的属性名;
<select id="findById" resultType="userPO">
select * from tb_user where usid= #{id}
</select>
三.sql语句传入参数parameterType,parameterMap和返回结果参数resultType,resultMap的注意事项
传入参数:
1.parameterType;
2.parameterMap;
parameterType:可为基本数据类型,包装类;
parameterMap:为map<K,V>
1.为基本类型时如果传入多个参数xxmapper.xml中的sql语句的参数就不可像单个参数那样任意命名
<select id="findById" resultType="userPO">
select * from tb_user where usid= #{id}
</select>
<1>上述为单个基本类型参数 #{}中参数名可随意定义
<insert id="addUser2" databaseId="mysql">
insert into tb_user values(null,#{param1},#{param2})
</insert>
<2>上述为多个基本类型参数#{}中参数只能用 param1 ,param2…paramN来定位参数
这是由底层代码用Map<KEY,VALUE >来实现的 Map<param1,“你输入的第一个参数”>,Map<param2,“你输入的第一二参数”>…
2.传入参数为包装类时
<insert id="addUser" parameterType="UserPO" databaseId="mysql">
insert into tb_user values(null,#{uname},#{pwd})
</insert>
传入参数必须与包装类对象的属性名一一对应
3.可以使用自定义Map<k,v>来当传入参数
表名甚至都可以用参数传入
<select id="findByMap" resultType="userPO" databaseId="mysql">
select *from ${tableName} where usid=${uname} and uname=#{pwd}
</select>
在测试类中自定义Map
Map<String,Object>map=new HashMap<String,Object >();
map.put(“tableName”,“tb_user”);
map.put(“uname”, “yc”);
map.put(“pwd”, " ‘a’ ");
${}与#{}的区别:
${}:等价于字符串的拼接
设值时如果是字符串 要加’ ’ map.put(“pwd”, " ‘a’ ");
如图所示它会将表名tb_user 和usid 的值给设置进去
而#{}相当于占位符只会设置成?运行时赋值
返回参数:
1.resultType;
2.resultMap;
resultType:
1.如果是查数量count 只能返回一列
不然不知道该返回哪个值给count函数
如:
select count(*) from tb_user;
2.如果返回类型是包装类
列名必须与属性名一致,sql语句中不能为列定别名,如果想定别名需用到reslutMap进行配置
如:
select uname u_name from tb_user;
u_name 就是uname的别名;
navicat的查询结果:
这样使用mybatis中查询不到,因为它无法定位到u_name,数据库中只有列名uname;
5.主键自增:
resultMap的配置:
//type:结果映射到UserInfoPO这个po对象类中
//id: 这个映射的唯一标识,后面调用该映射会用到
<resultMap type="UserInfoPO" id="myuserStep">
<id column="uid" property="uid" />//column:数据库列名而且是唯一标识,property:po对象中与column相对应的属性名,如果多个列名才能标识一条记录就配置多个<id/>
<result column="uname" property="uname"/>//<result />是你要得到的数据库其他非唯一标识的列名;
<result column="upwd" property="upwd"/>
<result column="usex" property="usex"/>
<result column="uemail" property="uemail"/>
<discriminator javaType="String" column="usex">//相当于java中switch判断语句 column根据那一列的数据判断
<case value="女" resultType="UserInfoPO">//value:判断的条件
<!-- association 进行分步查询:
1.根据ID查看用户信息
2.根据用户信息中tid值去类型表查看类型信息
3.将查询的类型信息设置到用户信息中
-->
<association property="typeinfo" select="com.yc.dao.TypeInfoMapper.findById" column="tid">//association :进行分步查询
//一查询能延迟加载,延迟加载要去mybatisConfig.xml中配置setting; <settings>
// <setting name="lazyLoadingEnabled" value="true"/>
// <setting name="aggressiveLazyLoading" value="false"/>
// </settings>
//------------------------------------------------------------
</association>
</case>
<case value="男" resultType="UserInfoPO">
<id column="uid" property="uid" />
<result column="uname" property="uname"/>
<result column="upwd" property="upwd"/>
<result column="usex" property="usex"/>
<result column="uname" property="uemail"/>
</case>
</discriminator>
</resultMap>
<!-- public UserInfoPO findUserStep(Integer id); -->
<select id="findUserStep" resultMap="myuserStep">//resultMap:根据id调用上述resultMap的配置
select *from tb_userinfo where uid=#{id}
</select>
配置一对多的关系
<resultMap type="TypeInfoPO" id="mytype">
<id column="tid" property="tid" />
<result column="tname" property="tname"/>
<!-- collection 嵌套结果集的封装规则
property="users" 指定属性 ofType="UserInfoPO"
-->
<collection property="users" ofType="UserInfoPO">
<!-- 定义集合中元素的封装规则 -->
<result column="uname" property="uname"/>
<result column="upwd" property="upwd"/>
<result column="usex" property="usex"/>
<result column="uemail" property="uemail"/>
</collection>
</resultMap>