![bcc315c2cad88272d93526f62a72453f.png](https://i-blog.csdnimg.cn/blog_migrate/b4836eb98c549ec57ebe38d49647e836.jpeg)
入门:
数据库列名与实体类的属性名一致,无需dao接口实现类,导入需要的相应的pom坐标
- xml配置
- 主配置文件:在<configuration></configuration>标签中配置数据库连接和映射配置文件位置。
![b914f63203666200ccf01109e43b2343.png](https://i-blog.csdnimg.cn/blog_migrate/d485d50567c16864f75e54b6576cf5b9.jpeg)
- 主配置文件:
- 在<mapper></mapper>标签下配置相应的具<select>/<update>/<insert>/<delete>标签。
- 配置过程中体现:namespace+id 为需要绑定的查询数据库的dao层接口方法
- "ResultType"体现返回值类型,"parameterType"体现参数类型,有就配上。
![7f57cdaf8a72c16c91047d66cbc356e8.png](https://i-blog.csdnimg.cn/blog_migrate/7ffd8759dc26fc2980e5b1a64526a705.jpeg)
- 注解配置:删除xml配置文件,在dao层接口方法上添加注解,修改主配置文件的<mapper></mapper>标签内容
![3b1ce9ca412cf011d0c376030e29545e.png](https://i-blog.csdnimg.cn/blog_migrate/c3fef6ff9092f69994ce1a970b822078.jpeg)
![c276b72ad8ca4caf0e1156a9591680dd.png](https://i-blog.csdnimg.cn/blog_migrate/b1ea334642db33cd5779526ba7ff80eb.jpeg)
![a9823e6837180fccc44f1ecfd03c3269.png](https://i-blog.csdnimg.cn/blog_migrate/63012b695573c3bedde0808a89eb578c.jpeg)
- 测试:
![0b55b3b846f82d2fe432f84083571ce7.png](https://i-blog.csdnimg.cn/blog_migrate/95a5b7604193c6fa641f7d6eaa8ed07f.jpeg)
- 结果:
![ad92ea9e78fb1e7d6db5543db978b798.png](https://i-blog.csdnimg.cn/blog_migrate/e03cf9a2a52df71c73d274a0a399d4ea.jpeg)
入门总结:
- 测试类编写思路:1.解析配置文件2.创建sqlSessionFactory对象3.获取代理对象4.获取实体类接口对象5.执行实体类方法6.释放资源 (用到了工厂模式、构建者模式、代理模式)
- 主配置配置文件中,在<configuration></configuration>标签中先配置<environments></environments>;再配置对应dao的mapper的resource属性是文件夹形式 resource="com/phonydao/StaffDao.xml;(配置文件位置),还可以用package标签(别名时使用)、class标签 (<mapper class="com.phony.dao.StaffDao"/>注解配置时使用)
- mybatis的映射配置文件位置(全限定类名)必须和dao的接口的包结构相同。
- 注解开发步骤: 1.注解开发,把resources具有相同包结构dao配置xml文件删除,在dao层的接口方法上写注解,并在SqlMapConfig.xml中mapper改为使用class即可,具体在dao层接口上使用@select注解,并指定sql语句,同时在【SqlMapConfig.xml中mapper中配置class属性】,属性值为dao接口的全限定类名
Dao层开发:
MyBatis支持Dao层实现类的实现:(新手看看就好,面向对象编程)测试类创建好“含有内容”的工厂,通过创建dao层实现类对象把工厂传入dao层,在实现类中创建该工厂私有变量,以及参数为该工厂的构造方法。之后利用传过来的工厂获取session对象,再去调用各种操作数据库的方法如:selectList、selectOne、update...,参数都为dao接口的方法的全限定类名,当方法存在参数,那么调用的这个方法需要增加第二个参数:
![640de6e260e3d8b850ac66719f930984.png](https://i-blog.csdnimg.cn/blog_migrate/290fb0e02511274eb78f8e98ea4d9d4a.jpeg)
![85a31c4e916e95f3867b66188f228611.png](https://i-blog.csdnimg.cn/blog_migrate/50af52fb524c21403fbd23e84376118a.jpeg)
下面详述几个dao层开发时配置文件的细节问题:
1、插入操作存在数据库乱码问题,在主数据库配置文件中,url属性增加字符设置,后面数据库配置在外部文件时,也是一样添加字符设置,略有不同。
<property name="url" value="jdbc:mysql://localhost:3306/java-web?useUnicode=true&characterEncoding=UTF-8"></property>
2、所有操作都需要利用session对象关闭资源,除查询对象外,需要提交事务操作。
![99c4de9d16af6f45147e07dd3d17ac96.png](https://i-blog.csdnimg.cn/blog_migrate/17fda4b355d6d4bcca93e5463c14c853.jpeg)
3、(基础)实体类可以包装实体类。当实现类的方法参数设置:
3.1、单独一个参数时可以在被调用时直接加上:
![00945a980eff95018b9884c8f72244e7.png](https://i-blog.csdnimg.cn/blog_migrate/ef4fdddb2f909b237c7b0829a9c441b9.jpeg)
3.2、实体类作为参数时,需要创建实体类对象,并在被调用方法下创建对象,并给对象赋值:
![e6fe90fed6b68cd053ac829cabebca0d.png](https://i-blog.csdnimg.cn/blog_migrate/2b682f296956ea8db30c63f95837eeac.jpeg)
3.2.1、当设置的涉及到数据库主键字段id时,其他操作没影响,需要注意的是新增操作 时,id的值。dao映射配置文件没有在sql语句中设置id,那么语句可以正常执行,控制台打印id=0,数据库却在自增长(前提设置了id自增长);dao映射配置文件在sql语句中设置id,只要与数据库已存在id不重复即可。
这里提供配置一个 获取插入操作后id的值:
keyProperty:实体类主属性;keyColumn:数据库表主键字段;order:设置在操作前/后获取;最后注意sql的编写。
![960ca5bd01a1878bd6c6f842583a3d06.png](https://i-blog.csdnimg.cn/blog_migrate/df0cedc4a0783243e903ac82e617d710.png)
4、映射配置文件相关细节:
4.1、sql语句的参数格式 #{xxx};
4.2、parameterType:参数类型(例:parameterType="com.phony.domain.staff"、parameterType="Integer")、resultType:返回类型(同上)
ps:当参数类型为一个基本类型(包装类),参数的#{}中可以随意写,不必按照实体类属性名
4.3、模糊查询时参数的两种写法:#{xxxx} 、'%${value}%' 一定要有LIKE 后者一定是value:前者直接达成占位符效果,只是调用时参数两边要加上%;后者被调用时直接加参数就行了。
4.4、当参数是包装实体类的实体类,创建包装实体类的实体类,使用OGNL思想,参数类型选包装实体类,#{}中填写被包装的实体类再点需要的属性。被调用时一层一层往上保存
![2448984cd628573786e438f285555528.png](https://i-blog.csdnimg.cn/blog_migrate/dec56de2ca71765f2cf757fac5d83490.jpeg)
![f033be392934cc7d14bc7dcc9c8c31a6.png](https://i-blog.csdnimg.cn/blog_migrate/ee34fd5895bb5c8abb32fad5592f2c77.jpeg)
4.5、数据库与实体累属性名称不一致时处理方案:
1.可以在映射配置文件中sql语句起别名;#{}中写实体类的属性名,重命名的是sql语句操作数据库字段后AS为实体类字段,多个参数用 逗号隔开。
![f8f3ad4f509de95500b6e60a71a1292e.png](https://i-blog.csdnimg.cn/blog_migrate/a2e4aba6e779fa3d2b1e3b80661678bb.png)
2.映射配置文件中添加配置操作;配置<resultMap></resultMap>标签
![41171c65db743eb1fc93eacd2c030537.png](https://i-blog.csdnimg.cn/blog_migrate/e5b750fbe5e1fb217a668360c15fa161.jpeg)
Type的值原先应该是实体类的全限定类名,由于在主配置文件mappers标签中用package标签配置,所以这里用别名就可以了
5、关于在外部配置数据库连接信息:
![c2a0b9fc151afa03b50b09d14768fe54.png](https://i-blog.csdnimg.cn/blog_migrate/7e448abcc5d8961b9eed7251a8df8e85.png)
![1a65a6d03e6649e309ff9797c96378ac.png](https://i-blog.csdnimg.cn/blog_migrate/43979ac4865daab4af72b5314a20dd15.png)
![651a9face93b63122162a84a110931c0.png](https://i-blog.csdnimg.cn/blog_migrate/606ef54cf6085b37a250c81189c40b1b.png)
jdbc:mysql://localhost:3306/java-web?useUnicode=true&characterEncoding=UTF-8
这个配置参数在配置信息转移到外部配置文件时,需要更改这样模糊查询就不会查询不到数据了
jdbc.url=jdbc:mysql://localhost:3306/java-web?characterEncoding=UTF-8
6、在主配置文件中给dao层映射配置文件用到该实体类时配置的别名:package标签配置时标识包类所有实体类被使用时都可以用类名做别名。
![c3b50757453868f1b850a5e844ee6cb6.png](https://i-blog.csdnimg.cn/blog_migrate/8beb57c9f83f19c6921ac199515d6793.jpeg)
动态Sql
1、数据库与实体类映射。数据库字段与实体类属性不一致时,在映射配置文件中首要配置相应的映射关系:那么当操作返回实体类型时,我们不用写resultType属性了,需要写resultMap属性了
![e2a10f1a232e780efb91d8f9d45a6283.png](https://i-blog.csdnimg.cn/blog_migrate/2c22d38efa017d9c38cbfe627974886e.jpeg)
![c36bda309b18430098c57c7e3e1fab83.png](https://i-blog.csdnimg.cn/blog_migrate/5934a376a765d9d75a8a3c1909141d17.png)
2、使用<sql></sql>标签可以对常用的sql语句进行封装。
![d798078dfe67409dccf6c7347cd08a92.png](https://i-blog.csdnimg.cn/blog_migrate/a16bf59ee90979656111146023461bc4.png)
使用include标签引用:
![c61c35cb7759bbc8693ef990c8567e80.png](https://i-blog.csdnimg.cn/blog_migrate/c6ac37c98b48ba41dff6dec267c83470.png)
<sql></sql>标签中不一定是完整的sql语句,只要是今后开发中出现次数比较多的都可放在里面,只要注意拼接的细节即可。
3、动态sql--if标签的使用。前提是sql语句结尾添加了WHERE 1=1,再去使用if标签,使用test标签属性做一个是否为空的判断,不为空if标签体内 AND开头做sql拼接(一般是WHERE的条件句)
![6057bf66d1260677f81483f63f49e00e.png](https://i-blog.csdnimg.cn/blog_migrate/11fc025c9a3d87ac3393b55c049def01.png)
多个条件就多个if标签拼接:
![a28d51834cb1a3861e7b91c2bcd0692d.png](https://i-blog.csdnimg.cn/blog_migrate/13424512a93e1aba12fce850165374d2.jpeg)
ps:实体类属性名可以写在#{}里、if标签test属性判断值。
4、动态sql--where标签的使用。用where标签包裹if标签,之前需要的前替就不没有了。
![c21209ab913dfffe2725fbdef446295b.png](https://i-blog.csdnimg.cn/blog_migrate/12624915599d346e12891b81744f4b4c.jpeg)
5、动态sql--foreach标签的使用。满足带有IN的子查询,如给定一个id集合,查询所有id的用户。在包装实体类中设定集合对象(方便被调用时设值);在where标签下嵌套if标签,if标签验证集合是否为空(多个判断依据用and连接,and切记不要大写);if标签体中在嵌套foreach标签,collection属性值为实体类集合名,open、close属性拼接"AND id IN ()",item属性为遍历集合的单个值,separator属性为IN中分隔符;foreach标签体内需要写#{xxx},xxx必须和item属性值一致。
![1535c188881c19f3df9bcce484fb3d8a.png](https://i-blog.csdnimg.cn/blog_migrate/bde6eb3747038da50fa7a4ab4fceda0c.jpeg)
![c577c2a607397980fab2db8e5eb571e7.png](https://i-blog.csdnimg.cn/blog_migrate/b1cc56657dd3f49bdd1bd47363ae0ab0.jpeg)
![09be01d4f8cbb129fbff4ea52e56fe3a.png](https://i-blog.csdnimg.cn/blog_migrate/22b8afdf3a5a302ddd036450ea2412f3.jpeg)
关于事务
- 在测试类中写在destroy方法中
- 在测试类中获取session对象时设置参数为true,便设置成了自动提交事务(不常用)
//当设置参数为true时表明设置了自动提交.init方法就不需要提交事务了
sqlSession = sqlSessionFactory.openSession(true);
多表连接先考虑写好sql,再去配置
一对一
在一个类中设置另一个类对象作为变量,在映射配置文件中配置类与该属性的分装,association标签连接,结合javatype属性
还有一种不常用的继承子类方式,toString加上子类的toString方式
一对多
在一个类中设置另一个类集合引用,在映射配置文件中配置该类与类集合的封装,用collection标签结合ofType属性。
多对多
多对多则互相在实体类中设置另一个实体类对象的属性,并都在映射配置文件中用collection标签结合ofType属性。
缓存
![810abfe65b37758f45d7fb44d495657e.png](https://i-blog.csdnimg.cn/blog_migrate/d03e5eaa5d27cee2a9aa09351433f370.jpeg)
![a7d732dd898da505336c6c479ff55637.png](https://i-blog.csdnimg.cn/blog_migrate/2c2d9981d711c0e3cfe9c446007136b9.jpeg)
一级缓存:指的是Mybatis中的SqlSession对象的缓存
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供的一块区域
该区域的结构是一个Map.当我们再次查询同样的数据,mybatis会先去sqlSession中查询是否有,有的话直接拿出来用
当SalSession对象消失时,mybatis的一级缓存也就消失了
二级缓存:配置中使用ResultMap->association标签中添加select属性配置你需要的查询的全限定类名.方法
![e3fea330312b57b837832bacc19fdbba.png](https://i-blog.csdnimg.cn/blog_migrate/faf90c857bc2d5cf8fc8c917ee1a8cbb.png)
注解开发
![8142a0c6fb5f5b1a1886ebdcb01d1667.png](https://i-blog.csdnimg.cn/blog_migrate/dd5f925b58fb00cedd98f533b121aa29.jpeg)
当数据库字段和实体类属性名不一致时:
![0ae0f4f80c1f3817330cfcaea626f4e1.png](https://i-blog.csdnimg.cn/blog_migrate/303493c1e71064f60e9bda0e82ae80a4.jpeg)
@One注解(一对一)代替了<assocation>标签;@Many注解(多对一)代替了<Collection>标签。
![6dd491597072e850170dce2dda5d9bc6.png](https://i-blog.csdnimg.cn/blog_migrate/974ce724b99ff8f838d7d07028b09446.png)
配合注解完成二级缓存设置。
欢迎指错。。。