mybatis基础

mybatis框架
原始jdbc操作存在很多弊端:
1.数据库连接创建,释放频繁,造成系统资源浪费,从而影响系统性能
2.sql语句在代码中硬编码,造成代码不易维护,实际应用中sql语句变化很大,sql语句的变化需要改变java代码
3.查询时需要将结果集的数据手动设置到实体中,插入语句需要将实体属性手动设置到sql占位符中
mybatis给出的解决方案
1.使用数据库连接池初始化连接资源
2.将sql语句抽取到xml配置文件中
3.利用反射等机制,自动将实体属性与表字段进行映射

mybatis默认事务是不提交的,所以需要进行提交才能执行增删改的操作到数据库 或者openSession(true) 自动提交事务

mybatis核心配置文件的标签如下
configuration(配置) 主标签
properties(属性) 引入外部properties文件
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器) JDBC
dataSource(数据源) POOLED 配置4个属性 username password driver url
databaseIdProvider(数据库厂商标识)
mappers(映射器) 可以单独文件或接口映射,也可以选择扫描包
常用的的mybatis配置文件如下

<?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="jdbc.properties"></properties>
    <typeAliases>
        <typeAlias type="domain.User" alias="user"></typeAlias>
    </typeAliases>
    <typeHandlers>
        <typeHandler handler="handler.DateTypeHandler"></typeHandler>
    </typeHandlers>
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql"></property>
        </plugin>
    </plugins>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"></property>
                <property name="url" value="${url}"></property>
                <property name="username" value="${username}"></property>
                <property name="password" value="${password}"></property>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="UserMapper.xml"></mapper>
        <package name="com.mapper"></package>
    </mappers>
</configuration>

如下是使用mybatis的基本代码 sqlSession.selectList(“UserMapper.selectAll”) UserMapper.selectAll是 映射器(mapper.xml)命名空间.方法名

String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        List<domain.User> users = sqlSession.selectList("UserMapper.selectAll");

根据三层架构的思想,我们还是有web service dao 三层. 在dao层会有接口 和实现类 ,在实现类中不再使用原生jdbc或 jdbcTemplate,queryRunner等sql硬编码的方式,而是使用mybatis来操作数据库,但是明显的daoimpl里的代码都是重复的,每次都创建新的sqlSessionFactory等mybatis的初始类,我们如果将这些初始化动作提出来.那么实现类最核心的部分就是执行映射器哪个方法的代码 sqlSession.selectList(“UserMapper.selectAll”);
sql已经定义在mapper.xml文件中,dao接口定义了实现类操作方法,mapper.xml和dao接口满足一些条件,mybatis将会直接通过dao接口用动态代理的方式创建接口的实现类,而不需要我们定义dao接口的实现类.
条件为:
1.接口方法名称和mapper.xml中sql的id需要对应
2.mapper.xml 文件的命名空间需要和dao接口的全限定名相同
3.接口的方法入参和sql的paramType相同
4.接口的返回值需要和sql的resultType相同

动态sql
1. where 可以根据后面的条件是否存在,动态地决定是否添加where 子句 并且会把第一个条件的and 去掉
2.if 可以根据条件是否满足,动态地决定是否添加 if标签内的语句
3.foreach 可以进行集合或数组的遍历

#{id}

4.sql片段定义 id,name 引用

如果我们java实体类中某个字段的类型和数据库的数据类型不一致,那么需要我们自定义类型处理器继承BaseTypeHandler或实现TypeHandler接口,然后配置在mybatis的配置文件中 内 比如日期类型转 Long毫秒值(java类型是日期,数据库类型是long)

plugins插件标签 可以引入 mybatis的相关插件 比如分页助手 pageHelper 首先当然是引入pageHelper 的jar包

   		<dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>3.7.5</version>
        </dependency>
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>0.9.1</version>
        </dependency>

然后配置 mybatis的配置文件 中 plugins标签

 	<plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql"></property>
        </plugin>
   	</plugins>

