Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口
定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper接口开发需要遵循以下规范:
- 接口与mapper.xml在同一包下,且名字一致
- Mapper.xml文件中的namespace与mapper接口的类路径相同。
- Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
- Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
- Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Mybatis 的配置文件有2個:
- SqlMapConfig.xml:配置数据库等运行环境,并引入实体与数据库的映射xml文件.
- UserMapper.xml:配置实体与数据库表字段的映射.
SqlMapConfig.xml
<?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>
<!--自定义别名-->
-->
<!--在SqlMapConfig.xml中配置:
<typeAliases>
<!-- 单个别名定义 之后所有需要配置user全包名的地方,都可以只写user-->
<typeAlias alias="user" type="cn.itcast.mybatis.po.User"/>
<!-- 引入的mapper映射文件 -->
<mappers>
<!--第一种:文件路径引入映射器-->
<mapper resource="cn/itcast/mybatis/dao/UserDao.xml"/>
<!-- 第二种:包名 -->
<mapper class="cn.itcast.mybatis.mapper"/>
<!-- 必须遵循动态代理mapper开发规则 -->
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以)
所有自定义的实体类都可以写实体类的名称即可 -->
<!--第三种:类注册-->
<package name="cn.itcast.mybatis.mapper.UserMapper"/>
</mappers>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC" />
<!-- 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
</configuration>
UserMapper.xml:
<?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">
<!-- namespace:命名空间,做sql隔离 -->
<mapper namespace="test">
<!--
id:sql语句唯一标识
parameterType:指定传入参数类型
resultType:返回结果集类型
#{}占位符:起到占位作用,如果传入的
是基本类型(string,long,double,int,boolean,float等),
那么#{}中的变量名称可以随意写.
-->
<!--selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:
org.apache.ibatis.exceptions.TooManyResultsException:
Expected one result (or null) to be returned by selectOne(),
but found: 3 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)-->
<select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itheima.pojo.User">
select * from user where id=#{id}
</select>
<!--
如果返回结果为集合,可以调用selectList方法,这个方法返回的结果就是一个集合,
所以映射文件中应该配置成集合泛型的类型
${}拼接符:字符串原样拼接,如果传入的参数
是基本类型(string,long,double,int,boolean,float等),
那么${}中的变量名称必须是value
注意:拼接符有sql注入的风险,所以慎重使用
-->
<select id="findUserByUserName" parameterType="java.lang.String" resultType="cn.itheima.pojo.User">
<!--select * from user where username like "%"#{username}"%";这种方法可以防止sql注入-->
select * from user where username like '%${value}%'
</select>
<!-- 数据库自增主键
#{}:如果传入的是pojo类型,那么#{}中的变量名称必须
是pojo中对应的属性.属性.属性.....
如果要返回数据库自增主键:可以使用select LAST_INSERT_ID()
-->
<!-- 执行 select LAST_INSERT_ID()数据库函数,返回自增的主键
keyProperty:将返回的主键放入传入参数的Id中保存.
order:当前函数相对于insert语句的执行顺序,
由于mysql的自增原理执行完insert语句之后才将主键生成
,在insert前执行是before,在insert后执行是AFTER
resultType:返回auto_increment自增列新记录id值。
也就是keyproperties中属性的类型
-->
<!--第一种方法-->
<insert id="insertUser" parameterType="cn.itheima.pojo.User" >
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
<!--第二种方法useGeneratedKeys="true"-->
<insert id="insertUser" parameterType="cn.itheima.pojo.User"
useGeneratedKeys="true" keyProperty="id">
insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
<!--需要增加通过select uuid()得到uuid值--oracle数据库
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
select uuid()
</selectKey>
insert into user(id,username,birthday,sex,address)
values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
注意这里使用的order是“BEFORE”-->
<delete id="delUserById" parameterType="int">
delete from user where id=#{id}
</delete>
<!--如果仅需要更新某些字段,下面的sql语句,更新会达不到预期的效果,其他user中不需要更新的字段会被null代替
<update id="updateUserById" parameterType="cn.itheima.pojo.User">
update user set username=#{username} where id=#{id}
</update>-->
<!--更新时,传入的参数有一个是null都会出错,如果传入的参数的数值为null或者""
则这种字段不更新,使用到if标签;
但是还有一个问题,在于if下的字段下的逗号问题,最后与where 连接前多一个逗号
sql为:update user set username=?, where id=?
可以使用set标签,但是注意set'只可以去除一个逗号,多了去不了,字段后的逗号不可缺少-->
<update id="updateUserById" parameterType="cn.itheima.pojo.User">
update user
<set>
<if test="username != null and username!='' " >
username = #{username},
</if>
<if test="sex != null and sex!=''" >
sex= #{sex},
</if>
<if test="birthday != null and birthday!='' ">
birthday = #{birthday},
</if>
<if test="address != null and address !=''">
address = #{address},
</if>
</set>
where id = #{id}
</update>
</mapper>
UserMapper.xml 引入SqlMapConfig.xml的方式有以下几种:
1. <mapper resource=" " />
使用相对于类路径的资源
如:<mapper resource="sqlmap/User.xml" />
2. <mapper class=" " />
使用mapper接口类路径
如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
3. <package name=""/>
注册指定包下的所有mapper接口
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。