MyBatis映射器

MyBatis映射器

MyBatis映射器主要内容有:核心配置文件,SQL映射文件,级联查询;MyBatis的强大之处在于SQL映射文件的编写。

MyBatis的核心配置文件配置了许多影响MyBatis行为的信息,这些配置信息通常只会配置在一个文件中,不会轻易改变,另外MyBatis与Spring整合后,MyBatis的核心配置文件将配置到Spring配置文件中,因此,在实际开发中,开发者需要修改MyBatis核心配置文件的情况并不多。
注意:MyBatis核心配置文件中的元素配置顺序不能颠倒,一旦颠倒,MyBatis的启动阶段将会发生异常。

映射器是MyBatis最重要的组件,有一个接口和一个XML文件组成,SQL映射文件常用的配置元素有select,insert,update,delete,sql,resultMap等
select元素:查询语句,可以自定义参数,返回结果集等
insert元素:插入语句,执行后返回一个整数,代表插入的行数。
update元素:更新语句,执行后返回一个整数,代表更新的行数
delete元素:删除语句,执行后返回一个整数,代表删除的行数
sql元素:定义一部分SQL,在多个位置被引用。
resultMap元素:提供映射规则,从数据库结果集中加载对象

下面演示一个案例:
1-创建web应用并在web文件夹的WEB-INF下导入相关jar包,并将jar包添加为项目库。

在这里插入图片描述
2- 创建MySQL数据库spring,并在该数据库中创建表user,表中字段包括uid,usex,uname,并录入相关数据
在这里插入图片描述3-在src目录下创建com.po包,在该包中创建持久化类MyUser,该类中的字段与数据库user表中一致。

public class MyUser {
    public Integer uid ; //主键
    public String uname ;
    public String usex ;

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUsex() {
        return usex;
    }

    public void setUsex(String usex) {
        this.usex = usex;
    }
    @Override
    public String toString(){
        return "User [uid = " + uid + " uname = " + uname + " usex = " + usex + "]" ;
    }
}

