注解开发

MyBatis 最初是一个 XML 驱动的框架。配置信息是基于 XML 的,而且映射语句也是定义在 XML 中的。随着技术的更新发展,对于开发效率要求也原来越高,特别是一些小型项目;越来越多的框架开始支持注解。

到MyBatis3时,MyBatis对注解有了完善的支持,利用注解可以在一些情况下提高开发效率

但不幸的是,Java 注解的的表达力和灵活性十分有限。尽管很多时间都花在调查、设计和试验上, 最强大的 MyBatis 映射并不能用注解来构建

常用注解

@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
准备工作:

在java/mapper下新建一个接口 ProductsMappers

public interface ProductsMappers {}

在全局文件中扫描这个包:

 <mappers><package name="mapper"/>
</mappers>

如果之前配置过就不用配置了

在test/java下创建一个测试类:

public class PriductsMappersTest {private SqlSessionFactory factory;@Beforepublic void init() throws IOException {//创建工厂创建类SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//加载配置文件InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//创建会话工程factory = sqlSessionFactoryBuilder.build(in);}
}

后面注解开发都会在接口进行写,测试会在测试类写。

1. select

接口方法:

 //按id查找@Select("select * from products where pid = #{id}")@Results(id = "my_name" ,value = {@Result(id = true,column = "pid",property = "pid"),@Result(column = "name",property = "pname")})Product selectById(int id);

注解:

@Select 括号里写的是SQL语句和xml文件里写的一样,若是普通取值用#{} 如果是模糊查询一样的字符串要用单引号:‘%${}%’@Results 是映射集,包含一个或多个 @Result映射,用 , 隔开,Result里id为true代表主键,默认是flase,column是列名,property是字段名当列名和字段名匹配时,注解开发是自动映射的,不同时要用Results注解进行定义

测试:

     @Testpublic void selectByIdTest(){try (SqlSession session = factory.openSession()) {ProductsMappers mapper = session.getMapper(ProductsMappers.class);Product product = mapper.selectById(3);System.out.println(product);}}

2. sql语句多个参数

接口方法:

    @Select("select * from products where name like '%${pname}%' and cid = #{cid}")@Results({@Result(id = true,column = "pid",property = "pid"),@Result(column = "name",property = "pname")})List<Product> selectByName(@Param("pname") String pname,@Param("cid") String cid);

注解:

@Param("参数名")   当有多个参数时要用 Param注解标明每个参数的参数名

测试:

 @Testpublic void selectByNameTest(){try (SqlSession session = factory.openSession()) {ProductsMappers mapper = session.getMapper(ProductsMappers.class);List<Product> list = mapper.selectByName("新疆","s001");System.out.println(list);}}

注意:

MyBatis的sql接受的参数只有一个无论实际传了几个

当sql语句需要多个参数时则必须将多个参数打包到一个对象中,通常是POJO或Map,上面的案例中使用了@Param注解本质就是告诉MyBatis有多个参数MyBatis会自动创建一个Map,然后将@Param的值作为Key,然后将Map传给sql,所以你也可以手动传一个Map,所以上面可以写成下面形式:

接口方法:

    @Select("select * from products where name like '%${pname}%' and cid = #{cid}")@Results({@Result(id = true,column = "pid",property = "pid"),@Result(column = "name",property = "pname")})List<Product> selectByName(Map<String,String> param);

测试:

     @Testpublic void selectByNameTest(){try (SqlSession session = factory.openSession()) {ProductsMappers mapper = session.getMapper(ProductsMappers.class);Map<String,String> map = new HashMap<String, String>();map.put("pname","新疆");map.put("cid" , "s001");List<Product> list = mapper.selectByName(map);System.out.println(list);}}

3. insert

接口方法:

 //插入@Insert("insert into products values(null,#{pname},#{price},#{pdate},#{user_id},#{cid})")void insertProduct(Product product);

测试:

@Testpublic void insertTest(){try (SqlSession session = factory.openSession(true)) {ProductsMappers mapper = session.getMapper(ProductsMappers.class);Product product = new Product();product.setPname("河南大枣");product.setPrice(50.98);product.setCid("s002");product.setUser_id(1);mapper.insertProduct(product);}}

自增

