mybatis

1.认识mybatis能做什么?

mybatis是一款持久层框架,对jdbc进行轻量级封装,做数据库curd操作,简化jdbc的代码,避免了繁琐的设置参数与获取结果集的代码。

mybatis需要开发人员自己编写sql语句进行数据库操作。

mybatis通过xml或注解实现类到表的一一映射,类的属性到表的字段的映射。这一步称为orm对象关系映射.

简而言之一句话:就是做数据库的curd操作。需要编写sql语句。

2.了解orm框架的学习步骤

mybatis勉勉强强的称为半自动化的orm框架,因为还需要编写sql语句。使用更加灵活。对一些复杂的数据库操作实现更加方便。

mybatis-plus框架,是基于mybatis框架运行,更加趋向于纯自动化的orm框架,但仍然支持sql语句。

spring-data-jpa框架,是纯自动化的orm框架。当我们把类与表,属性与字段做完映射后,不用编写sql语句,以面向对象的方式来做数据库操作。这种方式在实际开发中使用起来对开发人员要求更加高。

公司的实际应用中,mybatis与jpa使用频繁。

3.40分钟入门案例

  • 创建java项目,添加依赖项

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
​
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
  • 创建数据库表,与对应的实体类

CREATE TABLE `sys_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uname` varchar(50) DEFAULT NULL,
  `upwd` varchar(100) DEFAULT NULL,
  `uphone` char(11) DEFAULT NULL,
  `uemail` varchar(40) DEFAULT NULL,
  `uwechat` varchar(30) DEFAULT NULL,
  `usex` varchar(5) DEFAULT NULL,
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='系统管理-用户表';
  • 创建mybatis风格的xml配置文件与映射文件

配置文件:
<configuration>
​
    <!--配置数据库环境,支持多数据库配置-->
    <environments default="dev1">
        <environment id="dev1">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/704a47?characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
​
    <mappers>
        <mapper resource="mapper/sys/sysuser-mapper.xml"></mapper>
    </mappers>
</configuration>
映射文件:
<?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="a.b">
    <select id="getById" resultType="com.javasm.sys.entity.SysUser">
        select * from sys_user where id=#{azzz}
    </select>
</mapper>

注意点:切记切记把映射文件配置到配置文件中。

  • 加载xml配置文件,初始化mybatis的核心对象SqlSessionFactory

<mapper namespace="a.b">
    <select id="getById" resultType="com.javasm.sys.entity.SysUser">
        select * from sys_user where id=#{azzz}
    </select>
​
    <select id="getByUname"  resultType="com.javasm.sys.entity.SysUser">
        select * from sys_user where uname =#{aaaa}
    </select>
​
    <select id="listUsers"  resultType="com.javasm.sys.entity.SysUser">
        select * from sys_user
    </select>
</mapper>

4.对mybatis代码进行分析

4.0 SqlSessionFactoryBuilder核心对象

属于设置模式中的构建者模式,一般来说此对象中都有一个build方法;此对象职责为了实例化并初始化一个复杂的单例对象。
生命周期:此对象永不作为全局变量存在,就局部变量,用完即销毁。
方法:build()

4.1 SqlSessionFactory核心对象

实现类是DefaultSqlSessionFactory,此类中有一个成员变量Configuration对象,这个对象是mybatis最最重要的一个配置对象,此配置对象与配置文件,映射文件息息相关。
其实这个sqlSessionFactory对象并不重要,它只是一层外壳,对Configuration进行包装了。
生命周期:全局唯一的单例对象。创建出来就不销毁,直到程序进程关闭。
方法:openSession方法。

4.2 Configuration对象(重要)

影响后续ssm整合学习,影响mybatis向springboot整合的学习

第一个重要属性:Environment属性,是数据库连接池,事务管理,id。
第二个重要属性:mappedStatemetns的Map集合,此集合用来封装对映射文件中的curd标签的解析结果。
生命周期:全局唯一,贯穿mybatis整体。属于最重要对象。
第三个属性:typeAliasRegistry类型别名注册器对象,是个Map,默认有很多内嵌别名:
hashMap
String
int
double

