MyBatis学习系列(二)--------入门程序

前言

    在了解了JDBC的不足之后,我们来进行MyBatis的学习。

正文

java工程独立使用mybatis

我们先来使用原生的java结合mybatis操作数据库,依然是前一篇博文中创建的user表,我们使用mybatis通过uid来查找一个用户。
首先我们创建一个java工程,并且将mybatis的相关jar引入:
这里写图片描述
通过上一篇文章的架构图,我们可以看到,mybatis的最上层是sqlmapconfig文件,因此我们来创建一个配置文件SqlMapConfig.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>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理-->
            <transactionManager type="JDBC" />
        <!-- 数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/jdbc?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="sqlmap/User.xml"/>
    </mappers>
</configuration>

除此之外,我们还应该建立一个实体类pojo,对应数据库中的user表:

package com.mybatis.po;

public class User {

    private int uid;

    private String username;

    private String password;

    public int getUid() {
        return uid;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User [uid=" + uid + ", username=" + username + ", password=" + password + "]";
    }


}

接下来,我们在classpath目录下创建一个sqlmap文件夹,并在里面新建一个User.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="mybatis">
    <select id="findUserById" parameterType="int" resultType="com.mybatis.po.User">
        select * from user where uid = #{id}
    </select>
</mapper>

在这个文件中,有个namespace,这个是每个映射文件的命名空间。
按照文件的类型,在SqlMapConfig.xml中是要加载这个User.xml文件的,我已经在上面的代码中加载过了:

    <mappers>
        <mapper resource="sqlmap/User.xml"/>
    </mappers>

注意,在User.xml文件中,我们写了一个select标签,这个标签中有自定义的sql语句,在这个标签中:
- parameterType:定义输入到sql中的参数类型.
- #{id}表示使用preparedstatement设置占位符号,并将输入变量id输入到sql中。
- resultType:定义结果映射类型,即sql语句执行结果的类型,在这里我们使用了User对象来接受查询的结果,mybatis会将查询结果自动封装到User对象中去。
接下来我们来测试一下这个sql:

package com.mybatis.test;

import java.io.IOException;
import java.io.InputStream;

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 org.junit.Before;
import org.junit.Test;

import com.mybatis.po.User;

public class UserTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void createSqlSessionFactory() throws IOException {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void testFindUserById() {
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession();
            //根据用户id查询用户信息
            User user = sqlSession.selectOne("mybatis.findUserById", 2);
            System.out.println(user);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null ) {
                sqlSession.close();
            }
        }

    }

}

**看以上的代码,我们在运行测试方法值钱,先执行一个createSqlSessionFactory的方法,通过架构图我们看到,
我们是使用sqlSession来操作数据库的,而sqlSession来源于sqlSessionFactory,sqlSessionFactory对象其实就是SqlMapConfig配置文件经过转化后封装对象,因为我们在这里要提前创建sqlSessionFactory**
以上测试方法的执行结果如下:
这里写图片描述
查看输入信息,我们发现mybatis已经将我们写的sql和调用方法传入的参数自动装配,并且也将结果查询出来了。在这里我们使用的sqlSession.selectOne()方法代表查询的结果是一条记录,如果有多条,我们可以使用selectList()方法。
下面我们来使用selectList()方法根据用户名查询用户信息:
首先在User.xml中添加以下代码:

    <select id="findUserByName" parameterType="String" resultType="com.mybatis.po.User">
        select * from user where username like '%${value}%'
    </select>

编写对应的测试方法:

    @Test
    public void testFindUserByName() {
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession();
            //根据用户名查询用户信息
            List<User> list = sqlSession.selectList("mybatis.findUserByName", "张");
            for (User user : list) {
                System.out.println(user);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null ) {
                sqlSession.close();
            }
        }
    }

可以看到我们查询到了结果:
这里写图片描述
在这里,需要注意以下几点:

