Mybatis学习

本文详细介绍MyBatis框架的高级特性,包括配置文件解析、动态SQL、一对一及一对多关系映射等,帮助开发者更好地理解和应用MyBatis。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值