Mybatis
一、依赖jar包:log4g,mybatis,数据库连接包
二、配置文件
<?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="db.properties"></properties>
<!-- 别名,之后在实体类的xml文件中,ResultType,parameterType等可以直接填写对应别名 -->
<typeAliases>
<!-- 手动指定别名 -->
<typeAlias type="com.xxx.entity.User" alias="User"/>
<!-- entity包下的实体类会自动配置别名,别名就是类名 -->
<package name="com.xxx.entity"/>
</typeAliases>
<!-- 配置连接数据库的各项配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
</transactionManager>
<dataSource type="UNPOOLED">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 每个实体类对应的映射文件只有注册了才能使用 在mappers中注册 -->
<mappers>
<mapper resource="com/xxx/entity/User.xml" />
</mappers>
</configuration>
除了Configuration之外还要配置log4g.properties
log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=INFO
在实体类的xml文件中秩序配置好相应的sql语句,就可直接在方法中调用
例如:
<?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="User">
<select id="selectAll" resultType="User">
select * from user
</select>
</mapper>
注意:这里的resultType由于配置了别名,所以可以直接填写类名。同时使用resultType还需要一个前提条件,那就是实体类的属性名必须和数据库对应字段保持一致。
实体类xml中配置sql语句需要注意使用语句对应的标签。select语句使用select标签,update语句使用update标签等等。
配置语句时,如果sql语句中需要用到参数,需要配置parameterType,这里的类型要和方法中传来的类型一致,之后可以在语句中使用#{}EL表达式获取值
例如:
<select id="selectByMap" parameterType="Map" resultType="com.lanou.entity.User">
select * from user
where userName = #{username}
and password = #{password}
</select>
select多条件查询:
在使用之前的sql查询中,进行多条件查询一般需要进行参数的判断以及语句的拼接,在mybatis中,只需要使用where标签和if标签就可以自动实现sql的语句拼接。
<select id="selectByIf" parameterType="User" resultType="User">
select * from user
<where>
<if test="username !=null">
userName = #{username}
</if>
<if test="password != null">
password = #{password}
</if>
</where>
</select>
if语句中的test判断:如果test中的值为真,则拼接if中的语句,为假则不拼接。
update语句中的自动拼接参数:
当不确定update语句中的参数个数时,可以使用<set>标签和<if>标签一起来实现参数的拼接
<update id="updataUser" parameterType="User">
update user
<!-- set标签会自动去除最后的逗号 -->
<set>
<if test="username != null">
username = #{username},
</if>
<if test="password != null">
password = #{password},
</if>
</set>
where
id = #{id}
</update>
当拼接结束后,set标签会自动取出最后的逗号,使语句正确。
逻辑删除:
一般在开发中,数据库中的数据在删除时采用逻辑删除,逻辑删除就是给数据添加一个删除状态值,查询时要根据删除状态的默认值进行查询。这样执行删除时修改删除状态值就可以完成删除,数据不会被删除,在用户角度来说数据已经被删除。
<!-- 逻辑删除方法 -->
<update id="deleteUser" parameterType="User">
update user
set
deleteId = 1
where
id = #{id}
</update>
模糊查询:
mybatis中在使用模糊查询时,如果是用#{}获取参数,不能直接在sql语句上拼接%(_),需要在传参时在参数中拼接完%(_)后在传入到sql语句中。或者使用${}来进行字符串的拼接,这时,可以直接在sql语句上拼接%,但是不能忘记单引号
例如:
<select id="selectByLikeName" parameterType="User" resultType="User">
select
<include refid="baseUserInfo"></include>
from user
<where>
<!-- 参数中进行%的拼接 -->
username like #{}
</where>
</select>
<select id="selectByLikeName" parameterType="User" resultType="User">
select
<include refid="baseUserInfo"></include>
from user
<where>
<!-- 使用${}和%在sql语句中进行拼接 -->
username like '%${}%'
</where>
</select>
除了这两种方法,还可以使用<bind>标签进行拼接
<select id="selectByLikeName" parameterType="User" resultType="User">
select * from user
<where>
username like
<bind name="likename" value="'%' +username+'%'"/>
#{likename}
</where>
</select>
使用foreach标签对传入的集合参数进行遍历拼接
<select id="selectByList" resultType="User">
select * from user
<where>
<foreach collection="list" item="item" separator="," open="teacher_id in (" close=")" >
#{item}
</foreach>
</where>
</select>
上面说了使用resultType的方式来将查询结果封装到对象中,但是这种方式在使用上有局限性,就是必须保证对象属性名和字段名一致,这时,我们可以使用resultMap来进行实体类和表字段的映射,从而解决这种问题
<resultMap type="Teacher" id="basicMap">
<id property="teacherId" column="teacher_id"/>
<result property="teacherName" column="teacher_name"/>
</resultMap>
<select id="selectByMap" resultMap="basicMap">
select * from teacher
</select>
mybatis中的多关系映射
一对一(方式一):
<resultMap type="Student" id="oneToOne">
<id property="studentId" column="stuid"/>
<result property="studentName" column="stuName"/>
<association property="teacher" javaType="Teacher">
<id property="teacherId" column="teacher_id"/>
<result property="teacherName" column="teacher_name"/>
</association>
</resultMap>
<select id="selectOneToOne" resultMap="oneToOne">
select * from student s
left join teacher t on
s.teacher_id = t.teacher_id
</select>
在resultMap使用association标签表示该对象中的对象属性,javaType中填写的是这个属性的类型,在这个标签中使用子标签配置属性对象的映射关系。
一对一(方式二):
<resultMap type="Student" id="findOneToOne">
<id property="studentId" column="stuid"/>
<result property="studentName" column="stuName"/>
<association property="teacher" column="teacher_id" javaType="Teacher" select="findTeacher"></association>
</resultMap>
<select id="findOneToOne" resultMap="findOneToOne">
select * from student
</select>
<resultMap type="Teacher" id="TeacherMap">
<id property="teacher_id" column="teacherer_id"/>
<result property="teacherName" column="teacher_name"/>
</resultMap>
<select id="findTeacher" parameterType="int" resultMap="TeacherMap">
select * from teacher
where teacher_id = #{_parameter}
</select>
这种方式配置的一对一是一种嵌套查询,在查询出一个student实例后,由于<association>中配合了select,会自动去查询select中的方法,调用这个方法的时候还会传入参数,参数就是<association>的column的值。
一对多:
实现一对多映射需要在类上设置好对应的对象集合属性,然后在映射文件的resultMap中通过collection标签进行配置。
配置的方式有两种:
一种是通过链表查询直接将两张表的数据查询出来,然后将副表的字段在collection标签内进行映射,此时需要设置使用哪个类的对象来接收对应结果集字段,设置不再使用association中使用的javaType,而是使用ofType。
另一种方式是通过collection标签设置select属性和column属性,在对本条记录进行映射时,会以column属性的值为参数进行子查询,并将子查询的结果集映射成我们的实体类对象。组装成集合后再赋值到对应的睡醒上,完成一条记录的映射后循环进行下一条记录的组装。
方式一:
<resultMap type="Student" id="selectOneToMany">
<id property="studentId" column="student_id"/>
<result property="studentName" column="stuName"/>
<collection property="projects" ofType="Project">
<id property="projectId" column="project_id" />
<result property="projectName" column="project_name"/>
</collection>
</resultMap>
<select id="selectOneToMany" resultMap="selectOneToMany">
select * from student s
left join project p on s.stuid = p.student_id
</select>
方式二:
<resultMap type="Student" id="oneToMany2">
<id property="studentId" column="stuid"/>
<result property="studentName" column="stuName"/>
<collection property="projects" column="stuid" ofType="Project" select="selectProject"></collection>
</resultMap>
<select id="selectOneToMany2" resultMap="oneToMany2">
select * from student
</select>
<resultMap type="Project" id="projectMap">
<id property="projectId" column="project_id"/>
<result property="projectName" column="project_name"/>
</resultMap>
<select id="selectProject" parameterType="int" resultMap="projectMap">
select * from
project
where
student_id = #{_parameter}
</select>
多对多查询:
多对多关系要使用一个中间表来维护量表的外键,查询时使用三表查询
<resultMap type="Product" id="manyToMany">
<id property="proId" column="pro_id"/>
<result property="proName" column="pro_name"/>
<collection property="employees" ofType="Employee">
<id property="empId" column="emp_id"/>
<result property="empName" column="emp_name"/>
</collection>
</resultMap>
<select id="selectManyToMany" resultMap="manyToMany">
SELECT * from
employee e,product p,employee_product
where p.pro_id = employee_product.pro_id
and employee_product.emp_id = e.emp_id
</select>