Mybatis入门实例(优化版本)(2) - SSM(二)

来源:互联网 发布:python怎么滤波图片 编辑:程序博客网 时间:2024/06/08 17:23

本骗文章的内容是继续上一文章的继续优化,添加了面向接口,单例等优化,这种方式我们在实际项目中一般都是这样中方式使用的。
如果没有看过前面的Mybatis入门实例 - SSM(一),建议先看看再来看本篇;

1. 整体代码结构


首先还是来看一下我们优化后的项目代码结构:

这里写图片描述

我们在上一节的基础上增加了一个Mybatis的Util类MybatisUtil.java,还有就是增加了面向结构的dao层,接口UserDao.java以及结构的实现类UserDaoImpl.java。增加了一个新的测试入口类TestUtil.java
接下来我们就将来看看我们的改变。

2. 代码变化


2.1 MybatisUtil.java

我们还是先看代码,然后再来解释:

package com.stephen.mybatis.util;import java.io.IOException;import java.io.Reader;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class MybatisUtil {    private static String CONFIG_FILE = "mybatis-config.xml";    private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();    private static SqlSessionFactory sessionFactory;    private MybatisUtil(){    }    public static SqlSession getSession(){        SqlSession session = (SqlSession)threadLocal.get();        if (session == null) {            if (sessionFactory == null) {                buildSessionFactory();            }            session = (sessionFactory != null) ? sessionFactory.openSession() : null;            threadLocal.set(session);        }        return session;    }    public static void buildSessionFactory(){        try {            Reader reader = Resources.getResourceAsReader(CONFIG_FILE);            sessionFactory = new SqlSessionFactoryBuilder().build(reader);        } catch (IOException e) {            e.printStackTrace();        }    }    public static void closeSession(){        SqlSession session = threadLocal.get();        threadLocal.set(null);        if (session != null) {            session.close();        }    }    public static void closeSessionFactory(){        sessionFactory = null;    }}
  1. 我们使用单例的方式来实现getSqlSession(),保障在当前线程(ThreadLocal)有且只有一个实例。
  2. 使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件
  3. 另外增加关闭session等其他辅助方法。

2.2 定义我们的接口UserDao.java

还是先看代码:

package com.stephen.mybatis.dao;import com.stephen.mybatis.model.User;public interface UserDao {    Boolean add(User user);    Boolean delete(Integer id);    Boolean update(User user);    User get(Integer id);}

我们定义了关于对User的CRUD的结构。

2.3 接口的实现UserDaoImpl.java

老规矩,线上代码:

package com.stephen.mybatis.dao.impl;import com.stephen.mybatis.util.MybatisUtil;import com.stephen.mybatis.dao.UserDao;import com.stephen.mybatis.model.User;public class UserDaoImpl implements UserDao {    private static final String CLASS_NAME = User.class.getName();    private static final String SQL_ID_ADD = ".add";    private static final String SQL_ID_DELETE = ".delete";    private static final String SQL_ID_GET = ".get";    private static final String SQL_ID_UPDATE = ".update";    @Override    public Boolean add(User user) {        try {            MybatisUtil.getSession().insert(CLASS_NAME + SQL_ID_ADD, user);            MybatisUtil.getSession().commit();        } catch (Exception e) {            e.printStackTrace();            MybatisUtil.getSession().rollback();            return Boolean.FALSE;        } finally {            MybatisUtil.closeSession();        }        return Boolean.TRUE;    }    @Override    public Boolean delete(Integer id) {        try {            MybatisUtil.getSession().delete(CLASS_NAME + SQL_ID_DELETE,id);            MybatisUtil.getSession().commit();        } catch (Exception e) {            e.printStackTrace();            MybatisUtil.getSession().rollback();            return Boolean.FALSE;        } finally {            MybatisUtil.closeSession();        }        return Boolean.TRUE;    }    @Override    public Boolean update(User user) {        try {            MybatisUtil.getSession().update(CLASS_NAME + SQL_ID_UPDATE, user);            MybatisUtil.getSession().commit();        } catch (Exception e) {            e.printStackTrace();            MybatisUtil.getSession().rollback();            return Boolean.FALSE;        } finally {            MybatisUtil.closeSession();        }        return Boolean.TRUE;    }    @Override    public User get(Integer id) {        User user = null;        try {            user = MybatisUtil.getSession().selectOne(CLASS_NAME + SQL_ID_GET, id);        } finally {            MybatisUtil.closeSession();        }        return user;    }}
  1. 我们使用MybatisUtil来获取我们的session,再用session来执行我们的CRUD。
  2. session执行的第一个参数statement,我们的使用常量拼接来定义,首先我们各异利用反射机制拿到实体User的类名,User.class.getName(),既可以获得com.stephen.mybatis.model.User,再拼接CRUD的操作,就获得statement是:
    • com.stephen.mybatis.model.User.add
    • com.stephen.mybatis.model.User.update
    • com.stephen.mybatis.model.User.delete
    • com.stephen.mybatis.model.User.get
  3. 对应的UseMapper中的namespace更改为 namespace=”com.stephen.mybatis.model.User”

2.4 UserMapper.xml

为了方便我们这里需要修改namespace=”com.stephen.mybatis.model.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.stephen.mybatis.model.User">    <!-- 配置一个结果映射对象 -->    <resultMap type="com.stephen.mybatis.model.User" id="userMap">        <id property="id" column="id"/>        <result property="name" column="name"/>        <result property="age" column="age"/>    </resultMap>    <insert id="add" parameterType="User" useGeneratedKeys="true" keyProperty="id">        <![CDATA[            INSERT INTO users(name, age) VALUES(#{name}, #{age})        ]]>    </insert>    <select id="get" resultMap="userMap" parameterType="Integer">        <![CDATA[            SELECT * FROM users WHERE id = #{id}        ]]>    </select>    <delete id="delete" parameterType="Integer">        <![CDATA[            DELETE FROM users WHERE id = #{id}        ]]>    </delete>    <update id="update" parameterType="User">        <![CDATA[            UPDATE users SET name = #{name}, age = #{age} WHERE id = #{id}        ]]>    </update></mapper>

2.5 测试类TestUtil.java

package com.stephen.mybatis;import com.stephen.mybatis.dao.UserDao;import com.stephen.mybatis.dao.impl.UserDaoImpl;import com.stephen.mybatis.model.User;public class TestUtil {    /**     * @param args     */    public static void main(String[] args) {        UserDao userDao = new UserDaoImpl();        //test add        User user = new User();        user.setName("Stephen Huang");        user.setAge(18);        userDao.add(user);        System.out.println("add user:" + user);        //test get        System.out.println("get user id:" + user.getId());        System.out.println(userDao.get(user.getId()));        //test update        user.setAge(28);        userDao.update(user);        System.out.println("update user age=28:" + user);        //test delete        Integer userId = user.getId();        userDao.delete(userId);        System.out.println("delete user id=" + userId);        System.out.println("get deleted user: " + userDao.get(userId));    }}

3. 测试结果

除了以上文件的更改,其他文件没有任何变化,所以现在我们就可以运营我们的测试类TestUtil.java,来查看我们的测试结果了。

log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).log4j:WARN Please initialize the log4j system properly.add user:User [id=11, name=Stephen Huang, age=18]get user id:11User [id=11, name=Stephen Huang, age=18]update user age=28:User [id=11, name=Stephen Huang, age=28]delete user id=11get deleted user: null

今天就先优化到这里了,其实代码还有很大的优化的地步,接下来我会一步一步继续优化的。


GitHub代码参考下载地址

1 0