MyBatis基础(二)—持久层开发的两种方法

SqlSession作用范围

  • SqlSessionFactoryBuilder
    SqlSessionFactoryBuilder是以工具类方式来使用,需要创建sqlSessionFactory就new一个SqlSessionFactoryBuilder。

  • sqlSessionFactory
    正常开发时,以单例方式管理sqlSessionFactory,整个系统运行过程中sqlSessionFactory只有一个实例,将来和spring整合后由spring以单例方式管理sqlSessionFactory。

  • SqlSession
    sqlSession是一个面向用户(程序员)的接口,程序员调用sqlSession的接口方法进行操作数据库。
    由于sqlSession是线程不安全,(查看MyBatis的源码,Executor的实现类中currentSql、currentStatement等为成员变量),所以sqlSession最佳应用范围在方法体内,在方法体内定义局部变量使用sqlSession。

持久层开发的两种方法

原始的DAO开发方式

DAO接口和实现

UserDao

public interface UserDao {
    public User findUserById(int id) throws Exception;

    public List<User> findUserByUsername(String username) throws Exception;

    public void insertUser(User user) throws Exception;

}

UserDaoImpl

public class UserDaoImpl implements UserDao {
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        // 创建SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        User user = sqlSession.selectOne("test.findUserById", id);

        sqlSession.close();
        return user;
    }

    @Override
    public List<User> findUserByUsername(String username) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> list = sqlSession.selectList("test.findUserByName", username);
        sqlSession.close();
        return list;
    }

    @Override
    public void insertUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("test.insertUser", user);
        sqlSession.commit();
        sqlSession.close();
    }
}

测试类

public class UserDaoImplTest {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void init() throws IOException {
        String resource = "SqlMapConfig.xml";

        //MyBatis提供了Resources读取配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void testFindUserById() throws Exception {
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);

        User user = userDao.findUserById(1);
        System.out.println(user);
    }
}

User.xml同上一篇博文

mapper自动代理的开发方式

mapper开发规范

  1. mapper.xml中namespace指定为mapper接口的全限定名
    此步骤目的:通过mapper.xml和mapper.java进行关联。
  2. mapper.xml中statement的id就是mapper.java中方法名
  3. mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
  4. mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.

mapper开发的主要mapper.xml和mapper接口

mapper映射文件的命名方式建议:类名+Mapper.xml

mapper接口(相当于DAO接口)的命名方式建议:类名+Mapper

UserMapper

public interface UserMapper {
    public User findUserById(int id) throws Exception;

    public List<User> findUserByName(String username) throws Exception;
}

UserMapper.xml

<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
        SELECT * FROM USER WHERE id= #{id}
    </select>

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

    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
        <selectKey keyProperty="id" order="AFTER" resultType="int">
            select LAST_INSERT_ID()
        </selectKey>

        INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
    </insert>

    <delete id="deleteUser" parameterType="int">
         delete from user where id=#{id}
    </delete>

    <update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
</mapper>

测试类:

public class UserMapperTest {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void init() throws IOException {
        String resource = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    }

    @Test
    public void testFindUserById() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        // 创建代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user = userMapper.findUserById(1);

        System.out.println(user);
    }

    @Test
    public void testFindUserByUsername() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 创建代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        List<User> list = userMapper.findUserByName("小明");

        System.out.println(list);
    }

    @Test
    public void testInsertUser() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 创建代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user = new User();
        user.setUsername("李奎");
        userMapper.insertUser(user);

        sqlSession.commit();
        sqlSession.close();
    }
}

补充SqlMapConfig中几个配置

typeAliases

单个别名定义:
alias:别名,type:别名映射的类型

<typeAliases>
    <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> 
</typeAliases>

批量别名定义
指定包路径,自动扫描包下边的pojo,定义别名,别名默认为类名(首字母小写或大写)

<typeAliases>
    <package name="cn.itcast.mybatis.po"/>
</typeAliases>

mappers配置

resource引用

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

class引用mapper接口
class:配置mapper接口全限定名
要求:需要mapper.xml和mapper.java同名并且在一个目录中

<mappers>
        <mapper class="cn.itcast.mybatis.mapper.UserMapper"/>   
</mappers>

批量mapper配置
通过package进行自动扫描包下边的mapper接口,
要求:需要mapper.xml和mapper.java同名并且在一个目录 中

<mappers>
    <package name="cn.itcast.mybatis.mapper"/>
</mappers>

输入输出映射

parameterType

parameterType传递POJO包装对象,可以定义POJO包装类型扩展mapper接口输入参数的内容。
(使用场景:自定义查询等)

resultType

指定输出结果的类型(简单类型、POJO、HashMap…),将SQL查询结果映射为Java对象 。

**注意:**SQL查询的列名要和resultType指定POJO的属性名相同,指定相同属性方可映射成功,如果SQL查询的列名和resultType指定POJO的属性名全部不相同,list中无法创建POJO对象的。

resultMap

将SQL查询结果映射为java对象。

如果SQL查询列名和最终要映射的POJO的属性名不一致,使用resultMap将列名和POJO的属性名做一个对应关系 (列名和属性名映射配置)

定义resultMap

id:mapper.xml中的唯一标识
type:最终要映射的pojo类型

列名和属性名映射配置

id:要映射结果集的唯 一标识 ,称为主键
result:就是普通列的映射配置

column:结果集的列名
property:type指定的哪个属性中

<resultMap id="userListResultMap" type="user" >
     <id column="id_" property="id"/>
     <result column="username_" property="username"/>
     <result column="birthday_" property="birthday"/>
</resultMap>

动态SQL

SQL片段

通过sql片段可以将通用的sql语句抽取出来,单独定义,在其它的statement中可以引用sql片段。

通用的sql语句,常用:where条件、查询列。

SQL片段定义

<sql id="query_user_where">
</sql>

SQL片段引用

<include refid="query_user_where"></include>

if和where

<sql id="query_user_where">
    <if test="userCustom!=null">
        <if test="userCustom.username!=null and userCustom.username!=''">
            and username like '%${userCustom.username}%'
        </if>
        <if test="userCustom.sex!=null and userCustom.sex!=''">
            and sex = #{userCustom.sex}
        </if>
    </if>
</sql>

foreach

在statement通过foreach遍历parameterType中的集合类型。

collection:集合的属性
open:开始循环拼接的串
close:结束循环拼接的串
item:每次循环取到的对象
separator:每两次循环中间拼接的串

<sql id="query_user_where">
    <if test="userCustom!=null">
         <foreach collection="ids" open=" AND id IN ( " close=")" item="id" separator=",">
            #{id}
         </foreach>
    </if>
</sql>

完整代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值