 //插入@Insert("insert into products values(null,#{pname},#{price},#{pdate},#{user_id},#{cid})")@SelectKey(statement = "select last_insert_id()",keyColumn = "pid",keyProperty = "pid",resultType = Integer.class,before = false)void insertProduct(Product product);

SelectKey 注解:

statement:要执行的方法
keyColumn:主键列名
keyProperty:返回对应字段名
resultType返回类型
before:插入之前返回,false代表插入之后返回

4. update

接口方法:

 //更新@Update("update products set name = #{pname} where pid = #{pid}")void updateProduct(Map<String,Object> param);

测试:

 @Testpublic void updateTest() {try (SqlSession session = factory.openSession(true)) {ProductsMappers mapper = session.getMapper(ProductsMappers.class);Map<String,Object> map = new HashMap<String, Object>();map.put("pname","绘面");map.put("pid",12);mapper.updateProduct(map);}}

5.delete

接口方法:

 //删除@Delete("delete from products where pid = #{pid}")void delete(int pid);

测试:

@Testpublic void deleteTest() {try (SqlSession session = factory.openSession(true)) {ProductsMappers mapper = session.getMapper(ProductsMappers.class);mapper.delete(12);}}

6. 动态sql

动态sql指语句中包含逻辑代码,需要先运行逻辑代码,最后产生sql语句,所以需要在注解中告诉MyBatis这是一个动态sql,通过<script>sql....</script>语法来指定;

若想要在sql中使用各种标签则必须添加上述根标签,否则MyBatis会将整体作为sql语句

接口方法声明:

@Select("<script>" +"select * from products" +"<where>" +"<if test='name != null'>" +"and name like '%${name}%'" +"</if>" +"</where>" +"</script>")
@ResultMap("my_name")
List<Product> searchByName(String name);

注解:

script:标签里面的和xml里面的动态sql一样,只是用script标签包起来了,做为标识。ResultMap:是调用上面Results里面的内容,上面查询语句里Results设置了id,在这里调用id就可以使用value里面的内容

测试:

@Testpublic void SQLTest(){try (SqlSession session = factory.openSession()) {ProductsMappers mapper = session.getMapper(ProductsMappers.class);List<Product> list = mapper.searchByNameAndSex("新疆");System.out.println(list);}}

7.结果映射(ResultMap)

上面已经说过基本用法,在这总结一下:

1.自定义字段与属性对应关系

列名与字段名不匹配,需要自定义映射:

 //按id查找@Select("select * from products where pid = #{id}")@Results(id = "my_name" ,value = {@Result(id = true,column = "pid",property = "pid"),@Result(column = "name",property = "pname")})Product selectById(int id);

重复使用Results

MyBatis默认会自动映射所有字段和属性匹配的数据,另外id表示是否为主键字段,默认为false

强调:Results可以位于对应方法的上面或下面,但是无法跨域其他方法,默认只对当前方法有效,如果需要重复使用则需要为其指定id

接口方法声明:

//定义
@Results(id="map1",value = {@Result(id = true,column = "pid",property = "pid"),@Result(column = "name",property = "pname"),
})
//.....中间必须间隔其他方法不能立即应用到某个ResultMap

使用:

@Select("select * from kuser where name = #{pname}")
//通过@ResultMap注解 并传入id来使用
@ResultMap("map1")
public User selectUserByName(String name);

注意:
@Results的定义不能和使用它的@ResultMap一起出现,既然是重复使用的那我建议统一接口的最上面,
如果是当前要使用的并且要重用,直接使用Results即可,不需要在下面添加ResultMap就像下面这样:

@Select("select * from kuser where name = #{pname}")
@Results(id="map1",value = {@Result(id = true,column = "pid",property = "pid"),@Result(column = "name",property = "pname"),
})
public User selectUserByName(String name);

2.关联查询

一对一:

 @One 注解(一对一)代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。@One 注解属性介绍:select 指定用来多表查询的 sqlmapperfetchType 会覆盖全局的配置参数 lazyLoadingEnabled。使用格式:@Result(column=" ",property="",one=@One(select=""))

接口声明方法:

