zoukankan      html  css  js  c++  java
  • Mybatis入门-02-增删改查及配置(属性、别名、映射器)

    一、 前言

    一切当以官方文档为基准。

    参考视频狂神说Java-Mybatis

    本文之前的操作步骤:Mybatis入门-第一个程序

    前置内容:

    • Java
    • maven
    • MySQL
    • JDBC
    • JavaWeb中持久化层的一些知识,如POJO

    环境:

    • Java11
    • IDEA 2019.3.3
    • MySQL8
    • mybatis3

    路径:

    image-20200910112335563

    代码

    UserMapper:

    package com.duzhuan.dao;
    
    import com.duzhuan.pojo.User;
    
    import java.util.List;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/9 19:42
     * @Version: 1.0
     * @since: jdk11
     */
    public interface UserMapper {
        List<User> getUserList();
    }
    
    

    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">
    <mapper namespace="com.duzhuan.dao.UserMapper">
        
        <resultMap id="UserMap" type="com.duzhuan.pojo.User">
            <result column="pwd" property="password"/>
        </resultMap>
        
        <select id="getUserList" resultMap="UserMap">
            select * from mybatis.user
        </select>
    </mapper>
    

    User:

    package com.duzhuan.pojo;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/9 14:11
     * @Version: 1.0
     * @since: jdk11
     */
    public class User {
        private int id;
        private String name;
        private String password;
    
        public User() {
        }
    
        public User(int id, String name, String password) {
            this.id = id;
            this.name = name;
            this.password = password;
        }
    
    	/*getter and setter*/
        
        /*toString*/
    }
    
    

    MybatisUtils:

    package com.duzhuan.utils;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/9 21:38
     * @Version: 1.0
     * @since: jdk11
     */
    public class MybatisUtils {
    
        private static SqlSessionFactory sqlSessionFactory;
    
        static {
            try {
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession();
        }
    }
    
    

    二、增删改查

    1.通过id查询用户

    Usermapper:

    package com.duzhuan.dao;
    
    import com.duzhuan.pojo.User;
    
    import java.util.List;
    
    /**
     * @Autord: HuangDekai
     * @Date: 2020/9/9 19:42
     * @Version: 1.0
     * @since: jdk11
     */
    public interface UserMapper {
        List<User> getUserList();
    
        //------------ 新增的语句 --------------------
        User getUserById(int id);
        //------------------------------------------
    }
    
    

    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">
    <mapper namespace="com.duzhuan.dao.UserMapper">
        
        <resultMap id="UserMap" type="com.duzhuan.pojo.User">
            <result column="pwd" property="password"/>
        </resultMap>
        
        <select id="getUserList" resultMap="UserMap">
            select * from mybatis.user
        </select>
        
    <!--================新增的语句=================-->
        <select id="getUserById" parameterType="int" resultMap="UserMap">
            select * from mybatis.user where id = #{id}
        </select>
    <!--=========================================-->
        
    </mapper>
    
    

    paramterType中写的是getUserById这个方法的参数的数据类型,但是深究下去的话可以知道,在这里并不区分大小写,而且涉及到别名,这里暂时只用知道这里的int其实对应的是Integer。具体可看Mybatis3-设置-类型别名中的类型别名(typeAliases)。同时,parameterType只能填入一个数据类型,因此,对应的Mapper中的方法显然只能有一个输入参数。

    #{id}#{}是取参数的一种方式,id即在Mapper中传入的参数的名字。

    image-20200910231057781

    Mybatis里有#{}${}两种取值方式 ,前者类似于JDBC中的PrepareStatement,而${}则更像是字符串拼接,会导致SQL注入。

    在UserMapperTest里添加的测试样例:

        @Test
        public void getUserByIdTest(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = mapper.getUserById(1);
            System.out.println(user);
    
            sqlSession.close();
        }
    

    image-20200910225613507

    2.模糊查询

    在UserMapper添加:

    List<User> getUserListByName(String name);
    

    在UserMapper.xml的根标签里添加:

        <select id="getUserListByName" parameterType="String" resultMap="UserMap">
            select * from mybatis.user where name like concat('%',#{name},'%')
        </select>
    

    concat可以较为方便地实现模糊查询

    测试样例:

        @Test
        public void getUserListByNameTest(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = mapper.getUserListByName("a");
            for (User user : userList) {
                System.out.println(user);
            }
    
            sqlSession.close();
        }
    

    结果:

    image-20200911000710083

    3.分页查询

    分页查询的目的就是为了减少数据的处理量

    UserMapper中添加方法:

    List<User> getUserListLimit(Map<String,Integer> map);
    

    UserMapper.xml的根标签中添加:

        <select id="getUserListLimit" parameterType="map" resultMap="UserMap">
            select * from mybatis.user limit #{startIndex},#{pageSize}
        </select>
    

    UserMapperTest中添加测试样例:

        @Test
        public void getUserListLimitTest(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            Map<String, Integer> map = new HashMap<>();
            map.put("startIndex",0);
            map.put("pageSize",3);
            List<User> userListLimit = mapper.getUserListLimit(map);
            for (User user : userListLimit) {
                System.out.println(user);
            }
            sqlSession.close();
        }
    
    

    输出结果:

    这里可以看出使用Map作为参数的方便之处,因为从理论上讲,一个Map就可以解决所有的输入参数。但是Map对于维护来讲实在是个灾难,因此,在有条件的情况下,尽量使用实体类作为输入参数吧。

    4.增删改

    在Mybatis中,若mybatis-config.xml中配置的transactionManager标签的type是JDBC,那么事务自动提交默认是关闭的。

    如果要增删改,就要使用sqlSession.commit()方法提交修改才能持久化。

    4.1 增

    UserMapper中增加:

    int addUser(User user);
    

    insert语句会返回一个int值表示改变的行数,因此该方法设置了返回值数据类型为int。

    UserMapper.xml的根标签里增加:

        <insert id="addUser" parameterType="com.duzhuan.pojo.User">
            insert into mybatis.user(`id`,`name`,`pwd`) value (#{id},#{name},#{password})
        </insert>
    

    这里使用的不再是<select>标签,而是insert。但是id依旧是UserMapper里对应的方法的的方法名。可以看到,UserMapper中该方法传入的参数是一个实体类,不是基本类型,我们也没有对其设置别名,因此parameterType输入的应该是该实体类的全限定名称。

    仔细观察可以发现,SQL语句里用的并非是User.getId,而是直接使用了实体类里属性的属性名。

    image-20200911002953710

    测试样例:

        @Test
        public void addUserTest(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = new User(6, "Gala", "123456");
            int updateLine = mapper.addUser(user);
            if (updateLine>0){
                System.out.println("Add user ------>"+user);
                sqlSession.commit();
            }
            else{
                System.out.println("Failed");
            }
            sqlSession.close();
        }
    

    结果:

    image-20200911003817566

    image-20200911003834074

    4.2 删

    UserMapper中添加方法:

    int delUserById(int id);
    

    UserMapper.xml的根标签里添加:

        <delete id="delUserById" parameterType="int">
            delete from mybatis.user where id = #{id};
        </delete>
    

    与增加基本一致,只是换成了<delete>标签。

    测试样例:

        @Test
        public void delUserByIdTest(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            int id = 6;
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User userById = mapper.getUserById(id);
            int updateLine = mapper.delUserById(id);
            if (updateLine>0){
                System.out.println("Del user -------->"+userById);
                sqlSession.commit();
            }
            else{
                System.out.println("Failed");
            }
    
            sqlSession.close();
        }
    

    image-20200911090023532

    image-20200911090037762

    4.3 改

    UserMapper中添加方法:

        int updateUser(User user);
    

    UserMapper.xml的根标签里添加:

        <update id="updateUser" parameterType="com.duzhuan.pojo.User">
            update mybatis.user set `name` = #{name}, `pwd` = #{password} where `id` = #{id}
        </update>
    

    与增、删的操作基本一致,只是使用<update>标签。

    测试样例:

        @Test
        public void updateUserTest(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = new User(5, "bin", "123456");
            User oldUser = mapper.getUserById(user.getId());
    
            int updateLine = mapper.updateUser(user);
    
            if (updateLine > 0){
                System.out.println("Update User from:");
                System.out.println(oldUser);
                System.out.println("to");
                System.out.println(user);
                sqlSession.commit();
            }
            else{
                System.out.println("Failed");
            }
            sqlSession.close();
        }
    

    结果:

    image-20200911093109559

    image-20200911093147992

    三、配置

    1.properties

    官方文档-XML配置-属性

    这是之前写的配置文件(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>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8&amp;serverTimezone=UTC"/>
                    <property name="username" value="root"/>
                    <property name="password" value="qq123456"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper class="com.duzhuan.dao.UserMapper"></mapper>
        </mappers>
    </configuration>
    
    

    property的属性可以在外部配置,并可以进行动态替换,有利于解耦。

    例如将连接数据库的配置放到外部:

    image-20200911114632355

    db.properties代码:

    driver = com.mysql.jdbc.Driver
    url = jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC
    username = root
    password = qq123456
    

    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>
    	<!--=====================add=========================-->
        <properties resource="db.properties"></properties>
    	<!--==============================================-->
        
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <!--================update=================-->
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                     <!--=================================-->
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper class="com.duzhuan.dao.UserMapper"></mapper>
        </mappers>
    </configuration>
    
    

    部分环境中可能出现xml中有中文注释不能运行的问题。注意顺序,在XML里标签前后顺序不能改变,即<properties>必须在<environments>前。

    由于是Maven项目,因此propertiesresource的值可以直接写文件名。另外,根据官方文档也可以给出这样的例子:

    <properties resource="org/mybatis/example/config.properties">
      <property name="username" value="user"/>
      <property name="password" value="qq123456"/>
    </properties>
    

    甚至也可以在 SqlSessionFactoryBuilder.build() 方法中传入属性值。

    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);
    
    // ... 或者 ...
    
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);
    

    官方文档给出了优先级:

    如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:

    • 首先读取在 properties 元素体内指定的属性。
    • 然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
    • 最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。

    因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。

    建议尽量只使用一种方式。

    再次运行测试样例,运行通过就没问题了。

    这里运行了getUserListTest()获取结果:

    image-20200911120046527

    可以正常运行。

    2.别名

    官方文档-mybatis-配置-类型别名

    下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

    别名 映射的类型
    _byte byte
    _long long
    _short short
    _int int
    _integer int
    _double double
    _float float
    _boolean boolean
    string String
    byte Byte
    long Long
    short Short
    int Integer
    integer Integer
    double Double
    float Float
    boolean Boolean
    date Date
    decimal BigDecimal
    bigdecimal BigDecimal
    object Object
    map Map
    hashmap HashMap
    list List
    arraylist ArrayList
    collection Collection
    iterator Iterator

    上面是Mybatis默认有的类型别名。建立自己的类型别名可以使用注解(不利于维护,不推荐),这里不介绍。下面是使用XML配置类型别名,将com.duzhuan.pojo.User别名设置为User使用:

    修改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>
    
        <properties resource="db.properties"></properties>
     
        <!--=====================add======================-->
        <typeAliases>
            <typeAlias type="com.duzhuan.pojo.User" alias="User"></typeAlias>
        </typeAliases>
        <!--==============================================-->
        
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <mapper class="com.duzhuan.dao.UserMapper"></mapper>
        </mappers>
    </configuration>
    
    

    那么,在这个配置文件中注册的Mapper(这里即com.duzhuan.dao.UserMapper)可以将User作为com.duzhuan.pojo.User使用。

    修改UserMapper中带有com.duzhuan.pojo.User的项为User

    <?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.duzhuan.dao.UserMapper">
        
        <resultMap id="UserMap" type="User">
            <result column="pwd" property="password"/>
        </resultMap>
    
        <select id="getUserList" resultMap="UserMap">
            select * from mybatis.user
        </select>
    
        <select id="getUserById" parameterType="int" resultMap="UserMap">
            select * from mybatis.user where id = #{id}
        </select>
        
        <select id="getUserListByName" parameterType="String" resultMap="UserMap">
            select * from mybatis.user where name like concat('%',#{name},'%')
        </select>
    
        <insert id="addUser" parameterType="User">
            insert into mybatis.user(`id`,`name`,`pwd`) value (#{id},#{name},#{password})
        </insert>
    
        <delete id="delUserById" parameterType="int">
            delete from mybatis.user where id = #{id};
        </delete>
    
        <update id="updateUser" parameterType="User">
            update mybatis.user set `name` = #{name}, `pwd` = #{password} where `id` = #{id}
        </update>
    </mapper>
    
    

    这里再次用getUserListTest去测试:

    image-20200911130818443

    结果一致。

    官方文档中还有使用<package>的,类似于下面:

        <typeAliases>
            <package name="com.duzhuan.pojo"/>
        </typeAliases>
    

    这样就能直接把包内的所有类的类名作为别名。但是这样的话别名就只能是类名,而<typeAliase>可以用alias属性命名别的名字。

    3.映射器

    mybatis官方文档-设置-映射器

    映射器,即mappers。

    我们在上面将UserMapper绑定的操作使用的是使用映射器接口实现类的完全限定名:

        <mappers>
            <mapper class="com.duzhuan.dao.UserMapper"></mapper>
        </mappers>
    

    这种方式要求:

    • Mapper与其对应的Mapper.xml同名
    • Mapper于其对应的Mapper.xml在同一目录

    image-20200911140208072

    其余方法观看官方文档即可,对于下面这种方式不推荐使用:

    <!-- 使用完全限定资源定位符(URL) -->
    <mappers>
      <mapper url="file:///var/mappers/AuthorMapper.xml"/>
      <mapper url="file:///var/mappers/BlogMapper.xml"/>
      <mapper url="file:///var/mappers/PostMapper.xml"/>
    </mappers>
    
  • 相关阅读:
    设备坐标与逻辑坐标
    4个设备上下文DC
    VC6.0智能提示消失恢复
    VC
    JavaWeb_设置Cookie的作用路径
    JavaWeb_Cookie显示最近浏览的商品
    JavaWeb_Cookie
    MVC案例——通过配置切换底层存储源
    MVC案例——修改用户
    MVC案例——删除操作
  • 原文地址:https://www.cnblogs.com/duzhuan/p/13651417.html
Copyright © 2011-2022 走看看