在查询之前设置pageHelper的参数,查询后将结果传入PageInfo的构造函数,可以获取其他信息(总页数,总条数,前一页,后一页等)

		PageHelper.startPage(1,2);  //第几页,每页条数
        List<User> users = mapper.selectAll(user);
        PageInfo<User>pageInfo=new PageInfo<User>(users);

如果查询出的结果要封装到有个Order对象,order对象中有一个User类型的属性user 那么可以如下方式配置resultMap

 <resultMap id="orderAndUser" type="domain.Order">
        <id column="oid" property="id"></id>
        <result column="time" property="time"></result>
        <result column="amount" property="amount"></result>
        <result column="uid" property="user.id"></result>
        <result column="name" property="user.name"></result>
        <result column="identifyno" property="user.identifyno"></result>
    </resultMap>

也可以这样配置

 <resultMap id="orderAndUser" type="domain.Order">
        <id column="oid" property="id"></id>
        <result column="time" property="time"></result>
        <result column="amount" property="amount"></result>
        <association property="user" javaType="domain.User">
            <id column="uid" property="id"></id>
            <result column="name" property="name"></result>
            <result column="identifyno" property="identifyno"></result>
        </association>
    </resultMap>	

resultMap 对象中包含普通对象则用 association标签. 标签内的 property是对象名, javaType是对象的类型
resultMap 对象中包含集合对象则用 collection标签. 标签内的 property是对象名 ofType是集合内对象的类型
一对一 一对多 两个表关联查询就行了 (用户和订单 一个订单对应一个用户 一个用户可以有多个订单,分别是一对一和一对多)
多对多 有一个中间表维护两个表的关系 查询的时候是三张表关联查询(人员 角色 多对多)

mybatis注解开发 注解是用来替换mapper.xml文件的 注解是加在mapper接口的方法上的 注解需要在mybatis配置文件中配置包扫描 注解和xml配置sql不能同时加入mybatis映射器
@Insert @Delete @Update @Select 增删改查
封装结果集 @Results 代替ResultMap标签 @Result代替 result标签
实现一对一 和一对多结果集的封装 @One代替 association 标签 @Many 代替collection标签 但是又略有不同(注解版是分步查询的,xml版是一次性多表关联查询的)

一个订单对象里只有一个user对象 一对一的关系 注解版可以如下配置

  @Select(" SELECT *,o.id oid FROM day14.user u,day14.order o WHERE u.id=o.uid")
     @Results({
             @Result(property = "user.id",column = "uid"),
             @Result(property = "user.name",column = "name"),
             @Result(property = "user.identifyno",column = "identifyno"),
             @Result(property = "id",column = "oid"),
             @Result(property = "time",column = "time"),
             @Result(property = "amount",column = "amount"),
     })
     List<Order> selectAll();

一对一也可以进行这样的配置

  @Select(" SELECT * FROM  day14.order")
     @Results({

             @Result(property = "id",column = "id"),
             @Result(property = "time",column = "time"),
             @Result(property = "amount",column = "amount"),
             @Result(one = @One(select = "dao.UserMapper.selectOne"),column = "uid",javaType = User.class,property ="user")
     })
     List<Order> selectAll();

一个user可以对应多个order user对象中有一个orderList @Many里的JavaType 集合的话就写集合,xml的配置 oftype里写集合内元素的类型,注意

 @Select(" SELECT * FROM  day14.user")
     @Results({

             @Result(property = "id",column = "id"),
             @Result(property = "name",column = "name"),
             @Result(property = "identifyno",column = "identifyno"),
             @Result(many = @Many(select = "dao.OrderMapper.selectByUid"),column = "id",javaType = List.class,property ="orderList")
     })
     List<User> selectAll();		

多对多和一对多的注解查询类似,无非@Many 里select 属性对应的方法的sql语句是两张表的多表查询 而一对多的这个语句是单表查询

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值