 //按id查找@Select("select * from products where pid = #{id}")@Results(id = "my_name" ,value = {@Result(column = "name",property = "pname"),@Result(property = "user",column = "user_id",one = @One(select = "mapper.ProductsMappers.selectByUserId"))})Product selectById(int id);@Select("select * from user where id = #{id}")User selectByUserId(int id);

注解:

Result注解:property对应字段名column表明哪个列名作为参数one里面select对应下面的方法,即为调用下面方法按指定参数进行查询,查到后映射到指定字段上

一对多关联:

 @Many 注解(多对一)代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType(一般为 ArrayList)但是注解中可以不定义;使用格式:@Result(property="",column="",many=@Many(select=""))

接口方法:

 @Select("select * from user where id = #{id}")@Results({@Result(property = "list",column = "id",many = @Many(select = "mapper.ProductsMappers.selectByUserId"))})User selectUserByUserId(int id);@Select("select * from products where user_id = #{user_id}")@Results({@Result(column = "name",property = "pname")})List<Product> selectByUserId(int id);

一对多和一对一用法都一样,只是one注解变成了Many注解,Many注解里的select 调用一个查询方法,以id作为参数,返回的结果映射到list字段去。

一对一和一对多只能采用子查询的方式进行。

mybatis逆向工程(generator)

generator翻译为生成器,是MyBatis开源的一个插件,可以从数据库获取表信息,自动生成Mapper.xml,POJO,以及Mapper接口,但问题是,MyBatis不可能完全清楚我们的业务需求,所以其自动生成的sql只能满足基本的增删改查操作,而无法帮助我们进行连表操作,(当然包括带有条件的增删改查)

使用步骤

1.使用Maven添加generator插件
<build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><!-- 是否覆盖已存在的接口和POJO该配置不包括Mapper  若为False将会生成版本记录--><overwrite>true</overwrite></configuration></plugin></plugins>
</build>

如果pom.xml有build和plugins标签,则只需把plugin标签里面内容加入plugins标签里面即可。在这里有个注意:如果你的build标签和plugins标签之间有个pluginManagement标签,则他是不下载插件的,需要把pluginManagement去掉,他就会自动下载,下载完会出现在你的maven插件里面。

2.创建数据库配置文件,位于resource下名为jdbc.properties
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql:///mybatisdb?characterEncoding=utf8
jdbc.username = root
jdbc.password = 123456
location = D:/maven/repository/mysql/mysql-connector-java/5.1.47/mysql-connector-java-5.1.47.jar

上面四个是数据库配置文件,location是mysql驱动的位置,如果有,只需要在文件里加入location。

3.创建配置文件,位于resource下名为generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><!--导入属性配置--><properties resource="jdbc.properties"></properties><!--指定特定数据库的jdbc驱动jar包的位置--><classPathEntry location="${location}"/><context id="default" targetRuntime="MyBatis3"><!-- optional,旨在创建class时,对注释进行控制 --><commentGenerator><property name="suppressDate" value="true"/><property name="suppressAllComments" value="true"/></commentGenerator><!--jdbc的数据库连接 --><jdbcConnectiondriverClass="${jdbc.driver}" connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"></jdbcConnection><!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制--><javaTypeResolver><property name="forceBigDecimals" value="false"/></javaTypeResolver><!--Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类targetPackage 指定生成的model生成所在的包名targetProject 指定在该项目下所在的路径 --><javaModelGenerator targetPackage="com.lbb.pojo" targetProject="src/main/java"><!-- 是否允许子包,即targetPackage.schemaName.tableName --><property name="enableSubPackages" value="false"/><!-- 是否对model添加 构造函数 --><property name="constructorBased" value="true"/><!-- 是否对类CHAR类型的列的数据进行trim操作 --><property name="trimStrings" value="true"/><!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 --><property name="immutable" value="false"/></javaModelGenerator><!--mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 --><sqlMapGenerator targetPackage="com.lbb.dao"targetProject="src/main/resources"><property name="enableSubPackages" value="false"/></sqlMapGenerator><!--mapper接口文件生成所在的目录 为每一个数据库的表生成对应的接口文件 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.lbb.dao" targetProject="src/main/java"><!-- enableSubPackages:是否让schema(数据库名称)作为包的后缀 --><property name="enableSubPackages" value="false"/></javaClientGenerator><!--指定需要生成的表-->
<!--        <table  tableName="category"></table>--><table  tableName="orders"></table>
<!--        <table  tableName="products"></table>-->
<!--        <table  tableName="kuser"></table>--></context>
</generatorConfiguration>
3.运行generator

在idea右侧的maven菜单中双击执行mybatis-generator:generate

也可利用maven命令执行:mybatis-generator:generate

4.条件查询的使用查看POJO包,会发现每个POJO对应了一个Example


generator的目标是尽可能的帮我们减少sql的编写,如果只能进行简单的增删改查那编写意义不大,于是generator使用了一套Example来帮助我们用OOP(面向对象)的方式来完成SQL中的条件拼接

其设计思想是将条件看做是一个对象,该对象包含了SQL中常见的比较,逻辑运算等…打开文件你会发现其本质就是帮我们拼接响应的sql符号和关键字

5.配置mybatis-config.xml文件

在mybatis-config.xml下要进行扫描包:

<mappers><package name="com.lbb"/>
</mappers>
6.增删改查 案例

1、简单增删改查

public class OrdersTest {private SqlSessionFactory factory;@Beforepublic void init() throws IOException {//创建工厂创建类SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//加载配置文件InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//创建会话工程factory = sqlSessionFactoryBuilder.build(in);}//通过id@Testpublic void selectByIdTest(){SqlSession session = factory.openSession();OrdersMapper mapper = session.getMapper(OrdersMapper.class);Orders orders = mapper.selectByPrimaryKey(8);System.out.println(orders);}//添加@Testpublic void insertTest(){SqlSession session = factory.openSession(true);OrdersMapper mapper = session.getMapper(OrdersMapper.class);Orders orders = new Orders();orders.setUserId(1);orders.setNumber("JI1321651");orders.setCreatetime(new Date());mapper.insertSelective(orders);}//修改@Testpublic void updateTest(){SqlSession session = factory.openSession(true);OrdersMapper mapper = session.getMapper(OrdersMapper.class);Orders orders = new Orders();orders.setId(12);orders.setNumber("1321321");mapper.updateByPrimaryKeySelective(orders);}//删除@Testpublic void deleteTest(){SqlSession session = factory.openSession(true);OrdersMapper mapper = session.getMapper(OrdersMapper.class);mapper.deleteByPrimaryKey(12);}
}

2、example的使用

public class OrdersTest {private SqlSessionFactory factory;@Beforepublic void init() throws IOException {//创建工厂创建类SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//加载配置文件InputStream in = Resources.getResourceAsStream("mybatis-config.xml");//创建会话工程factory = sqlSessionFactoryBuilder.build(in);}//and条件@Testpublic void test5() {SqlSession session = factory.openSession(true);OrdersMapper mapper = session.getMapper(OrdersMapper.class);//声明对象OrdersExample ordersExample = new OrdersExample();//创建条件OrdersExample.Criteria criteria = ordersExample.createCriteria();//加入使用and方法连接criteria.andUserIdEqualTo(1);criteria.andNumberLike("%11%");List<Orders> orders = mapper.selectByExample(ordersExample);System.out.println(orders);}// or条件@Testpublic void test6() {SqlSession session = factory.openSession();OrdersMapper mapper = session.getMapper(OrdersMapper.class);//声明对象OrdersExample ordersExample = new OrdersExample();//创建一个条件对象,可以包含n个andOrdersExample.Criteria criteria1 = ordersExample.createCriteria();criteria1.andNumberLike("%11%");//创建一个条件对象可以包含n个and,且前面添加or关键字OrdersExample.Criteria criteria2 = ordersExample.or();criteria2.andUserIdEqualTo(2);//最终的意思是 名字带有张的 或者生日为空的;  具体查看生产的sql即可List<Orders> orders = mapper.selectByExample(ordersExample);System.out.println(orders);}
}

注意:重新生成的Mapper文件时不会不会覆盖之前的Mapper,而是会直接在里面添加sql导致id冲突,所以重新生成mapper时一定要手动删除已存在的mapper

mybatis之注解开发与逆向工程相关推荐

