MyBatis是一个优秀的持久层框架,它主要是完成对操作数据库的过程进行封装。它以xml或注解的方式将要执行的各种statement配置起来,并通过Java对象和statement中的sql进行映射生成最终执行的sql语句,最后让mybatis框架进行sql并将结果映射成Java对象并返回。
其中在mybatis的配置文件以及dao层的配置文件需要认真对待,在mybatis的配置文件中需要完成数据库连接的路劲及配置信息,并配置好mapper映射关系的文件路径,例如:
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- mybatis数据库配置 -->
<dataSource type="POOLED">
<!-- 根据数据库版本使用不同的驱动,6.0版本以上使用com.mysql.cj.jdbc.Driver,6.0以下使用com.mysql.jdbc.Driver -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<!-- 数据库连接路径:其中可以除了必要的路径信息外,还可以在后面以?结尾添加UTF—8字符集设置(characterEncoding=UTF8)以及时区设置( serverTimezone=GMT)-->
<property name="url" value="jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=UTF8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT" />
<property name="username" value="root" />
<property name="password" value="1234567" />
</dataSource>
</environment>
</environments>
<!-- 配置mapper映射文件的路径 -->
<mappers>
<!-- 需要执行的dao层的xml文件路径 -->
<mapper resource="dao/StudentMapper.xml" />
</mappers>
</configuration>
在dao层的xml文件中,我们需要设置好dao接口的路径,在xml文件中编写我们的sql功能语句,即相应的增删改查。
其中需要注意的地方有resultType和resultMap的用法,resultType可以把查询结果封装到pojo类型中,但必须pojo类的属性名和查询到的数据库表的字段名一致。 如果sql查询到的字段与pojo的属性名不一致,则需要使用resultMap将字段名和属性名对应起来,进行手动配置封装,将结果映射到pojo中,resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
在sql语句中的#或$用于接收dao接口传递的参数,其中#是以注入的方式放入了sql语句,$是以拼接的方式放入了sql语句。
dao层mapper的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">
<!-- namespce中放入dao接口的路径 -->
<mapper namespace="dao.StudentDao">
<!-- 修改方法 -->
<update id="change1">
update students set sage=#{age},sname=#{name} where
sid=#{id}
</update>
<!-- 通过id查询信息 -->
<select id="queryStuById"
resultType="model.Student">
select * from students where sid=${id1}
</select>
<!-- 添加信息 -->
<insert id="addStu1">
insert into students
values(#{students.sid},#{students.sage},#{students.sname})
</insert>
<!-- 查询所有信息 -->
<select id="queryAllStu" resultMap="stu">
select * from students
</select>
<!-- 双表联合查询 -->
<select id="getStuWithScore" resultMap="ss">
SELECT * from students s
LEFT JOIN scores ss ON s.sid=ss.sid
</select>
<!-- id中放dao层的接口,resultMap中放数据库映射关系的id -->
<select id="getStuWithObj" resultMap="so">
select * from students s
join objs o on s.sid=o.sid
</select>
<!-- 使用where标签可以自动在sql语句中加上where条件关键字 -->
<select id="getStuMH" resultMap="stu">
select * from students
<where>
<if test="min!=null and max!=null">
<!-- 可以使用between and 完成区间查询-->
and sage > #{min} and sage < #{max}
</if>
<if test="xuefen!=null and xuefen !=''">
and xuefen > #{xuefen}
</if>
<if test="name!=null">
and sname like concat(#{name},'%')
</if>
</where>
</select>
<!-- choose标签 完成多选一条件筛选 -->
<select id="getStuWhen" resultMap="ss">
select * from students s join scores ss on
s.sid=ss.sid where 1=1
<!-- <where> -->
<choose>
<when test="zong!=null">
and zong > #{zong}
</when>
<when test="xuefen!=null">
and xuefen > #{xuefen}
</when>
<otherwise>
and sname like '张%'
</otherwise>
</choose>
<!-- </where> -->
</select>
<!-- trim标签 完成sql语句的拼接:
trim 属性prefix:
前缀覆盖并增加其内容
suffix:后缀覆盖并增加其内容
prefixOverrides:前缀判断的条件
suffixOverrides:后缀判断的条件
-->
<update id="gaifen">
update students
<trim prefix="set" suffix="where sid=#{sid}" suffixOverrides=",">
<if test="xuefen!=null">
xuefen=#{xuefen},
</if>
<if test="sname!=null">
sname=#{sname}
</if>
</trim>
</update>
<!-- set标签拼接修改语句 -->
<update id="gaifen1">
update students
<set>
<if test="xuefen!=null">
xuefen=#{xuefen}
</if>
</set>
<where>
sid=#{sid}
</where>
</update>
<!-- dao层传入对象数组 ,并根据对象数组查询相关信息 -->
<!-- foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。
foreach元素的属性主要有 item,index,collection,open,separator,close。
item :表示集合中每一个元素进行迭代时的别名
index :指定一个名字,用于表示在迭代过程中,每次迭代到的位置
open :表示该语句以什么开始
separator :表示在每次进行迭代之间以什么符号作为分隔符
close :表示以什么结束
-->
<!-- 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array -->
<select id="getStuByAgeArray" resultMap="stu">
select * from students where sage in
<foreach collection="array" item="ages" open="(" close=")" separator=",">
#{ages}
</foreach>
</select>
<!-- 如果传入的是单参数且参数类型是一个list集合的时候,collection的属性值为list -->
<select id="getStuByAgeArray2" resultMap="stu">
select * from students where sage in
<foreach collection="list" item="ages" open="(" close=")" separator=",">
#{ages}
</foreach>
</select>
<!-- 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map -->
<select id="getStuByMap" resultMap="stu">
select * from students where xuefen > #{xuefen} and sage in
<foreach collection="ages" item="age" open="(" close=")" separator=",">
#{age}
</foreach>
</select>
<!-- resultMap中type放入实体类的全限定类名,id与上方sql语句调用的resultMap的名字一致 -->
<resultMap type="model.Student"
id="stu">
<id property="sid" column="sid" />
<!-- <result property="sname" column="sname"/> -->
<result property="sage" column="sage" />
</resultMap>
<resultMap type="model.Student"
id="ss">
<!-- id通过索引查询数据 -->
<id property="sid" column="sid" />
<!-- result通过遍历查询数据 -->
<result property="sname" column="sname" />
<result property="sage" column="sage" />
<result property="xuefen" column="xuefen" />
<!-- association中的property放实体类名称,javaType中放实体类的全限定名 -->
<!-- association完成一对一查询,多列查询 -->
<!-- 此处未使用association -->
<collection property="score"
ofType="model.Score">
<result property="bishi" column="bishi" />
<result property="jishi" column="jishi" />
<result property="zong" column="zong" />
</collection>
</resultMap>
<resultMap type="model.Student"
id="so">
<id property="sid" column="sid" />
<result property="sname" column="sname" />
<!-- collection中的property放实体类名称,javaType中放实体类全限定名 -->
<!-- collection完成一对多查询,多行查询 -->
<collection property="wupin"
ofType="model.Wupin">
<result property="desc" column="desc" />
</collection>
</resultMap>
</mapper>
dao接口的写法:
public interface StudentDao {
//修改方法
int change1(@Param("id")int sid,@Param("age")int sage,@Param("name")String sname);
//通过id查询
Student queryStuById(@Param("id1")int sid);
//添加方法
int addStu1(@Param("students")Student stu);
//查询所有
List<Student> queryAllStu();
//双表查询,显示多列
List<Student> getStuWithScore();
//双表查询,显示多行
List<Student> getStuWithObj();
//传入对象数组
List<Student> getStuByAgeArray(Integer[] ages);
//传入list集合
List<Student> getStuByAgeArray2(List<Integer> ages);
//传入map集合
List<Student> getStuByMap(Map<String,Object> map);
//修改信息(使用trim标签)
int gaifen(@Param("xuefen")String xuefen,@Param("sname")String sname,@Param("sid")String sid);
//修改信息(使用set标签)
int gaifen1(@Param("xuefen")String xuefen,@Param("sid")String sid);
//查询信息(使用choose标签)
List<Student> getStuWhen(@Param("xuefen")String xuefen,@Param("zong")String zong);
//查询信息(使用where标签)
List<Student> getStuMH(@Param("min")String min,@Param("max")String max,@Param("name")String name,@Param("xuefen")String xuefen);
}
其中的@Param是注解,方便mapper文件引用传入的参数,#{}和${}都可以使用,但是不用这个注解,使用${}会报错,此时只能用#{}。