MyBatis学习笔记:基于xml和注解对表的基本操作

MyBatis学习笔记:基于xml和注解对表的基本操作

本篇博文主要是想记录下在使用mybatis时遇到的一个小问题,也就顺便介绍下使用MyBatis基于xml和注解来实现对数据库的基本操作。

具体遇到了什么问题,见文章最后。

第一部分:基于xml的实现

主要步骤如下:

1、使用idea建立一个项目。项目结构如下(图中相关的类后面会一一说到)

2、在pom.xml文件添加mybatis相应的依赖。具体如下

      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.4.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>6.0.6</version>
        </dependency>

      </dependencies>

主要涉及到两个包:mybatis、mysql-connector-java,另外一个是用于测试的junit。

3、创建数据库和表,这里使用的是MySQL数据库。

我主要是借助于Sequel pro这个工具来建库和表,截图如下

4、与表对应的实体类Person类代码如下

    public class Person {

        private int id;
        private String userName ;
        private int age ;
        private String mobilePhone ;

        //getter setter

    }

5、添加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>
        <!-- 引用config.properties配置文件 -->
        <properties resource="config.properties"/>
        <typeAliases>
            <typeAlias type="com.wrh.entity.Person" alias="Person"/>
        </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <!-- 配置数据库连接信息 -->
                <dataSource type="POOLED">
                <!-- value属性值引用config.properties配置文件中配置的值 -->
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
    //这里注册personMapper.xml文件,具体见第7步
    </configuration>

其中,mybatis-config.xml文件中所用的到的数据库相关信息放在config-properties.xml文件中,具体如下:


    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mybatis?useSSL=true
    username=XXX
    password=XXXX