  1. mybatis使用注解开发

    mybatis使用注解开发 面向接口编程 在之前我们是通过面向对象编程,但是在真正开发的时候我们会选择面向接口编程. 根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的 ...

  2. MyBatis之注解开发

    mybatis常用注解: @Insert:实现新增 @Update:实现更新 @Delete:实现删除 @Select:实现查询 @Result:实现结果集封装 @Results:可以与@Result ...

  3. mybatis的注解开发之三种动态sql

    脚本sql XML配置方式的动态SQL我就不讲了,有兴趣可以自己了解,下面是用<script>的方式把它照搬过来,用注解来实现.适用于xml配置转换到注解配置 @Select(" ...

  4. SSM—mybatis框架-注解开发-动态sql(where,set,trim,choose,when,foreach)-模糊查询写法-特殊符号处理-缓存

    文章目录 2.0.注解 2.1.动态sql 2.1.1.where 2.1.2.set 2.1.3.trim 2.1.3.1.trim的where 2.1.3.2.trim的set 2.1.4.1.c ...

  5. Mybatis接口注解开发

    [1.在项目中新增一个接口,如下] package com.crayon.test; import java.util.List; import org.apache.ibatis.annotatio ...

  6. MyBatis----回顾mybatis自定义和环境搭建+完善自定义Mybatis的注解开发

    上一篇

  7. MyBatis-学习笔记04【04.自定义Mybatis框架基于注解开发】

    Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...

  8. Mybatis—注解开发

    Mybatis的注解开发 MyBatis的常用注解 这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了. @Insert:实现新增 @Upd ...

  9. Mybatis注解开发笔记

    Mybatis注解开发(笔记) 欢迎来到菜鸟研究所 创建新的Maven项目 配置文件 prom.xml log4j.properties jdbcConfig.properties SqlMapCom ...

最新文章

  1. SAP RETAIL系统与制造业SAP系统上关于补货的配置
  2. pragma名字的来源
  3. acwing3132. 食物(BZOJ3028)
  4. c语言 typedef_C Typedef-能力倾向问题与解答
  5. 安装flash-----纠结
  6. OpenCV尽量不要打开CUDA参数编译,否则太慢了
  7. 阿里云眼中的“云网络3.0”:构建应用、云、边一体网络
  8. 【语音识别】基于matlab GUI MFCC+VQ说话人识别系统【含Matlab源码 1153期】
  9. 云计算 third day
  10. ubuntu端口转发工具 Rinetd
  11. win10重置计算机网络设置,为你解答win10下如何重置网络
  12. FDD与TDD工作原理
  13. vue加载vue-amap 报错解决办法
  14. Would you like to share anonymous usage data about this project with the Angular Team at Google unde
  15. 八种方法求π的近似值
  16. 200行Go代码实现自己的区块链——区块生成与网络通信
  17. 对日软件开发过程中的质量管理
  18. C++11多线程:thread头文件
  19. ooXMLAgile Encryption(一)文档结构
  20. 服务器导出word文档中有乱码,使用Aspose.word DOC转PDF文件乱码问题-Doc文件

热门文章

  1. 如何优雅地解决ssh中Too-many-authentication-failures的问题
  2. 程序员:如何走出自己的管理之路?
  3. 分治算法实践5-小明的散步路径 C++
  4. 理论物理极础9:相空间流体和吉布斯-刘维尔定理
  5. 【Halcon视觉】标定
  6. ESP8266-Arduino编程实例-MQ-135空气质量检测传感器驱动
  7. CorelDRAW2022订阅版本专属功能
  8. 机甲 java_强殖机甲之变身斗士
  9. 第三章:MATLAB的基础知识(基本符号,数据类型,运算符,复数运算,三角函数运算)
  10. 微带线,带状线和接地共面波导的区别