4-在src目录下创建com.mybatis包,并在该包中创建SQL映射文件UserMapper.xml和MyBatis核心配置文件mybatis-config.xml
总结:select元素用于映射SQL的select语句,若要传递多个参数,可以使用Map对象传递多个参数,也可以使用JavaBean传递多个参数,insert元素用于SQL的插入语句,执行结果返回影响的行数,改元素有3个常用属性,分别为keyProperty:将插入或更新操作返回值赋值给PO的某个属性,keyColumn:设置哪一列是主键,userGeneratedKeys:获取数据库产生的主键,返回自增的字段作为主键,即主键回填;对于不支持主键回自动递增的数据库,例如Oracle,可以使用MyBatis的selectKey元素来自定义生成主键。使用update和delete映射SQL的更新和删除操作,对于结果集,可以使用Map对象或者POJO存储。
(1)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 = "com.dao.UserDao">
    <!--select元素用来映射SQL语句select语句,可以自定义结果和返回参数-->
    <!--根据uid查询一个用户信息-->
    <select id = "selectUserById" parameterType = "Integer" resultType = "com.po.MyUser">
        select * from user where uid = #{uid}
    </select>
    <!--查询王姓男性的用户信息,使用map对象传递多个参数-->
    <select id = "selectAllUser" resultType = "com.po.MyUser" parameterType = "map">
        select * from user
        where uname like concat('%',#{uname},'%')
        and usex = #{usex}
    </select>
    <!--查询王姓男性的用户信息,使用JavaBean传递多个参数-->
    <select id = "selectAllUser1" resultType = "com.po.MyUser" parameterType = "com.pojo.SelectUserParam">
        select * from user
        where uname like concat('%',#{uname},'%') and usex = #{usex}
    </select>
    <!--insert元素用于映射插入语句,MyBatis执行完一条插入语句将返回一个整数,表示其影响的行数-->
    <!--MySQL,SQL server等数据库可以采用自增主键的字段作为主键,有时候需要使用这个刚刚产生的主键,用于关联其它业务-->
    <!--添加一个用户,成功后将主键回填给uid-->
    <insert id = "addUser" parameterType = "com.po.MyUser" keyProperty = "uid" useGeneratedKeys="true">
        insert into user (uname,usex) values (#{uname}, #{usex})
    </insert>
    <!--如果在实际工程中不支持主键自动递增,例如Oracle,或者取消了主键自动递增的规则,可以使用MyBatis的selectKey元素自定义生成主键-->
    <insert id = "insertUser" parameterType = "com.po.MyUser">
        <!--先使用selectKey元素定义主键,然后再定义SQL语句,BEFORE是先产生主键,再执行SQL语句,keyProperty属性指定新生主键返回给po类-->
        <selectKey keyProperty="uid" resultType = "Integer" order = "BEFORE">
        <!--若最大的uid是空,则让1做为新的uid,若最大的uid非空,则让最大的uid+1作为新的uid-->
            select if(max(uid) is null, 1, max(uid) + 1) as newUid from user
        </selectKey>
        insert into user (uid, uname, usex) values(#{uid}, #{uname}, #{usex})
    </insert>
    <!--修改一个用户-->
    <update id = "updateUser" parameterType = "com.po.MyUser">
        update user set uname = #{uname}, usex = #{usex} where uid = #{uid}
    </update>
    <!--删除一个用户-->
    <delete id = "deleteUser" parameterType = "com.po.MyUser">
        delete from user where uid = #{uid}
    </delete>
    <!--sql元素的作用在于可以可以定义SQL语句的一部分,以方便后面的SQL引用它,例如仿佛使用的列名,在MyBatis只需使用sql元素编写依次,便能在其它元素中引用它-->
    <sql id ="comColumns"> uid, uname, usex </sql>
    <select id = "selectUser" resultType = "com.po.MyUser">
        select <include refid = "comColumns"/> from user
    </select>
    <!--使用Map存储结果集,查询所有用户信息存储到Map中-->
    <select id = "selectAllUserMap" resultType = "map">
        select * from user
    </select>
    <!--使用POJO存储结果集,使用自定义结果集类型-->
    <resultMap type = "com.pojo.MapUser" id = "MyResult">
        <!--property是com.pojo.MapUser类中的属性,column是查询结果的列名,可以来自不同的表,将数据表的列名映射到对应类的属性上-->
        <id property = "m_uid" column = "uid"/>
        <result property = "m_uname" column = "uname"/>
        <result property = "m_usex" column = "usex"/>
    </resultMap>
    <!--使用自定义结果集查询所有用户-->
    <select id="selectResultMap" resultMap = "MyResult">
        select * from user
    </select>

</mapper>

(2)MyBatis核心配置文件MyBatis-config.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>
    <!--告诉MyBatis映射文件的位置-->
    <mappers>
        <mapper resource = "com/mybatis/UserMapper.xml"/>
    </mappers>
</configuration>

5-在src目录下创建包com.dao,在该包中创建数据访问接口UserDao,此接口和UserMapper.xml组成映射器,在该接口中需要编写与映射文件id对应的接口方法,同时该接口需要使用@Mapper和@Repositirty注解.


import com.po.MyUser;
import com.pojo.MapUser;
import com.pojo.SelectUserParam;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;
//数据访问层的注解,表示该层交给Spring管理
@Repository
@Mapper
/**
 * Spring将指定包中使用@Mapper注解的接口自动装配为MyBatis的映射接口
 */
public interface UserDao {
    //接口方法与映射文件UserMapper.xml的id对应
    public MyUser selectUserById(Integer uid) ;
    //返回是List形式的MyUser类型数据,参数是map类型
    public List<MyUser> selectAllUser(Map<String,Object> param) ;
    //返回的是List形式的MyUser类型的数据,参数是普通Java类
    public List<MyUser> selectAllUser1(SelectUserParam param) ;
    //添加一个用户
    public Integer addUser(MyUser myUser) ;
    //添加用户
    public Integer insertUser(MyUser myUser) ;
    //修改用户信息
    public Integer updateUser(MyUser myUser) ;
    //删除用户信息
    public Integer deleteUser(MyUser myUser) ;
    //查询用户
    public List<MyUser> selectUser() ;
    //查询用户存储到Map中
    public List<Map<String,Object>> selectAllUserMap() ;
    //查询用户存储到POJO中
    public List<MapUser> selectResultMap() ;

}

6-在src目录下创建日志文件log4j.properties,保证在控制台输出

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

7-为了使用JavaBean传递多个参数和使用POJO方式存储结果集,在src目录下创建包com.pojo,在该包中创建类SelectUserParam和MapUser
SelectUserParam类:

public class SelectUserParam {
    private String uname ;
    private String usex ;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUsex() {
        return usex;
    }

    public void setUsex(String usex) {
        this.usex = usex;
    }
}

MapUser 类:

public class MapUser {
    private Integer m_uid ;
    private String m_uname ;
    private String m_usex ;

    public Integer getM_uid() {
        return m_uid;
    }

    public void setM_uid(Integer m_uid) {
        this.m_uid = m_uid;
    }

    public String getM_uname() {
        return m_uname;
    }

    public void setM_uname(String m_uname) {
        this.m_uname = m_uname;
    }

    public String getM_usex() {
        return m_usex;
    }

    public void setM_usex(String m_usex) {
        this.m_usex = m_usex;
    }
    public String toString(){
        return "User [uid = " + m_uid + " uname = " + m_uname + " usex = " + m_usex + "]" ;
    }
}

8-在src目录下创建包com.controller,在该报中创建类UserController,在该类中调用数据访问接口的方法。


import com.dao.UserDao;
import com.po.MyUser;
import com.pojo.MapUser;
import com.pojo.SelectUserParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
//控制层的注解,表示该层交给Spring管理
@Controller
public class UserController {
    @Autowired //依赖注入,将数据访问层注入到控制层,不用自己new,实现控制翻转
    public UserDao userDao ;
    public void test(){
        MyUser myUser = userDao.selectUserById(1) ;
        System.out.println(myUser) ;
        //利用map对象传递多个参数
        Map<String,Object> param = new HashMap<>() ;
        param.put("uname", "王") ;
        param.put("usex", "男") ;
        List<MyUser> myUser1 = userDao.selectAllUser(param) ;
        for(MyUser user1 : myUser1){
            System.out.println(user1) ;
        }
        //利用JavaBean传递多个参数
        SelectUserParam param1 = new SelectUserParam() ;
        param1.setUname("王") ;
        param1.setUsex("男") ;
        List<MyUser> myUser2 = userDao.selectAllUser1(param1) ;
        for(MyUser user2 : myUser2){
            System.out.println(user2) ;
        }
        //添加一个用户,主键回填(自动递增)
        MyUser myUser3 = new MyUser() ;
        myUser3.setUname("陈恒") ;
        myUser3.setUsex("男") ;
        int add = userDao.addUser(myUser3) ;
        System.out.println("添加了" + add + "条记录") ;
        System.out.println("添加记录的主键是" + myUser3.getUid()) ;
        //自定义主键
        MyUser myUser4 = new MyUser() ;
        myUser4.setUname("张国庆") ;
        myUser4.setUsex("男") ;
        int number = userDao.insertUser(myUser4) ;
        System.out.println("插入了" + number + "条记录") ;
        System.out.println("插入记录的主键是" + myUser4.getUid()) ;
        //修改一个用户
        MyUser myUser5 = new MyUser() ;
        myUser5.setUid(3) ;
        myUser5.setUname("李沁") ;
        myUser5.setUsex("女") ;
        int number1 = userDao.updateUser(myUser5) ;
        System.out.println("修改了" + number1 + "条记录") ;
        System.out.println("修改记录的主键为" + myUser5.getUid()) ;
        //删除一个用户
        MyUser myUser6 = new MyUser() ;
        myUser6.setUid(1) ;
        int number2 = userDao.deleteUser(myUser6) ;
        System.out.println("删除了" + number2 + "条记录") ;
        //查询用户
        List<MyUser> myUsers = userDao.selectUser() ;
        for(MyUser myUser7 : myUsers){
            System.out.println(myUser7) ;
        }
        //查询用户信息,用Map存储结果,多个Map对象存储到List中
        /**
         * Map中的key是select语句查询的字段名,而Map的value是查询结果中字段对应的值,
         * 一条记录映射到一个Map对象,多个记录则将多个Map对象存储到List中
         */
        List<Map<String,Object>> map = userDao.selectAllUserMap() ;
        for(Map<String,Object> map1 : map){
            System.out.println(map1) ;
        }
        //查询所有用户信息,将结果存储到POJO中
        List<MapUser> list = userDao.selectResultMap() ;
        for(MapUser list1 : list){
            System.out.println(list1) ;
        }

    }
}

9-在src目录下创建spring配置文件applicationContext.xml,配置相关信息,配置数据库信息,扫描包信息,事务管理等。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--指定需要扫描的包,是注解生效-->
    <context:component-scan base-package="com.dao"/>
    <context:component-scan base-package="com.controller"/>
    <!--配置数据源-->
    <bean id = "dataSource" class = "org.apache.commons.dbcp2.BasicDataSource">
        <!--配置数据库驱动-->
        <property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
        <!--配置连接数据库的url-->
        <property name = "url" value = "jdbc:mysql://localhost:3306/spring?characterEncoding=utf8"/>
        <!--连接数据库的用户名-->
        <property name = "username" value = "root"/>
        <!--连接数据库的密码-->
        <property name = "password" value = "123456"/>
        <!--最大连接数-->
        <property name = "maxTotal" value = "30"/>
        <!--最大空闲连接数-->
        <property name = "maxIdle" value = "10"/>
        <!--初始化最大连接数-->
        <property name = "initialSize" value = "5"/>
    </bean>
    <!--添加事务支持-->
    <bean id = "txManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name = "dataSource" ref = "dataSource"/>
    </bean>
    <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="txManager"/>
    <!--配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合-->
    <bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean">
        <property name = "dataSource" ref = "dataSource"/>
        <!--configLocation的属性值为MyBatis的核心配置文件-->
        <property name = "configLocation" value = "classpath:com/mybatis/mybatis-config.xml"/>
    </bean>
    <!--Mapper代理开发,使用Spring自动扫描MyBatis接口并装配,Spring将指定包中的所有被@Mapper注解过的接口自动装配为MyBatis的映射接口-->
    <bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--mybatis-spring的组件扫描器-->
        <property name = "basePackage" value = "com.dao"/>
        <property name = "sqlSessionFactoryBeanName" value = "sqlSessionFactory"/>
    </bean>
</beans>

10-在com.controller包中创建测试类TestController,完成测试。

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestController {
    public static void main(String[] args){
        //初始化Spring容器,加载配置文件
        ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml") ;
        //获取目标对象的实例
        UserController uc = (UserController) appCon.getBean("userController") ;
        uc.test() ;
    }
}

11-测试结果如下:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值