Mybatis 开发 DAO方法

Mybatis

SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建会话工厂
将SqlSessionFactoryBuilder当成一个工具类使用,不需要使用单例管理SqlSessionFactoryBuilder。
在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

SqlSessionFactory
通过SqlSessionFactory创建SQLSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例,整个项目只有一个实例)
将来mybatis和Spring整合后,使用单例模式去管理SqlSessionFactory。

SqlSession
SqlSession是一个面向用户(程序员)接口
SqlSession提供了很多操作数据库的方法,
selectOne:返回单个对象,根据主键来查询
selectList:返回1个或者多个对象。
SqlSession是线程不安全,在SqlSession实现类中除了有接口中方法(操作数据库的方法),还有数据域属性。
SqlSession最佳应用场合是在方法体内,定义成局部变量使用。

原始DAO开发方法(DAO接口和DAO实现类)

编写:DAO接口、DAO 实现

DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。

存在的问题

(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和接口名字、入参类型、返回值类型要一致。

目录结构:
在这里插入图片描述
在这里插入图片描述

使用Mapper开发常见问题

(1)代理内部selectOne和selectList怎么区别的
根据接口的返回值来区别的。
如果返回值是POJO对象,selectOne来实现。
如果返回值是集合对象,selectList来实现。
(2)Mapper接口方法只能是一个参数
系统是否不利于扩展维护。
系统框架中,DAO层的代码是被业务层公用的
即使Mapper接口只有一个参数,可以使用包装类型的POJO满足不同业务方法的需求。

SQLMapConfig配置文件

可以配置内容和属性
在这里插入图片描述

properties(属性)

mybatis将按照下面的顺序来加载属性

(1)在properties元素内体定义的属性首先会被读取。
(2)然后会读取properties元素中resource或者URL加载的属性,它会覆盖已经读取同名的属性。
(3)最后读取parameterType传递的属性,它会覆盖已经读取同名的属性。

在这里插入图片描述

结构
在这里插入图片描述

配置resource中的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>
    <properties resource="db.properties">
    
    <property name="jdbc.password" value="12"></property>
    <property name="xxxid" value="1"></property>
    
    </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>
    <mappers>
        <mapper resource="com/zly/d_sql_map_config/mapper/UserMapper.xml"></mapper>
    </mappers>
</configuration>

配置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.zly.c_dao_mapper.mapper.UserMapper">
    <!--查询用户列表:主键查询-->
    <select id="findUserById" parameterType="int" resultType="com.zly.c_dao_mapper.pojo.User">
        select  * from user where id = #{id}//根据id查找用户
    </select>
</mapper>

测试:

public class Demo01 {
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void fun0() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream( "sqlMapconfig.xml" );
        //通过配置创建会话工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build( inputStream );
    }
    @Test
    public void fun1() throws IOException {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
        User user = userMapper.findUserById( 1 );
        System.out.println(user);
    }
}

结果:
在这里插入图片描述
建议:
(1)不要在properties元素体内添加任何属性值,只将属性值定义到properties文件中。
(2)在properties文件定义的属性名要有一定的特殊性,不能和系统,其他框架的名字重复。
xxx.yyy
jdbc.url
redis.url

settings(全局配置参数)(了解)

mybatis全局配置参数
setting 标签的配置是配置 MyBatis 框架运行时的一些行为的,例如缓存、延迟加载、结果集控制、执行器、分页设置、命名规则等一系列控制性参数,其所有的 setting 配置都放在父标签 settings 标签中。
setting可以配置的参数很多,做了解就行,当要用到的时候可以查资料。

typeAliases(类型别名)
在Mapper.xml中,定义了很多statement,statement需要parameterType指定输入参数的类型和resultType指定结果映射的类型。
如果在指定类型的时候,写“全路径”不大方便开发,可以针对parameterType和resultType指定的类型提供别名,在Mapper.xml中使用别名。

