MyBaties入门
1.什么是mybatis,有什么用?
- Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时 只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性 能,灵活度高。
- MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数 据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
- 通过 xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最 后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。(从执行 sql 到返 回 result 的过程)
orm(Object Relational Mapping)
对象关系映射框架
实体类映射到一个数据库表,类中的属性映射到表的字段
(执行效率 高–>低) jdbc–>dbutils–>mybatis–>hibernate,jpa,mp
优点:
- 基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任 何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。
- 与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不 需要手动开关连接;
- 很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库 MyBatis 都支持)。
- 提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射 标签,支持对象关系组件维护。
2.快速入门
- 创建java工程
- 添加mybatis与mysql数据库驱动包。
- 在mysql数据库下创建数据库表。
- 在entity包下创建数据库表对应的实体类。
- 在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>
- 在类路径下创建mybatis的xml核心配置文件,注意引入映射文件。
- 使用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">
- 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>
- environments标签,用来配置数据库连接信息.
- mappers标签,用来加载外部的xml映射文件
- settings标签,用来修改mybatis运行的默认行为.
<settings>//展示自带的日志<setting name="logImpl" value="STDOUT_LOGGING"/>//数据库用连字符起字段名的忽略.把数据库中的_分割的列名,映射到实体类的驼峰属性名<setting name="mapUnderscoreToCamelCase" value="true"></setting></settings>
- 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
映射文件的namespace写为当前映射文件对应的接口类的全类名
<mapper namespace="com.javasm.dao.UserDao">
创建对应实体类的接口写方法和映射文件的id值相同
测试类调用
//传入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.模糊查询
- 在映射文件中的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设计模式
记忆框架的使用,
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入门相关推荐
- Mybaties入门介绍
2019独角兽企业重金招聘Python工程师标准>>> Mybaties和Hibernate是我们在Java开发中应用的比较多的两个ORM框架.当然,目前Mybaties正在慢慢取代 ...
- spring入门详细教程(五)
前言 本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/ ...
- Mybatis最入门---代码自动生成(generatorConfig.xml配置)
[一步是咫尺,一步即天涯] 经过前文的叙述,各位看官是不是已经被Mybatis的强大功能给折服了呢?本文我们将介绍一个能够极大提升我们开发效率的插件:即代码自动生成.这里的代码自动生成包括,与数据库一 ...
- Spring5——(一)spingIOC(入门介绍,spring创建bean,依赖,注入,注解方式)
为什么要有框架? (1)对于web层来说,一个大型的程序往往需要编写大量的servlet,并且取值封装会非常繁琐. (2)对于dao层,要编写大量的sql语句,对于结果的解析也很麻烦,并且sql的复用 ...
- 用Construct 2制作入门小游戏~
今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...
- Docker入门六部曲——Swarm
原文链接:http://www.dubby.cn/detail.html?id=8738 准备工作 安装Docker(版本最低1.13). 安装好Docker Compose,上一篇文章介绍过的. 安 ...
- Docker入门六部曲——Stack
原文链接:http://www.dubby.cn/detail.html?id=8739 准备知识 安装Docker(版本最低1.13). 阅读完Docker入门六部曲--Swarm,并且完成其中介绍 ...
- Docker入门六部曲——服务
原文链接:http://www.dubby.cn/detail.html?id=8735 准备 已经安装好Docker 1.13或者以上的版本. 安装好Docker Compose.如果你是用的是Do ...
- 【springboot】入门
简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...
- SpringBoot (一) :入门篇 Hello World
什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不 ...
最新文章
- php获取请求路径_如何获取php.ini文件路径?
- [译] 探究 Swift 中的 Futures Promises
- 全球及中国太阳能硅片产业供需走势及投资建设前景分析报告2021-2027年
- pc寄存器or程序计数器
- Java 25 岁生日快乐!
- tensorflow和python版本不一样_相比Tensorflow2和PyTorch,TensorFlow1.x版本有什么弊端?...
- EJB3.0 Timer
- win11天气小组件如何开启 Windows11开启天气组件的设置方法
- 苹果M1芯片版Mac出现重装系统Bug,如何正确重装 macOS
- Android使用本地广播
- flash制作文字笔顺_汉字标准读音与笔顺Flash版
- 微软拼音清除自定义短语的方法
- Spring Date JPA -自定义操作(Querydsl)
- 摄影师的“伟大”!分享一组高大上的“照骗”的前期与后期
- nodejs之pathinfo/pathname的使用
- RFID手持机助力仓储物流信息化管理
- android 融云群组列表,群组中 @ 功能介绍
- 洛谷 P1016 旅行家的预算
- java银行安全性_Java使用同步方法解决银行取钱的安全问题案例分析
- CMNET vs CMWAP
热门文章
- 20170825阿里在线笔试之菜鸟仓库货架格子编号
- java图的拓扑排序,本周算法:图的拓扑排序,本周算法拓扑排序
- fisco bcos console控制台 调用合约报错 does not exist
- 微信小程序 云开发 和 传统服务器 对比 区别
- Linux ubuntu基本知识
- Kubernetes 小白学习笔记(12)--搭建一个kubernetes集群-安装dashboard和heapster并验证集群安装结果
- 比特币交易的脚本如何执行
- 中虚数怎么表示_虚数是负数的平方根,为什么在三次方程中才出现的呢?|高中篇3...
- python字典默认排序_Python字典练习:设置默认获取排序,小,知识点,setdefaultgetsorted...
- 基于springboot的高校后勤系统