4.3 SqlSession核心对象

实现类:DefaultSqlSession会话对象,用来执行数据库curd操作,有selectOne,selecList,insert,delete,update等方法。
生命周期:很短暂的,随用随创建,用完即销毁。绝对不会是全局,静态。
方法:
    selectOne
    selectList
    insert
    update
    delete
    getMapper(这个最重要)

5.认识mybatis的xml风格的配置文件(不重要)

1.environments标签配置数据库环境,启用事务管理,启用连接池。
2.mappers标签配置映射文件。
3.properties引用外部properties资源配置文件
4.settings标签,用来改变mybatis的默认运行行为的。
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/></setting>
    </settings>
5.typeAilas别名标签
   <!--类型别名标签-->
    <typeAliases>
        <!--对指定包下的类全部自动注册别名,类名首字母小写;其实别名是忽略大小写,注意:千万出现同名的类-->
        <package name="com.javasm"></package>
        <!--<typeAlias type="com.javasm.sys.entity.Sysuser" alias="suser"></typeAlias>-->
    </typeAliases>
mybatis默认提供了常用类的内嵌别名:string,int,map,list等

6.认识mybatis的xml风格的映射文件

注意一点:mapper标签的namespace属性,必须有值,而且多个映射文件的namespace不能重复。

6.1 curd操作

insert,update,delete标签,都没有resultType属性。

    <!--
        如果我们传入的参数是个简单类型(String,int,date),#{随便写},因为mybatis底层判断传入的参数是简单类型,则执行把参数作为动态参数赋值。
        如果我们传入的参数是个实体类,#{属性名},因为mybaits底层会把属性名首字母大写,参数.getDname得到动态参数。
    -->
    <!--
        如果数据库表主键自增,需要获取新插入记录的主键,使用useGeneratedKeys="true" keyProperty="id",实际应用中,只有数据量偏小的项目,采用主键自增。
        如果数据库表主键是自己设置,无需考虑获取新增记录主键。
    -->
    <insert id="save" useGeneratedKeys="true" keyProperty="id">
       insert into sys_dept(dname,daddress) values(#{dname},#{daddress})
    </insert>
​

@Test
    public void test4_updateById2() throws IOException {
        InputStream in= Resources.getResourceAsStream("mybatis.xml");
        SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in);
​
        SqlSession sqlSession = f.openSession();//这里打开的会话对象,默认是启用事务控制,对insert,update。delete操作不会自动提交数据库
​
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("n","市场三部");
        map.put("a","aaaaaa");
        map.put("id",4);
        int r = sqlSession.update("com.javasm.sys.sysdeptDao.updateById2", map);
​
        sqlSession.commit();
​
        sqlSession.close();
    }
    
      <update id="updateById2">
        update sys_dept set dname=#{n},daddress=#{a} where id=#{id}
    </update>

    <delete id="delById">
        delete from sys_dept where id=#{id}
    </delete>

6.2动态参数获取

在映射文件中编写sql语句,需要动态参数支持两张写法,#{}或${}.
#{}:mybatis对#{}进行sql解析时,会把解析称为?占位符到sql语句中,然后PreparedStatement进行sql编译,set动态参数。有效避免sql注入攻击。
    
    简单类型参数,#{随便写},因为mybatis底层判断传入的参数是简单类型,则执行把参数作为动态参数赋值。
    实体类参数,#{属性名},因为mybaits底层会把属性名首字母大写,参数.getDname得到动态参数。
    map参数,#{key}
    
${}:mybatis对${}进行解析时,会直接把动态参数拼接到sql语句中.只有一种情况才使用${}获取动态参数.
    动态参数属于sql语法的一部分,(表名,字段名)

6.3 多参数传递

方法1:mybatis底层只支持单参数传递,如果我们有多个参数要传递,需要把多参数封装起来(实体,map)。
方法2:有dao接口的情况下才可以使用,使用@Param注解
​
//mybatis底层会把多个参数封装称为map,默认key:un-uname:up-upwd   param1-uname;param2-upwd
Sysuser getByNameAndPwd(@Param("un") String uname, @Param("up") String upwd);