1. 如果sql查询结果是一个List,那么resultType的类型就是该集合中的每一个元素的类型.
2. 和前面不同的是,这里使用了${},在前面的sql中,#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型的转换,切可以防止sql注入.#{}可以接受简单类型值或者pojo属性值.如果parameterType传输单个简单类型值,#{}括号中可以是value或者其他名称.
3. ${}是字符串拼接指令,表示拼接sql串,通过${}可以将parameterType传入的内容拼接在sql中,且不进行jdbc类型转换,${}可以接收简单类型值或者pojo属性值,如果parameterType传输单个简单数据类型值,${}括号中只能是value
4. parameterType指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中.
5. resultType指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象.

插入数据以及主键返回

    依旧是上面的User.xml中,我们来编写一个插入新用户的sql:

扫描二维码关注公众号,回复: 3533175 查看本文章
    <!-- 新增用户信息 -->
    <insert id="insertUser" parameterType="com.mybatis.po.User">
        insert into
        user (username, password)
        value (#{username}, #{password})
    </insert>

继续测试插入数据的方法:

@Test
    public void testInsertUser() {
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession();
            //添加新用户
            User user = new User();
            user.setUsername("小李");
            user.setPassword("111111");
            sqlSession.insert("mybatis.insertUser", user);
            //新增数据需要提交事务 
            sqlSession.commit();
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null ) {
                sqlSession.close();
            }
        }
    }

刷新数据中的数据,可以看到数据已经插入成功:
这里写图片描述
因为我们在数据库中的user表中使用的是主键自增长,因此我们在插入数据后可以通过以下方式来得到新添加记录的主键:
修改User.xml中的insert语句:

    <!-- 新增用户信息 -->
    <insert id="insertUser" parameterType="com.mybatis.po.User">
        <selectKey keyProperty="uid" order="AFTER" resultType="Integer">
            select LAST_INSERT_ID()
        </selectKey>

        insert into
        user (username, password)
        value (#{username}, #{password})
    </insert>

这样就可以在插入数据后直接获得用户记录的uid:
这里写图片描述
这里写图片描述

在insert语句中添加selectKey将实现主键返回
keyProperty:返回的主键存储在pojo的哪个属性中
order:selectKey的执行顺序,是相对于insert语句来说的,由于mysql的自增原理是执行完insert语句之后才生成主键,因此这里执行顺序为after
resultType:返回的主键类型
LAST_INSERT_ID()是mysql的函数,返回auto_increment自增列新记录的id值.
类似的,也可以在插入数据前就设置pojo的主键,除了自己设置以外,也可以使用mysql的uuid()函数来实现:
我们在User.xml中添加一个插入的语句:

    <insert id="insertUserWithId" parameterType="com.mybatis.po.User">
        <selectKey resultType="String" order="BEFORE" 
            keyProperty="uid">
            select uuid()
        </selectKey>    
        insert into
        user (uid, username, password)
        value (#{uid}, #{username}, #{password})
    </insert>

测试代码如下:

    @Test
    public void testInsertUserWwith() {
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession();
            //添加新用户
            User user = new User();
            user.setUsername("大王");
            user.setPassword("666");
            sqlSession.insert("mybatis.insertUserWithId", user);
            //新增数据需要提交事务 
            sqlSession.commit();
            System.out.println("插入记录的id是:" + user.getUid());
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null ) {
                sqlSession.close();
            }
        }
    }

注意,在这里我们传入的User对象是没有uid的,数据库会在插入数据前,先使用mysql的函数生成一个uuid作为主键,然后添加都User对象中,再去插入数据库,我们可以通过控制台的输出看到这个过程
这里写图片描述
其他的删除或者更新的功能也大致一样,这里不再赘述

总结

我们使用mybatis对数据库进行操作后,到底带来了那些方便呢?

  • 在SqlMapConfig.xml中,我们配置了数据库连接池,不用频繁的创建连接,耗费性能.
  • sql语句配置在xml映射文件中,和java代码分离,便于维护.
  • 将java对象映射到sql中,通过statement中的parameterType定义输入参数的类型.
  • Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型.

猜你喜欢

转载自blog.csdn.net/xiaoyao2246/article/details/81101753