一:走进MyBatis

框架:1:是一系列jar包,其本质是对JDK功能的拓展.2:框架是一组程序的组合,包含了一系列的最佳实践,作用是解决某一个领域的问题.
WEB开发中的最佳实践:根据职责的纵向划分:控制层 业务层  持久层控制层:WEB/MVC: 负责处理页面交互的相关操作(Struts2/Spring MVC)业务层:service: 负责复杂的业务逻辑计算和判断(Spring)持久层:dao:     负责将业务逻辑数据进行持久化存储(MyBatis/Hibernate)![最佳实践图](https://img-blog.csdn.net/20180325191939870?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
ORM框架:遵循ORM思想实现的技术,解决的是持久层的问题(和数据库做CRUD):一个良好的持久层应该保证:当持久层的实现技术改变的时候,不会影响上一层的代码(service).![ORM思想](https://img-blog.csdn.net/20180325192600523?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
MyBatis:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(PlainOld Java Objects,普通的 Java对象)映射成数据库中的记录。https://mybatis.github.io/mybatis-3/zh/index.html 手册里面足够学习了

二:基础操作:

MyBatis依赖jar包:  在github下载里面有好多好的项目源码 多动手敲代码    1):MySQL驱动包:mysql-connector-java-5.1*jar2):核心包:mybatis-3.54.jar3):其他依赖.lib目录中所有的jar(有需要再拷贝)mysql-connector-java-5.1.40.jar![MyBatis的配置文件AND映射文件](https://img-blog.csdn.net/2018032519482747?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)![MyBatis-Config.xml](https://img-blog.csdn.net/2018032519520899?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
日志文件的输出:先拷贝jar包:slf4j-api-1.7.21.jarslf4j-log4j12-1.7.21.jar并配合log4j-1.2.17.jar一起使用log4j.properties文件内容:#设置全局的日志配置:输出Error级别,输出到控制台  日志的级别:ERROR>WARN>INFO>DEBUG>TRACE级别越低,输出的信息越详细log4j.rootLogger=ERROR, stdout#设置自定义的日志级别  每次记得修改包名log4j.logger.cn.wolfcode.mybatis.hello=TRACElog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
OGNL表达式:![OGNL表达式](https://img-blog.csdn.net/20180325201451932?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
resultMap:主要解决表的列名跟属性名称不匹配的问题:![resultMap](https://img-blog.csdn.net/20180325202006482?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
Mapper接口:Mapper接口的原理:动态代理:Spring的时候重点来讲解![Mapper组件](https://img-blog.csdn.net/20180325202550225?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
参数处理://方式一:把多个参数封装成一个JavaBeanClient login1(LoginVO vo);//方式二:使用Map对象来封装多个参数Client login2(Map<String, Object> paramMap);//方式三:使用Param注解,原理是方式二Client login3(@Param("username")String username,@Param("password")String password);List<Client> login4(@Param("orderby")String orderby);
    <select id="login1" parameterType="LoginVO" resultType="client">SELECT id,username,password FROM client Where username = #{username}AND password = #{password}</select><select id="login2" parameterType="map" resultType="client">SELECT id,username,password FROM client Where username = #{username1}AND password = #{password1}</select><select id="login3" resultType="client">SELECT id,username,password FROM client Where username = #{username}AND password = #{password}</select><select id="login4" resultType="client">SELECT id,username,password FROM clientORDER BY ${orderby}</select>
    @Testpublic void testLogin1() throws Exception {LoginVO vo = new LoginVO("will","1111");SqlSession session = MyBatisUtil.getSession();ClientMapper clientMapper = session.getMapper(ClientMapper.class);Client client = clientMapper.login1(vo);session.close();System.out.println(client);}@Testpublic void testLogin2() throws Exception {Map<String,Object> paramMap = new HashMap<String,Object>(){{this.put("username1", "will");this.put("password1", 1111);}};SqlSession session = MyBatisUtil.getSession();ClientMapper clientMapper = session.getMapper(ClientMapper.class);Client clietn = clientMapper.login2(paramMap);session.close();System.out.println(clietn);}@Testpublic void testLogin3() throws Exception {SqlSession session = MyBatisUtil.getSession();ClientMapper clientMapper = session.getMapper(ClientMapper.class);Client clietn = clientMapper.login3("will","1111");session.close();System.out.println(clietn);}@Testpublic void testLogin4() throws Exception {SqlSession session = MyBatisUtil.getSession();ClientMapper clientMapper = session.getMapper(ClientMapper.class);List<Client> clietn = clientMapper.login4("id desc");session.close();for (Client c : clietn) {System.out.println(c);}}
    ![参数处理# &](https://img-blog.csdn.net/20180325203955827?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
MyBatipse插件:MyBatipse是Eclipse的一个插件,提供了内容提示和MyBatis的配置文件验证功能!

三:注解开发

开发和配置MyBatis框架:方式一:使用XML配置,把SQL和映射写在XML文件中.   推荐!方式二:使用注解配置,把SQL和映射写在JAVA代码中(Mapper接口).
public interface UserMapper {@Insert("insert into t_user value (#{id},#{name},#{salary})")@Options(useGeneratedKeys=true,keyProperty="id")void save(User u);@Update("UPDATE t_user set name = #{name}, salary = #{salary} where id = #{id}")void update(User u);@Delete("DELETE FROM t_user WHERE id = #{id}")void delete(Long id);@Select("SELECT * FROM t_user WHERE ID = #{id}")@Results(id="BaseResultMap",value={@Result(column="id",property="id"),@Result(column="name",property="name"),@Result(column="salary",property="salary")})User get(Long id);@Select("SELECT * FROM t_user")@ResultMap("BaseResultMap")List<User> listAll();
}
    既然修改了mapper文件,那么mybatis-config.xml文件中修改为<mapper> <mappec class=""/> </mapper>

四:动态SQL

choose:选择,跟if  else 一个意思<choose><when test="deptId > 0"> AND deptId = #{deptId}</when><otherwise>AND deptId IS NOT NULL</otherwise></choose>
Where:若果条件以AND或者OR开头,就应该替换为WHERE
set:如果中间以有值就输入,最后一个去掉逗号,<set><if test="name!=null">name = #{name},</if><if test="password != null">password = #{password},</if></set>
trim:可以替代where 跟set 一般不用![trim的作用](https://img-blog.csdn.net/20180325213152704?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDE2MTcwOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
mapper文件:public interface EmployeeMapper {List<Employee> query(@Param("minSalary")BigDecimal minSalary,@Param("maxSalary")BigDecimal maxSalary,@Param("deptId") Long deptId);void batchDelete(@Param("ids") List<Long> ids);void batchSave(@Param("emps") List<Employee> emps);
}
        <!-- foreach元素:collection属性:表示对哪一个集合或数组做迭代如果参数是数组类型,此时Map的可以为array如果参数是List类型,此时Map的key为list我们可以在参数上使用Param注解,规定死Map中key是什么.@Param("ids")open属性:在迭代集合之前,拼接什么符号.close属性:在迭代集合之后,拼接什么符号.separator属性:在迭代元素时,每一个元素之间用什么符号分割开来.    item属性:被迭代的每一个元素的变量index属性:迭代的索引   --><delete id="batchDelete">DELETE employee where id in<foreach collection="ids"  open="(" close=")" separator="," item="id">#{id}</foreach></delete>
mysql的批量插入:<insert id="batchSave">inset into employee (name,sn,salary) values<foreach collection="emps" separator="," item="e">(#{e.name},#{e.sn},#{e.salary})</foreach></insert>
查询操作:<select id="query" resultType="Employee">SELECT id,name,sn,salary,deptId From employee<where><if test="minSalary!=null">AND salary >= #{minSalary}</if><if test="maxSalary">AND salary &lt;= #{maxSalary}</if><choose><when test="deptId > 0"> AND deptId = #{deptId}</when><otherwise>AND deptId IS NOT NULL</otherwise></choose></where></select>
bind:可以吧重复的小段代码提出来用sql:把重复的代码包装起来利用他的id调用include:文件中插入sql的代码.

分页查询: 回顾一下这一篇博客的知识点

domain

    <select id="query" resultType="Employee">SELECT id,name,sn,salary,deptId From employee<where><if test="minSalary!=null">AND salary >= #{minSalary}</if><if test="maxSalary">AND salary &lt;= #{maxSalary}</if><choose><when test="deptId > 0"> AND deptId = #{deptId}</when><otherwise>AND deptId IS NOT NULL</otherwise></choose></where></select>

mapper

    public interface EmployeeMapper {List<Employee> queryForList(QueryObject qo);int queryForCount(QueryObject qo);}
    <mapper namespace="cn.wolfcode.mybatis.hello.mapper.EmployeeMapper"><sql id="base_where"><where><if test="keyword != null and keyword != ''"><bind name="keywordLike" value="'%'+keyword+'%'"/>AND (name like #{keywordLike} OR sn LIKE #{keywordLike})</if><if test="minSalary!=null">AND salary >= #{minSalary}</if><if test="maxSalary!=null">AND salary &lt;= #{maxSalary}</if><if test="deptId > 0">AND deptId = #{deptId}</if></where></sql><!-- 查询结果集 --><select id="queryForList" resultType="Employee">Select id,name,sn,salary,deptId FROM employee<include refid="base_where" /><if test="pageSize > 0">LIMIT #{start},#{pageSize}</if></select><!-- 查询结果总数 --><select id="queryForCount" resultType="int">SELECT COUNT(id) FROM employee<include refid="base_where" /></select></mapper>

query

@Getter
@Setter
public class EmployeeQueryObject extends QueryObject{private String keyword;private BigDecimal minSalary;private BigDecimal maxSalary;private Long deptId = -1L;public String getKeyword(){return employ2null(keyword);}
}
@Getter
public class PageResult {private List<?> result;private int totalCount;private int currentPage = 1;private int pageSize = 3;private int prevPage;private int nextPage;private int totalPage;public PageResult(List<?> result, int totalCount, int currentPage, int pageSize) {this.result = result;this.totalCount = totalCount;this.currentPage = currentPage;this.pageSize = pageSize;this.totalPage = totalCount % pageSize == 0 ? totalCount % pageSize : totalCount % pageSize + 1;this.prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;this.nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;currentPage = currentPage > totalPage ? totalPage : currentPage;}
}
@Getter
@Setter
public class QueryObject {private int currentPage = 1;private int pageSize = 3;public int getStart() {return (currentPage - 1) * pageSize;}//如果说字符串为空字符串,也应该设置为nullpublic String employ2null(String str) {return hasLength(str) ? str : null;}public boolean hasLength(String str) {return str != null && !"".equals(str.trim());}
}

service

public interface IEmployeeService {PageResult query(QueryObject qo);
}

impl

public class EmployeeServiceImpl implements IEmployeeService{private EmployeeMapper employeeMapper = MyBatisUtil.getMapper(EmployeeMapper.class);public PageResult query(QueryObject qo) {int rows = employeeMapper.queryForCount(qo);if(rows == 0){return new PageResult(Collections.EMPTY_LIST,0,1,qo.getPageSize());}List<Employee> result = employeeMapper.queryForList(qo);return new PageResult(result,rows,qo.getCurrentPage(),qo.getPageSize());}
}

MyBatisUtil

    public class MyBatisUtil {private static SqlSessionFactory factory = null;static{InputStream in;try {//创建SqlSessionFactory对象in = Resources.getResourceAsStream("mybatis-config.xml");factory = new SqlSessionFactoryBuilder().build(in);} catch (IOException e) {e.printStackTrace();}}//返回一个SqlSession对象public static SqlSession getSession(){//默认false不自动提交事务return factory.openSession();}public static <T> T getMapper(Class<T> mapperClass){return getSession().getMapper(mapperClass);}}

mybatis-config.xml

<configuration><properties resource="db.properties"></properties><!-- 日志技术 --><settings><setting name="logImpl" value="LOG4J"/></settings><typeAliases><!-- <typeAlias type="cn.wolfcode.mybatis.hello.User" alias="User"/> --><!-- 一般写到domain包就可以了,自动为该包中的类起别名,默认的别名就是简单类名首字母小写,其实不区分大小写 --><package name="cn.wolfcode.mybatis.hello"/></typeAliases><!-- 1:配置数据库的环境 --><environments default="dev"><!-- 开发环境:在以后事务管理器和连接池都是交给Spring框架来管理的 --><environment id="dev"><!-- ①:事务管理器 --><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><!-- 2:关联映射文件 --><mappers><mapper resource="cn\wolfcode\mybatis\hello\mapper\EmployeeMapper.xml"/></mappers>
</configuration>

MyBatis的总结(上)相关推荐

  1. MyBatis实战【上】

    MyBatis 主要内容 Mybatis 入门 Mybatis 的基本使用 J ava 日志处理框架 Mybatis 配置完善 SqlSession 常用 API Mapper 动态代理 动态 SQL ...

  2. 当mybatis逆向工程遇上了数据库字段增加

    最近做的一个项目让我对mybatis的逆向工程有些迷茫,毕竟第一次在实际项目中使用,有太多稚嫩,老人路过还请指教. 对于mybatis的逆向工程,我既喜欢它让我省了很多力气,但是另一方面,它也给我套了 ...

  3. Spring boot + Mybatis Plus实现上一页、下一页功能。

    在做查询的h时候, 我们会遇到上一页.下一页这样的需求, 这时候使用 id + 1 和 id -1 来做查询是不能够完成需求的, 因为会遇到有的 id 被删除而导致id 不连贯的一个情况. Sprin ...

  4. 字段为NULL导致MyBatis在Oracle上执行SQL报错,无效的列类型

    在oracle中的null为不确定的意思,存储null时,mybatis解析不到oracle字段类型.所以写SQL时最好加上具体的字段类型.如 insert into user(id,name,age ...

  5. jeefast使用Mybatis进行图片上传

    在jeefast中找到配置虚拟目录的地方 看一下是否继承了WebMvcConfigurerAdapter 接口,如果继承的话就重写配置虚拟目录的方法 @Overridepublic void addR ...

  6. Mybatis常见面试题(三)

    Mybatis 映射文件中,如果 A 标签通过 include 引用了 B 标签的内容,请问, B 标签能 否定义在 A 标签的后面,还是说必须定义在 A 标签的前面? :虽然 Mybatis 解析 ...

  7. 为什么国内流行的 MyBatis ,国外 Java 工程师却不愿意使用?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源 | zhihu.com/question/30966 ...

  8. 为什么老外不愿意用 MyBatis?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:知乎@陈龙 链接:zhihu.com/question/30 ...

  9. 提升开发效率的一款mybatis开发神器

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 本篇同步更新地址; https://me.csdn.net/Dan ...

最新文章

  1. 制作欧比旺·克诺比逼真的CG角色学习教程
  2. 关于Webpack详述系列文章 (第四篇)
  3. Eclipse安装hibernate插件的问题
  4. [BUUCTF-pwn]——ciscn_2019_n_8
  5. 大数据在未来十年将如何发展
  6. 【加权并查集】bzoj 4602 齿轮
  7. mysql的DbUtils_Dbutils操作mysql
  8. G1刷机问题 E:error status=7
  9. 比特币、以太坊、瑞波币、万融链和区块链
  10. 又来?软件测试之接口自动化面试题汇总
  11. hadoop 集群调度 Azkaban2搭建
  12. 计算机检索系统中 每一种文献特征,自考《档案文献检索》串讲资料(1)
  13. 中兴 F607 光猫超级管理用户查看
  14. ASP.NET课设——新闻发布系统
  15. 学生个人网页模板 学生个人网页设计作品 简单个人主页成品 个人网页制作 HTML学生个人网站作业设计
  16. 虚拟机打不开磁盘或它所依赖的某个快照磁盘
  17. ITMS-SERVICES://方式安装IPA在IOS 7.1中的变化
  18. pythonic的典故_旷视开源深度学习框架「天元」,提供人人可用的AI“生产力工具”【星特写】...
  19. Word2Vec之Skip-Gram与CBOW模型
  20. php 提取视频中的音频,如何把视频中的音频提取出来

热门文章

  1. 5年外包码农,拿到阿里offer,成功上岸,凭什么?
  2. 超实用,Spring Security+JWT+Vue实现一个前后端分离无状态认证Demo
  3. mysql是怎样运行的书籍_《Mysql是怎样运行的》读书笔记三
  4. stm32f103r8t6的晶振频率_STM32F103R8T6[1]
  5. 包容网关 Inclusive Gateway
  6. Springboot2Web原生组件注入
  7. 2019.8.6原型链与继承
  8. spring源码之—Assert.notNull()
  9. Python 练习: 简单角色游戏程序
  10. 将普通文章内容替换为微信图文消息符合的内容