1.什么是mybatis,有什么用?

  1. Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时 只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性 能,灵活度高。
  2. MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数 据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
  3. 通过 xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最 后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。(从执行 sql 到返 回 result 的过程)

orm(Object Relational Mapping)对象关系映射框架

实体类映射到一个数据库表,类中的属性映射到表的字段

(执行效率 高–>低) jdbc–>dbutils–>mybatis–>hibernate,jpa,mp

优点

  1. 基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任 何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。
  2. 与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不 需要手动开关连接;
  3. 很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库 MyBatis 都支持)。
  4. 提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射 标签,支持对象关系组件维护。

2.快速入门

  1. 创建java工程
  2. 添加mybatis与mysql数据库驱动包。
  3. 在mysql数据库下创建数据库表。
  4. 在entity包下创建数据库表对应的实体类。
  5. 在mapper包下创建实体类对应的xml映射文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="userMapper"><-- parameterType表示查询参数类型;resultType表示数据库查询结果的每行记录封装类型。--><select id="selectUserByKey" parameterType="int" resultType="User">select * from tb_user where uid = #{uid}</select>
</mapper>
  1. 在类路径下创建mybatis的xml核心配置文件,注意引入映射文件。
  2. 使用mybatis的核心api对象加载配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--加载外部的properties资源文件--><properties resource="jdbc.properties"></properties><settings><setting name="logImpl" value="STDOUT_LOGGING"/><!--开启事物不自动提交手动提交事物--><setting name="mapUnderscoreToCamelCase" value="true"/></settings><!--配置该包下的所有类都有简写的名--><typeAliases><package name="com.javasm.entity"/></typeAliases><!--数据库环境--><environments default="dev"><environment id="dev"><!--事务管理器,使用JDBC的事务管理方法--><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${jdbc.Driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><!--映射文件--><mappers><mapper resource="com\javasm\dao\userMapper.xml"/><mapper resource="com\javasm\dao\userMapper2.xml"/></mappers>
</configuration>

8.测试引入junit4

public class SqlSessionFactoryUtil {private static SqlSessionFactory ssf=null;static{InputStream input = null;try {input = Resources.getResourceAsStream("mybatis-config.xml");} catch (IOException e) {e.printStackTrace();}ssf = new SqlSessionFactoryBuilder().build(input);}public static SqlSessionFactory getSqlSessionFactory(){return ssf;}
}② 创建junit测试类
public class TestStart {private static SqlSessionFactory ssf = null;private SqlSession session = null;@BeforeClasspublic static void initFactory() {ssf = SqlSessionFactoryUtil.getSqlSessionFactory();}@Beforepublic void openSession() {session = ssf.openSession();}@Testpublic void testGetUserById() throws IOException {//SqlSession的selectOne方法的第一个参数是namespace.id组成的字符串,//第二个参数是查询参数,且当前只能传入一个参数。Object result = session.selectOne("userMapper.getUserById", 1);System.out.println(result);}@Afterpublic void closeSession() {session.close();}@AfterClasspublic static void closeFactory() {ssf = null;}
}

3.mybatis的核心对象(重要)

1.SqlSessionFactoryBuilder:构建者模式应用,有build方法,用来构建复杂的单例的SqlSessionFactory对象

生命周期:用完即销毁.其生周期只存在于方法体内,可重用。

2.SqlSessionFactory:工厂模式应用,与构建者的区别在于工厂生产N个对象.实现类:DefaultSqlSessionFactory,该对象中持有的DataSource

生命周期:全局唯一.放在web项目下理解,tomcat启动期间,只有一份Factory.单例

3.SqlSession:数据库会话对象,实现类DefaultSqlSession.该对象内部有curd方法执行数据库表操作.(selectOne,selectList,insert,delete,update,getMapper),只有getMapper方法重要代理模式使用.

生命周期:每次数据库操作临时打开会话,用完关闭会话.需要创建它每个线程都有自己的 SqlSession 实例,SqlSession实例是不能被共享,也不 是线程安全的。

4.dao接口的代理对象:


4.详细了解mybatis的核心文件配置

标签文件有先后顺序.dtd文件能看选后顺序

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
  1. properties标签,用来加载外部properties文件.
 <properties resource="jdbc.properties"></properties>
//引入
<dataSource type="POOLED"><property name="driver" value="${jdbc.Driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/>
</dataSource>
  1. environments标签,用来配置数据库连接信息.
  2. mappers标签,用来加载外部的xml映射文件
  3. settings标签,用来修改mybatis运行的默认行为.
 <settings>//展示自带的日志<setting name="logImpl" value="STDOUT_LOGGING"/>//数据库用连字符起字段名的忽略.把数据库中的_分割的列名,映射到实体类的驼峰属性名<setting name="mapUnderscoreToCamelCase" value="true"></setting></settings>
  1. typeAliases:用来对指定包下的类自动起别名.要求整个项目下不能有同名的类
<typeAliases>//具体类起别名,别名影响的是映射文件中的parameterType与resultType属性<!--<typeAlias type="com.javasm.sys.entity.Sysuser" alias="sysuser"></typeAlias>-->//该包下所有文件起别名,别名就是文件名//不同的包不能起同名的类<package name="com.javasm"></package>
</typeAliases>

5.掌握mybatis的映射文件(重要)

1.映射文件中常用标签
  • select标签:用来执行select语句
<!--parameterType:参数类型,可以写别名resultType:把查询结果的一行记录封装的类型(map,实体对象,String,Double,Integer)如果parameterType是简单类型的话,#{随便写}如果parameterType是实体类,#{类的成员变量名}如果parameterType是map,#{map的key}/params1,params2
-->//简单类型下parameterType可以省略<select id="selectUserByKey" parameterType="int" resultType="sysuser">select * from sysuser where uid=#{uid}</select>
  • insert
<!--生成key模式  主键对应的属性名-->获得自增id
<!-- useGeneratedKeys="true" keyProperty="uid"-->
<insert id="addUser" parameterType="User" useGeneratedKeys="true" keyProperty="uid" >insert into tb_user(uid, uname, uphone) values (#{uid},#{uname},#{uphone})
</insert>
@Test
public void addUser(){User user = new User();user.setUphone("5423423");user.setUname("sdsa");System.out.println(session.insert("userMapper.addUser", user));//返回受影响的行记录数  System.out.println(user.getUid());//返回刚刚新增的idsession.commit();//配置文件开启了事物
}
  • update
<update id="updataUser" parameterType="user">update tb_user set uname=#{uname},uphone=#{uphone} where uid=#{uid}
</update>
@Test
public void updataUser() {User user = new User();user.setUid(9);user.setUname("赵鑫阳a");System.out.println(session.update("userMapper.updataUser", user));//受影响行记录数session.commit();
}
  • delete
<delete id="delUserById" parameterType="int">delete from tb_user where uid=#{uid}
</delete>
@Test
public void delUser() {System.out.println(session.delete("userMapper.delUserById", 9));session.commit();
}
2.#{}与${}使用

两者都是用来获取参数拼接sql.

#{}:mybatis内会使用PreparedStatement对象进行sql语句预编译,使用**?参数占位符**来传参,防止sql注入攻击.查询参数必须使用#{}

${}:不使用?占位符传参,而是字符串替换,就是把{}替换成变量的值,大多数用在对表格指定字段的排序使用,传入排序字段和排序规则(select * from user order by id)这个id是指定字段不能使数据/查询指定字段


6.getMapper

  1. 映射文件的namespace写为当前映射文件对应的接口类的全类名

    <mapper namespace="com.javasm.dao.UserDao">

  2. 创建对应实体类的接口写方法和映射文件的id值相同

  3. 测试类调用

//传入dao接口的类对象,返回的是指定类的代理对象,映射文件的namespace必须是dao接口的全名
@Test
public void selectUserByKey() {//传入一个接口对象返回一个接口的代理对象UserDao mapper = session.getMapper(UserDao.class);User user = mapper.selectUserByKey(4);//根据类名,方法名==namespace.id,底层仍然调用selectOneSystem.out.println(user);
}

xml映射文件中的namespace不再随意,必须是mapper接口的名称(含包名)。

调用SqlSession会话对象方法时,通过getMapper方法返回mapper接口类型的对象是当前接口的代理对象


6.多参数操作

  • 把多个参数封装到map

    User selectUserByIdAndPhone(User user);

  • 把多个参数封装到实体对象

    User selectUserByIdAndPhone2(Map<String,Object> map);

  • 在dao接口的方法中仍然保持多形参,形参前使用@Param注解,这种方式是mybatis底层把多个参数封装到map.map的key默认0,1,2…或者param1,param2…也可以通过@Param注解指定key

    User selectUserByIdAndPhone3(@Param("uid_key") Integer uid,@Param("uphone_key") String phone);


7.模糊查询

  1. 在映射文件中的sql语句中使用%
<select id="selectUsersByPhone" parameterType="String" resultType="sysuser">//idea环境下这个语句会报错但是不影响运行select * from sysuser where uphone like "%"#{uphone}"%"
</select>

2.传入的字符串参数中带有%

@Test
public void test4_selectUsersByPhone() {SysuserDao mapper = session.getMapper(SysuserDao.class);List<Sysuser> sysusers = mapper.selectUsersByPhone("%2%");System.out.println(sysusers);
}

8.查询结果返回map

对于复杂的多表级联查询,返回结果无法封装实体类,建议resultType=“map”,直接封装为map对象即可

1.两表联查询单个结果集

  Map<String,Object> seletUserAndPowerById(Integer uid);
 <select id="seletUserAndPowerById" parameterType="int" resultType="map">select * from tb_user u,tb_power p where p.uid=u.uid and u.uid=#{uid}</select>
@Test
public void seletUserAndPowerById() {UserDao mapper = session.getMapper(UserDao.class);Map<String, Object> map = mapper.seletUserAndPowerById(4);System.out.println(map);session.commit();
}

1.两表联查询多个结果集

List<Map<String,Object>> seletUserAndPowerById(Integer uid);
<select id="seletUserAndPowerById" parameterType="int" resultType="map">select * from tb_user u,tb_power p where p.uid=u.uid and u.uid=#{uid}
</select>
@Test
public void seletUserAndPowerById() {UserDao mapper = session.getMapper(UserDao.class);List<Map<String, Object>> list = mapper.seletUserAndPowerById(4);System.out.println(list);session.commit();
}

注意点:

  • 需要命名的地方,绝对不允许单个单词;

  • 类的成员变量不建议long,不允许基本类型(Long数据,前端js代码不支持,数据丢失精度)

  • 表字段名不允许u_name/uName(一个字母_单词)set,get方法名不规范,成员变量名不允许uName;成员变量名不允许is开头;

  • 表中类型datetime,date,timestamp,实体类的成员变量类型,建议使用String;

  • 23种gof设计模式


  1. 记忆框架的使用,

  2. mybatis常见错的位置:

常见错误
  • 映射文件忘记在配置文件引入.(配置文件中的mapping忘记写)
//Mapped Statements collection does not contain value for userMapper.selectUserByKey
  • 映射文件中的namespace与id在写的时候写错
//Mapped Statements collection does not contain value for userMapper.selectUserByKeys
  • 映射文件中的id重复了
//Mapped Statements collection already contains value for userMapper.selectUserByKey
  • properties文件的配置不加载,key很可能写的单个单词
//url--->jdbc.url

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。

设置名 描述 有效值 默认值
cacheEnabled 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true | false true
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 true | false false
aggressiveLazyLoading 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。 true | false false (在 3.4.1 及之前的版本中默认为 true)
useGeneratedKeys 允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。 true | false False
defaultExecutorType 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。 SIMPLE REUSE BATCH SIMPLE
defaultStatementTimeout 设置超时时间,它决定数据库驱动等待数据库响应的秒数。 任意正整数 未设置 (null)
defaultResultSetType 指定语句默认的滚动策略。(新增于 3.5.2) FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(等同于未设置) 未设置 (null)
safeRowBoundsEnabled 是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。 true | false False
safeResultHandlerEnabled 是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false。 true | false True
mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。 true | false False
logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 未设置
proxyFactory 指定 Mybatis 创建可延迟加载对象所用到的代理工具。 CGLIB | JAVASSIST JAVASSIST (MyBatis 3.3 以上)

MyBaties入门相关推荐

  1. Mybaties入门介绍

    2019独角兽企业重金招聘Python工程师标准>>> Mybaties和Hibernate是我们在Java开发中应用的比较多的两个ORM框架.当然,目前Mybaties正在慢慢取代 ...

  2. spring入门详细教程(五)

    前言 本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/ ...

  3. Mybatis最入门---代码自动生成(generatorConfig.xml配置)

    [一步是咫尺,一步即天涯] 经过前文的叙述,各位看官是不是已经被Mybatis的强大功能给折服了呢?本文我们将介绍一个能够极大提升我们开发效率的插件:即代码自动生成.这里的代码自动生成包括,与数据库一 ...

  4. Spring5——(一)spingIOC(入门介绍,spring创建bean,依赖,注入,注解方式)

    为什么要有框架? (1)对于web层来说,一个大型的程序往往需要编写大量的servlet,并且取值封装会非常繁琐. (2)对于dao层,要编写大量的sql语句,对于结果的解析也很麻烦,并且sql的复用 ...

  5. 用Construct 2制作入门小游戏~

    今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...

  6. Docker入门六部曲——Swarm

    原文链接:http://www.dubby.cn/detail.html?id=8738 准备工作 安装Docker(版本最低1.13). 安装好Docker Compose,上一篇文章介绍过的. 安 ...

  7. Docker入门六部曲——Stack

    原文链接:http://www.dubby.cn/detail.html?id=8739 准备知识 安装Docker(版本最低1.13). 阅读完Docker入门六部曲--Swarm,并且完成其中介绍 ...

  8. Docker入门六部曲——服务

    原文链接:http://www.dubby.cn/detail.html?id=8735 准备 已经安装好Docker 1.13或者以上的版本. 安装好Docker Compose.如果你是用的是Do ...

  9. 【springboot】入门

    简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...

  10. SpringBoot (一) :入门篇 Hello World

    什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不 ...

最新文章

  1. php获取请求路径_如何获取php.ini文件路径?
  2. [译] 探究 Swift 中的 Futures Promises
  3. 全球及中国太阳能硅片产业供需走势及投资建设前景分析报告2021-2027年
  4. pc寄存器or程序计数器
  5. Java 25 岁生日快乐!
  6. tensorflow和python版本不一样_相比Tensorflow2和PyTorch,TensorFlow1.x版本有什么弊端?...
  7. EJB3.0 Timer
  8. win11天气小组件如何开启 Windows11开启天气组件的设置方法
  9. 苹果M1芯片版Mac出现重装系统Bug,如何正确重装 macOS
  10. Android使用本地广播
  11. flash制作文字笔顺_汉字标准读音与笔顺Flash版
  12. 微软拼音清除自定义短语的方法
  13. Spring Date JPA -自定义操作(Querydsl)
  14. 摄影师的“伟大”!分享一组高大上的“照骗”的前期与后期
  15. nodejs之pathinfo/pathname的使用
  16. RFID手持机助力仓储物流信息化管理
  17. android 融云群组列表,群组中 @ 功能介绍
  18. 洛谷 P1016 旅行家的预算
  19. java银行安全性_Java使用同步方法解决银行取钱的安全问题案例分析
  20. CMNET vs CMWAP

热门文章

  1. 20170825阿里在线笔试之菜鸟仓库货架格子编号
  2. java图的拓扑排序,本周算法:图的拓扑排序,本周算法拓扑排序
  3. fisco bcos console控制台 调用合约报错 does not exist
  4. 微信小程序 云开发 和 传统服务器 对比 区别
  5. Linux ubuntu基本知识
  6. Kubernetes 小白学习笔记(12)--搭建一个kubernetes集群-安装dashboard和heapster并验证集群安装结果
  7. 比特币交易的脚本如何执行
  8. 中虚数怎么表示_虚数是负数的平方根,为什么在三次方程中才出现的呢?|高中篇3...
  9. python字典默认排序_Python字典练习:设置默认获取排序,小,知识点,setdefaultgetsorted...
  10. 基于springboot的高校后勤系统