Mybatis开发DAO层的两种方法

Mybatis开发DAO方法

常用类

SqlSessionFactoryBuilder

通过SqlSessionFactoryBuilder创建会话工厂

将SqlSessionFactoryBuilder当成一个工具类使用,不需要使用单例管理SqlSessionFactoryBuilder。

在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

SqlSessionFactory

通过SqlSessionFactory创建SQLSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例,整个项目只有一个实例)

将来mybatisSpring整合后,使用单例模式去管理SqlSessionFactory

SqlSession

SqlSession是一个面向用户(程序员)接口

SqlSession提供了很多操作数据库的方法,

selectOne:返回单个对象,根据主键来查询

selectList:返回1个或者多个对象。

SqlSession是线程不安全,在SqlSession实现类中除了有接口中方法(操作数据库的方法),还有数据域属性。

SqlSession最佳应用场合是在方法体内,定义成局部变量使用。

使用Mybatis开发DAO层

方法一:最基本的方法

目录结构如下:

实现一个案例,从一个User表中根据id查找一个用户

UserDao为一个接口,UserDaoImpl为该接口的实现类

UserDao

public interface UserDao {
    /**
     * 得到用户通过id
     * @param id
     * @return
     */
    public User getUserById(Integer id);
}

UserDaoImpl

public class UserDaoImpl implements UserDao {
    //在创建DAO的时候,需要传递工厂
    private SqlSessionFactory sqlSessionFactory;

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

    @Override
    public User getUserById(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        User ser = sqlSession.selectOne("user.findUserById",id);
        return ser;
    }
}

POJO为数据库中表的实体类的映射

package com.hyx2.dao_first.pojo;

import java.util.Date;

public class User {
    private Integer id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址

    public User() {
    }

    public User(String username, String sex, Date birthday, String address) {
        this.username = username;
        this.sex = sex;
        this.birthday = birthday;
        this.address = address;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" + "id=" + id + ", username='" + username + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + '}';
    }
}

配置User.xml文件,执行sql查询语句

<?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="user">

<select id="findUserById" parameterType="int" resultType="pojo.User">
        select  * from user where id = #{id}
    </select>
    
</mapper>

接下来为配置好的Mybatis配置文件注册该User.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="db.properties"></properties>


    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <!--数据库连接要素,数据库,数据库位置,账户,密码-->
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>

    <!--配置实体类的xml文件,在这文件中执行sql语句-->
    <mappers>
     <mapper resource="User.xml"></mapper>
    </mappers>
</configuration>

数据库连接配置信息

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis01?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123

执行测试

import UserDao;
import impl.UserDaoImpl;
import pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

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

public class Demo01 {

    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void fun0() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream( "hyx2_first_sqlMapconfig.xml" );
        //通过配置创建会话工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build( inputStream );
    }

    @Test
    public void fun(){
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        User userById = userDao.getUserById(1);
        System.out.println(userById);
    }
}

存在的问题

(1)dao接口实现类方法中,存在大量模板代码(重复),设想能否将这项代码抽取出来,大大减少程序员的工作量。

AOP思想;代理模式

(2)调用SQLSession方法的时候,传入的变量类型Object,即使变量类型传入错误,在编译阶段也不报错,不利于程序的开发。

方法二:Mapper代理开发方法(只需要写Mapper接口(相当于DAO接口))

使用该方法,程序员要干的事情

程序员只需要编写Mapper接口(就相当于DAO),mybatis可以自动生成Mapper接口实现类对象。但是:要像自动生成实现类对象,需要遵循一些规范。

(1)Mapper接口和Mapper.xml放在同一个目录下。同名。

(2)Mapper.xml中namespace的值等于Mapper接口的全路径

(3)statementId,parameterType、ResultType和接口名字、入参类型、返回值类型要一致。

使用该方法代码实现方法一中的案例:

目录结构如下:

User直接使用方法一种的代码

UserMapper为一个接口:

package mapper;

import pojo.User;

public interface UserMapper {
    /**
     * 找到用户通过id
     */
    public User findUserById(Integer id);
}

UserMapper.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="com.hyx2.dao_two.mapper.UserMapper">

<select id="findUserById" parameterType="int" resultType="pojo.User">
        select  * from user where id = #{id}
    </select>

</mapper>

hyx2_two_sqlMapconfig.xml中内容与案例一种的一样,只需要修改mappers中的代码

 <!--配置实体类的xml文件,在这文件中执行sql语句-->
    <mappers>
     <mapper resource="com/hyx2/dao_two/mapper/UserMapper.xml"></mapper>
    </mappers>

开始测试:

package test;

import mapper.UserMapper;
import pojo.User;
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 java.io.IOException;
import java.io.InputStream;

public class Dmo01 {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void fun0() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream( "hyx2_two_sqlMapconfig.xml" );
        //通过配置创建会话工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build( inputStream );
    }

    @Test
    public void fun(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User userById = mapper.findUserById(1);
        System.out.println(userById);
    }
}

使用Mapper开发常见问题

下图的对应关系一定要注意

代理内部selectOne和selectList怎么区别的

根据接口的返回值来区别的。

如果返回值是POJO对象,selectOne来实现。

如果返回值是结合对象,selectList来实现。

Mapper接口方法只能是一个参数

系统是否不利于扩展维护。

系统框架中,DAO层的代码是被业务层公用的

即使Mapper接口只有一个参数,可以使用包装类型的POJO满足不同业务方法的需求。

猜你喜欢

转载自blog.csdn.net/h1025372645/article/details/89816857
今日推荐