6.4 模糊查询

使用concat字符串拼接函数:建议使用这种
select * from sys_dept where dname like concat("%",#{dname},"%") 
直接拼接:
select * from sys_dept where dname like "%"#{dname}"%" 

7.getMapper方法(最重要)

分两步来学习,今天学习使用;后天我们来看getMapper方法的源码.

1.定义dao接口;
public interface SysuserDao {
    Sysuser getById(Integer id);
    List<Sysuser> listUsers();
    Sysuser getByNameAndPwd(String uname,String upwd);
    Sysuser getByNameAndPwd2(Map map);
​
    int insert(Sysuser u);
    int update(Sysuser u);
    int delById(Integer id);
}
2.定义映射文件:
<mapper namespace="com.javasm.sys.dao.SysuserDao">
    <insert id="insert">
      insert into sys_user(uname, upwd) values(#{uname},#{upwd})
    </insert>
    <update id="update">
      update sys_user set upwd=#{upwd} where id=#{id}
    </update>
    <delete id="delById">
      delete from sys_user where id=#{id}
    </delete>
    <select id="getById" resultType="com.javasm.sys.entity.Sysuser">
      select * from sys_user where id=#{id}
    </select>
    <select id="listUsers" resultType="com.javasm.sys.entity.Sysuser">
      select * from sys_user
    </select>
    <select id="getByNameAndPwd" resultType="com.javasm.sys.entity.Sysuser">
      select * from sys_user where uname=#{a} and upwd=#{b}
    </select>
    <select id="getByNameAndPwd2" resultType="com.javasm.sys.entity.Sysuser">
      select * from sys_user where uname=#{name} and upwd=#{pwd}
    </select>
</mapper>
<!--映射文件中namespace:必须是dao接口的全名-->
<!--curd标签的id:必须是dao接口中的方法名-->
3.具体使用:
   @Test
    public void test1_getById() throws IOException {
        InputStream in= Resources.getResourceAsStream("mybatis.xml");
        SqlSessionFactory f = new SqlSessionFactoryBuilder().build(in);
        SqlSession s = f.openSession();
        SysuserDao ud = s.getMapper(SysuserDao.class);//得到接口类型的实例化对象
        //当执行SysuserDao对象的getById方法时,底层得到对象的  包名.接口名   ,根据 包名.接口名 得到对应的MapedStatement;在根据接口方法的返回值判断是返回many或one,执行selectOne或selectList方法。
        Sysuser byId = ud.getById(1);
        Map<String,String> map = new HashMap<String, String>();
        map.put("name","fyt");
        map.put("pwd","123456");
        Sysuser byNameAndPwd2 = ud.getByNameAndPwd2(map);
​
        Sysuser u =new Sysuser();
        u.setUname("aaa");
        u.setUpwd("111");
        int r = ud.insert(u);
​
        int i = ud.delById(4);
​
        s.commit();
        s.close();
    }

建议:搭建安装mybatisX插件,帮助我们做dao接口与映射文件之间的联动。

9.常见异常

异常产生原因:sqlSession.方法()第一个字符串参数写错了
IllegalArgumentException: Mapped Statements collection does not contain value for a.b.getById
映射文件路径错误
IOException: Could not find resource mapper/sys/sysUser-mapper1.xml
同一个映射文件中,curd标签的id重复。
IllegalArgumentException: Mapped Statements collection already contains value for a.b.getByUname. please check mapper/sys/sysuser-mapper.xml and mapper/sys/sysuser-mapper.xml

参数类型不一致
ClassCastException: java.lang.String cannot be cast to java.lang.Integer
ReflectionException: There is no getter for property named 'a' in 'class com.javasm.sys.entity.Sysdept'

总结:

orm框架的概念;

mybatis的核心对象:Configuration,sqlSessionFactory,SqlSession

curd操作:

多参数传递:

#{}与${}

getMapper方法的使用

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值