JobPlus知识库 IT 软件开发 文章
Mybatis进阶教程

新建项目,基本环境都如上篇,Maven的pom.xml中添加jUnit依赖。

Insert获取主键的值

Mapper.xml的Insert节点添加useGeneratedKeys,keyProperty即可。

KeyProperty:(仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

UseGeneratedKeys:仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的。

修改内容为下:

   <insert id="insertBlog" parameterType="Blog"            keyProperty="id"            useGeneratedKeys="true"    >        INSERT INTO Blog (id,title) VALUES (#{id},#{title})    </insert>

此时数据库内容:

程序运行前数据库内容

测试程序:

@Test    public void test1(){        InputStream inputStream = null;        SqlSession sqlSession = null;        try {            inputStream = Resources.getResourceAsStream("mybatis-config.xml");            SqlSessionFactory mSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);            sqlSession = mSqlSessionFactory.openSession();            Blog blog = new Blog("获取主键的值");            sqlSession.insert("me.aihe.dao.BlogMapper.insertBlog",blog);            // 检测是否将插入数据的主键返回            System.out.println(blog.getId());            sqlSession.commit();        } catch (IOException e) {            e.printStackTrace();        } finally {            if (sqlSession != null) {                sqlSession.close();            }        }    }

运行结果

运行结果

运行程序之后数据库内容

注意:还有一种实现方式是在insert内部添加<SelectKey>节点,这里就不再演示。

SQL映射文件参数分析

在Mapper.xml文件中,SQL语句里我们可以传入对象,或传入其它参数。
当我们以如下方式传递参数时:

 // 这是在UserMapp.java文件  int insertByParam(int id,String name, String email); //UserMapper.xml文件中    <insert id="insertByParam">        INSERT INTO User (id,name,email) VALUE (#{id},#{name},#{email})    </insert>

测试程序如下:

@Test    public void test2(){        InputStream inputStream = null;        SqlSession sqlSession = null;        try {            inputStream = Resources.getResourceAsStream("mybatis-config.xml");            SqlSessionFactory mSqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);            sqlSession = mSqlSessionFactory.openSession();            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);            userMapper.insertByParam(2,"Gao","gao@gmail.com");            sqlSession.commit();        } catch (IOException e) {            e.printStackTrace();        } finally {            if (sqlSession != null) {                sqlSession.close();            }        }    }

这个时候程序运行会出现如下错误,提示我们找不到参数。

### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg2, arg1, arg0, param3, param1, param2]解决方法:四种任选其一

  • 修改UserMapp.java文件添加@Param注解,即可

int insertByParam(@Param("id") int id,@Param("name") String name, @Param("email") String email);

  • 修改UserMapper.xml文件,修改为param*类型如下

   <insert id="insertByParam"  >        INSERT INTO User (id,name,email) VALUE (#{param1},#{param2}, #{param3})    </insert>

  • 将参数换为对象,如下

// UserMapper.java修改为如下    int insertByPoDo(User user);//UserMapper.java修改为下   <insert id="insertByPoDo"        parameterType="User"    >        INSERT INTO User (name,email) VALUE (#{name},#{email})    </insert>//Test文件修改为如下    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    User user = new User("leishen","Rxlen@126.com");    userMapper.insertByPoDo(user);

  • 将参数转为Map对象。

    int insertByMap(Map<String,Object> map);//xml      <insert id="insertByMap">          INSERT INTO User (name,email) VALUE (#{name},#{email})      </insert>//Test            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);            HashMap<String,Object> map = new HashMap<String, Object>();            map.put("name","test");            map.put("email","test@qq.com");            userMapper.insertByMap(map);            sqlSession.commit();

一般来说,模型与业务相关传入POJO对象,与业务无关就传入Map对象。
注意:关于参数封装原理部分请查看MapperMethod.java,ParamNameResolve.java

SQL语句中$与#的区别

默认情况下,使用#{}格式的语法会导致 MyBatis 创建预处理语句属性并安全地设置值(比如?)。这样做更安全,更迅速,通常也是首选做法,不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用:

ORDER BY ${columnName}

这里 MyBatis 不会修改或转义字符串。
注意:** 以这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。**

$是字符串替换,#会进行预编译

获取列表数据// UserMapper接口    List<User> getUserByEmail(@Param("email") String email);// UserMaper.xml    <select id="getUserByEmail" resultType="me.aihe.dao.User">        SELECT * FROM User WHERE email LIKE #{email}    </select>//测试文件   UserMapper userMapper = sqlSession.getMapper(UserMapper.class);   List<User> result = userMapper.getUserByEmail("aihe%");   System.out.println(result);

最终输出内容

获取列表数据结果

获取Map数据//UserMapeer接口文件    Map<String,Object> getUserMapById(@Param("id") Integer id);//UserMapper.xml文件    <select id="getUserMapById" resultType="java.util.Map">        SELECT * FROM User WHERE id = #{id}    </select>//测试程序    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    Map result = userMapper.getUserMapById(2);    System.out.println(result);

测试输出结果获取Map数据结果

获取Map映射的多组数据

这个和获取列表很类似了,只不过把数组都封装到一个Map中去了

// UserMapper接口文件    @MapKey("id")    Map<Integer,User> getUserMapLikeemail(@Param("email") String email);// UserMapper.xml文件    <select id="getUserMapById" resultType="java.util.Map">        SELECT * FROM User WHERE id = #{id}    </select>// 测试文件    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    Map result = userMapper.getUserMapLikeemail("%aihe%");    System.out.println(result);

程序输出获取Map映射的多组数据

**注意: 注解@MapKey指定的是以数据库表中的那一列作为Map结果的key。

使用ResultMap来映射结果数据// UserMapper接口    User getUserMapByIdThroughResultMap(@Param("id") Integer id); // UserMapper.xml文件    //Id标识的是查询结果中的主键是那一列,对应的User属性是什么    <resultMap id="MyResultMap" type="User">        <id column="id" property="id" />            <result property="email" column="email" />        <result property="name" column="name" />    </resultMap>    <select id="getUserMapByIdThroughResultMap" resultMap="MyResultMap">        SELECT * FROM User WHERE id = #{id}    </select>//测试文件   UserMapper userMapper = sqlSession.getMapper(UserMapper.class);   User user = userMapper.getUserMapByIdThroughResultMap(2);   System.out.println(user);

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
391人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序