系统已经定义的别名
在这里插入图片描述

自定义别名:

定义单个别名:

在这里插入图片描述
批量定义:
在这里插入图片描述
typeHandlers(类型处理器)

由于数据库厂商的不同,所以厂商设置的参数可能也不同,同时数据库也可以自定义数据类型,typeHandler允许我们根据项目的需要自定义设置Java传递到数据库的参数中,或者从数据库读取数据,我们也需要进行特殊的处理,这些都可以在在定义的typeHandler中进行处理,尤其是在使用枚举的时候我们常常需要使用typeHandler进行转换。
mybatis中通过typeHandlers完成JDBC类型和Java类型的转换。

mappers(映射器)

在mybatis下mapper映射配置有四种方式:

通过resource加载,通过URL地址(使用完全限定路径,绝对路径),通过Mapper接口加载,批量加载(推荐)在这里插入图片描述

批量加载时需要Mapper接口和Mapper映射文件放在同一个目录下面。并且遵循使用Mapper开发DAO的要求。

输入映射和输出映射

输入映射
Mybatis支持输入哪些类型
简单类型、POJO,HashMap,POJO的包装的类型。
需求:查询用户列表:已经下过订单男性用户,那么传入的参数包含用户信息(User)和订单信息(Order)

输出映射:
1.resultType
  使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
  如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
  只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。

案例:
查找名字带“小”并且性别为男的用户。
mapper接口:

public interface UserMapper {
  public List<User> findUserList(UserQueryVo userQueryVo);
}

mapper配置文件

  <?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">
    <!--namespace:命名空间,对SQL进行分类管理,SQL隔离-->
    <mapper namespace="com.huadian.e_parameter_type_pojo.mapper.UserMapper">
        <select id="findUserList" parameterType="com.huadian.e_parameter_type_pojo.vo.UserQueryVo"  resultType="com.huadian.e_parameter_type_pojo.pojo.User">
            select  * from user where username like "%"#{user.username}"%" and sex = #{user.sex}
        </select>

user实体类:

    package com.huadian.e_parameter_type_pojo.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 vo 类:

package com.huadian.e_parameter_type_pojo.vo;

import com.huadian.e_parameter_type_pojo.pojo.User;

public class UserQueryVo {
    //用户信息
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

config.xml配置:
在这里插入图片描述

resultMap
(1)使用条件
Mybatis使用resultMap完成高级输出结果映射
当列名和属性名不一致的情况,自己来指定如何进行映射

在这里插入图片描述
动态SQL

需求(1):更新用户,前端修改了什么,SQL语句就包含哪些列
Update user set username=? where uid = ?
Update user set username=?,sex=? where uid = ?
Java 代码进行判断。
If(username ==null){
拼接SQL语句
}
需求(2):根据用户名和性别查询用户列表,
如果传递了用户名和性别,2个都作为条件
如果传递了用户名,没有传递性别,用户名作为条件
一个参数都没有传递,就没有条件
If和where
在这里插入图片描述
可以将 if 的 sql语句提出,这样在不同的语句中使用时可以调用,不需要写重复的代码。

Foreach:

foreach主要用在构建in条件中,它可以在SQL语句中迭代一个集合。它的属性主要有:item、index、collection、separator、close、open。
(1)item:表示集合中每个元素进行迭代时的别名。
(2)index:制定一个名称,用于表示在迭代过程中,每次迭代到的位置。
(3)open:表示该语句以什么开始(既然是in条件语句,所以必然以“(”开始)。
(4)separator:表示在每次进行迭代之间以什么符号作为分隔符(既然是in条件语句,所以必须以“.”,作为分隔符)。
(5)close:表示该语句以什么语句结束(既然是in条件语句,所以必然是以“)”结束)。
(6)collection:最关键并最容易出错的属性,需格外注意,该属性必须指定,不同情况下,该属性的值是不一样的。

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值