6、定义操作person表的sql映射文件Person.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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
     例如namespace="mapper.Person"就是mapper(包名)+Person(Person.xml文件去除后缀)
      -->
    <mapper namespace="mapper.Person">
        <insert id="insertPerson" parameterType="Person" >
            INSERT INTO PERSON(ID,USERNAME,AGE,MOBILEPHONE)VALUES (#{id},#{userName},#{age},#{mobilePhone})
        </insert>

        <!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为queryById,id属性值必须是唯一的,不能够重复
          使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
          resultType="com.wrh.entity.Person"就表示将查询结果封装成一个Person类的对象返回
         Person类就是PERSON表所对应的实体类
         -->
        <select id="queryById" parameterType="int" resultType="com.wrh.entity.Person">
            SELECT * FROM PERSON WHERE ID=#{id}
        </select>

        <update id="updatePerson">
            UPDATE PERSON SET USERNAME=#{userName},AGE=#{age},MOBILEPHONE=#{mobilePhone} WHERE ID=#{id}
        </update>
    </mapper>

7、在mybatis-config.xml文件中注册Person.xml文件

具体操作为将如下的代码添加到mybatis-config.xml文件的相应位置。

        <mappers>
            <!--
            userMapper.xml位于mapper这个包下,所以resource写成mapper/Person.xml -->
            <mapper resource="mapper/Person.xml"/>

        </mappers>  

8、编写测试代码:执行在Person.xml文件中定义的insert、select语句 。

    package com.wrh;

    import com.wrh.entity.Person;
    import com.wrh.mapper.PersonMapper;
    import com.wrh.utils.MybatisUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;

    /**
     * Created by wuranghao on 2017/7/16.
     */
    public class PersonTest {

        SqlSession sqlSession ;
        @Test
        public void insertPerson(){
            sqlSession = MybatisUtil.getSqlSession();
            int id = 100;
            String userName = "wojiushimogui";
            int age = 19;
            String mobilePhone = "18000000001";
            Person person = new Person();
            person.setId(id);
            person.setAge(age);
            person.setUserName(userName);
            person.setMobilePhone(mobilePhone);
            try{
                sqlSession.insert("insertPerson",person);
                sqlSession.commit();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                MybatisUtil.closeSession(sqlSession);
            }

        }

        @Test
        public void queryById(){
            sqlSession = MybatisUtil.getSqlSession();
            int id = 100;
            try{
                /**
                 * 映射sql的标识字符串,
                 * mapper是Person.xml文件中mapper标签的namespace属性的值,
                 * getUser是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
                 */
                Person person = sqlSession.selectOne("mapper.Person.queryById",id);

                sqlSession.commit();//手动commit
                System.out.println(person.getUserName());
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                MybatisUtil.closeSession(sqlSession);
            }

        }
    }

经过测试,正常工作。

其中测试代码中所用到的工具类:MybatisUtil的代码如下

    package com.wrh.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.Reader;

    /**
     * Created by wuranghao on 2017/7/16.
     */
    public class MybatisUtil {
        private final  static SqlSessionFactory sqlSessionFactory;

        static {
            String resource="mybatis-config.xml";
            Reader reader =null;
            try {
                reader = Resources.getResourceAsReader(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        }

        /**
         * 获取SqlSessionFactory
         * @return SqlSessionFactory
         */
        public static SqlSessionFactory getSqlSessionFactory(){
            return sqlSessionFactory;
        }

        /**
         * 获取SqlSession
         * @return SqlSession
         */
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession();
        }

        /**
         * 获取SqlSession,可以设置是否自动commit
         * @return SqlSession
         */
        public static SqlSession getSqlSession(boolean isAutoCommit){
            return sqlSessionFactory.openSession(isAutoCommit);
        }
        /**
         * 关闭SqlSession
         */
        public  static void closeSession(SqlSession sqlSession){
            if (sqlSession!=null)
                sqlSession.close();
        }
    }

第二部分:基于注解的实现

与基于xml文件实现不同的是:用PersonMapper.java接口来代替Person.xml文件。

    public interface PersonMapper {

        @Insert("insert into person(ID,USERNAME,AGE,MOBILEPHONE) VALUES(#{id},#{userName},#{age},#{mobilePhone})")
        int add(Person person);


        @Select("select * from person where id = #{id}")
        Person queryById(int id);
    }

需要说明的是,我们不需要针对PersonMapper接口去编写具体的实现类代码,这个具体的实现类由MyBatis帮我们动态构建出来,我们只需要直接拿来使用即可。

注册:将PersonMapper类注册在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="config.properties"/>
        <typeAliases>
            <typeAlias type="com.wrh.entity.Person" alias="Person"/>
        </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>
            <!--
            userMapper.xml位于mapper这个包下,所以resource写成mapper/Person.xml 
            <mapper resource="mapper/Person.xml"/>
            -->
            <mapper class="com.wrh.mapper.PersonMapper"/>
        </mappers>
    </configuration>

值得注意的地方,即与注册personMapper.xml文件的区别:<mapper class="com.wrh.mapper.PersonMapper"/>这行代码。

最后编写相应的测试代码,具体如下

    public class PersonTest {

        SqlSession sqlSession ;

        @Test
        public void add(){
            //sqlSession = MybatisUtil.getSqlSession();利用此方法获取sqlSession将会导致不自动commit,需要手动添加sqlSessin.commit(),如果部添加将导致没有将数据插入到数据库中
            sqlSession = MybatisUtil.getSqlSession(true);
            PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);
            int id = 1001;
            String userName = "wojiushimogui";
            int age = 19;
            String mobilePhone = "18000000001";
            Person person = new Person();
            person.setId(id);
            person.setAge(age);
            person.setUserName(userName);
            person.setMobilePhone(mobilePhone);
            try{
                int add = personMapper.add(person);
                System.out.println("add = " + add);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                MybatisUtil.closeSession(sqlSession);
            }

        }

        @Test
        public void queryById2(){
            sqlSession = MybatisUtil.getSqlSession();
            PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);

            int id = 100;
            try{

                Person person = personMapper.queryById(id);
                System.out.println(person.getUserName());
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                MybatisUtil.closeSession(sqlSession);
            }

        }

    }

遇到的问题

在测试过程中,遇到一个问题,如果采用如下的代码来获取sqlSession时,在执行 add方法之后,数据库中没有相对应的Person信息

sqlSession = MybatisUtil.getSqlSession();//该方法的具体代码见上面。

产生的原因:没有commit

解决方法为:

1)手动commit,即在add方法中添加代码:sqlSession.commit()

2)在获得sqlSession时将isAutoCommit设置为true。

    //sqlSession = MybatisUtil.getSqlSession();利用此方法获取sqlSession将会导致不自动commit,而导致没有将数据插入到数据库中
    sqlSession = MybatisUtil.getSqlSession(true);

看了下DefaultSqlSessionFactory.java类中这两个方法的区别,如下:

    public SqlSession openSession() {
        return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
    }

    public SqlSession openSession(boolean autoCommit) {
        return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, autoCommit);
    }

既不带参数的openSession()方法是isAutoCommit设置为false的。

参考资料

1、http://www.cnblogs.com/xdp-gacl/p/4262895.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值