MyBatis笔记
- 格式:doc
- 大小:58.00 KB
- 文档页数:5
MyBatisPlus2.3个⼈笔记-04-配置⽂件与插件使⽤接⼊ springboot application.yml配置 1.mapper 扫描mybatis-plus:# 如果是放在src/main/java⽬录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml# 如果是放在resource⽬录 classpath:/mapper/*Mapper.xmlmapper-locations: classpath:/com/huarui/mybatisplus/mapper/*Mapper.xml#实体扫描,多个package⽤逗号或者分号分隔typeAliasesPackage: com.huarui.mybatisplus.entity@SpringBootApplication@MapperScan("com.huarui.mybatisplus.mapper")public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}} 2.⾃定义公共字段填充处理器当我们新增或修改时需要给某个字段赋值默认值@TableName("tbl_user")public class User extends Model<User> {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.ID_WORKER)private Long id;/** ** 新增修改时字段⾃动填充*/@TableField(fill = FieldFill.INSERT_UPDATE)private String name;}package com.huarui.mybatisplus.configuration;import com.baomidou.mybatisplus.mapper.MetaObjectHandler;import org.apache.ibatis.reflection.MetaObject;/*** Created by lihui on 2019/2/17.* ⾃定义公共字段填充处理器*/public class MyMetaObjectHandler extends MetaObjectHandler {/*** 插⼊操作⾃动填充*/@Overridepublic void insertFill(MetaObject metaObject) {//获取到需要被填充的字段的值Object fieldValue = getFieldValByName("name", metaObject);if(fieldValue == null) {System.out.println("*******插⼊操作满⾜填充条件*********");setFieldValByName("name", "youxiu326", metaObject);}}/*** 修改操作⾃动填充*/@Overridepublic void updateFill(MetaObject metaObject) {Object fieldValue = getFieldValByName("name", metaObject);if(fieldValue == null) {System.out.println("*******修改操作满⾜填充条件*********");setFieldValByName("name", "youxiu326", metaObject);}}}MyMetaObjectHandler.javamybatis-plus:# 如果是放在src/main/java⽬录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml# 如果是放在resource⽬录 classpath:/mapper/*Mapper.xmlmapper-locations: classpath:/com/huarui/mybatisplus/mapper/*Mapper.xml#实体扫描,多个package⽤逗号或者分号分隔typeAliasesPackage: com.huarui.mybatisplus.entityglobal-config:#主键类型 0:"数据库ID⾃增", 1:"⽤户输⼊ID",2:"全局唯⼀ID (数字类型唯⼀ID)", 3:"全局唯⼀ID UUID"; id-type: 2#⾃定义填充策略接⼝实现meta-object-handler: com.huarui.mybatisplus.configuration.MyMetaObjectHandler 3.逻辑删除@TableName("tbl_user")public class User extends Model<User> {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.ID_WORKER)private Long id;@TableField("deleteFlag")@TableLogic //逻辑删除标志private Integer deleteFlag;}mybatis-plus:# 如果是放在src/main/java⽬录下 classpath:/com/yourpackage/*/mapper/*Mapper.xml# 如果是放在resource⽬录 classpath:/mapper/*Mapper.xmlmapper-locations: classpath:/com/huarui/mybatisplus/mapper/*Mapper.xml#实体扫描,多个package⽤逗号或者分号分隔typeAliasesPackage: com.huarui.mybatisplus.entityglobal-config:#逻辑删除配置(下⾯3个配置)logic-delete-value: -1 #删除状态logic-not-delete-value: 1 #未删除状态sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector4.分页插件与乐观锁插件使⽤@EnableTransactionManagement@Configuration@MapperScan("com.huarui.mybatisplus.mapper.*")public class MybatisPlusConfig {/*** 分页插件*/@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}/*** 乐观锁插件*/@Beanpublic OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();}} 分页插件配置即可使⽤ 乐观锁实现⽅式:取出记录时,获取当前version更新时,带上这个version执⾏更新时, set version = yourVersion+1 where version = yourVersion如果version不对,就更新失败@TableName("tbl_employee")public class Employee extends Model<Employee> {private static final long serialVersionUID = 1L;/** @TableId:* value: 指定表中的主键列的列名,如果实体属性名与列名⼀致,可以省略不指定.* type: 指定主键策略. ID_WORKER 全局唯⼀ID,内容为空⾃动填充(默认配置)*/@TableId(value = "id", type = IdType.ID_WORKER)/*** 声明该属性不是数据库中字段*/@TableField(exist = false)private String notExist;/*** 乐观锁版本号* 仅⽀持int,Integer,long,Long,Date,Timestamp*/@Versionprivate Integer version;} 5.性能分析插件spring:profiles:#spring boot application.properties⽂件中引⽤maven profile节点的值active: dev #指定dev环境package com.huarui.mybatisplus.configuration;import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;import com.baomidou.mybatisplus.plugins.PaginationInterceptor;import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;import com.baomidou.mybatisplus.plugins.SqlExplainInterceptor;import org.mybatis.spring.annotation.MapperScan;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import org.springframework.transaction.annotation.EnableTransactionManagement; /*** Created by lihui on 2019/2/17.*/@EnableTransactionManagement@Configuration@MapperScan("com.huarui.mybatisplus.mapper.*")public class MybatisPlusConfig {/*** 分页插件*/@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}/***/@Bean@Profile({"dev","test"})// 设置 dev test 环境开启public PerformanceInterceptor performanceInterceptor () {PerformanceInterceptor p = new PerformanceInterceptor ();p.setFormat(true);p.setMaxTime(200);//参数:maxTime SQL 执⾏最⼤时长,超过⾃动停⽌运⾏,有助于发现问题。
一、前言数据库操作怎能少了INSERT操作呢?下面记录MyBatis关于INSERT操作的笔记,以便日后查阅。
二、 insert元素属性详解其属性如下:parameterType ,入参的全限定类名或类型别名keyColumn ,设置数据表自动生成的主键名。
对特定数据库(如PostgreSQL),若自动生成的主键不是第一个字段则必须设置keyProperty ,默认值unset,用于设置getGeneratedKeys方法或selectKey子元素返回值将赋值到领域模型的哪个属性中useGeneratedKeys ,取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys 方法获取主键并赋值到keyProperty设置的领域模型属性中。
MySQL和SQLServer执行auto-generated key field,因此当数据库设置好自增长主键后,可通过JDBC的getGeneratedKeys方法获取。
但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了statementType ,取值范围STATEMENT,PREPARED(默认值),CALLABLEflushCache ,取值范围true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存timeout ,默认为unset(依赖jdbc驱动器的设置),设置执行该操作的最大时限,超时将抛异常databaseId ,取值范围oracle|mysql等,表示数据库厂家,元素内部可通过`<if test="_databaseId = ‘oracle‘">`来为特定数据库指定不同的sql语句三、一般的INSERT操作——返回值为插入的记录数目mapper接口代码:/*** 添加学生信息* @param student 学生实例* @return 成功操作的记录数目*/int add(EStudent student);mapper.xml:<insert id="add" parameterType="EStudent">insert into TStudent(name, age) values(#{name}, #{age})</insert四、执行INSERT操作后获取记录主键mapper接口代码:/*** 添加学生信息* @param student 学生实例* @return 成功操作的记录数目*/int add(EStudent student);至于mapper.xml则分为两种情况了,一种是数据库(如MySQL,SQLServer)支持auto-generated key field,另一种是数据库(如Oracle)不支持auto-generated key field的。
《MyBatis核心技术全解与项目实战》读书笔记1. 第一章 MyBatis简介本章主要介绍了MyBatis的基本概念、特点和优势,以及其在Java企业级应用开发中的重要作用。
MyBatis是一个优秀的持久层框架,它将SQL语句与Java对象映射(POJO)相结合,使得开发人员可以更加方便地操作数据库。
MyBatis的主要目标是简化数据库操作,提高开发效率,同时也提供了良好的数据封装和安全性。
SqlSessionFactory:用于创建SqlSession对象,SqlSession是MyBatis中执行SQL语句的核心接口。
SqlSession:用于执行SQL语句的会话对象,可以通过它来执行增删改查等操作。
Mapper:映射器接口,用于定义SQL语句和Java对象之间的映射关系。
Configuration:MyBatis的全局配置类,用于配置各种属性,如缓存策略、事务管理等。
插件:MyBatis的插件机制,允许开发者自定义拦截器、类型处理器等组件,以实现对MyBatis的功能扩展。
灵活性:MyBatis支持多种存储结构,如JDBC、ODBC、JNDI等,同时还支持自定义类型处理器和插件,使得MyBatis能够满足各种复杂的数据库操作需求。
易用性:MyBatis提供了简洁的XML映射文件来描述SQL语句和Java对象之间的映射关系,使得开发者无需编写复杂的SQL语句即可完成数据库操作。
性能优化:MyBatis通过一级缓存和二级缓存机制来提高查询性能,同时还支持动态SQL、分页查询等功能,使得MyBatis能够在高并发环境下保持良好的性能表现。
安全性:MyBatis提供了严格的权限控制机制,可以限制不同用户对数据库的操作权限,保证数据的安全性。
1.1 MyBatis概念及特点MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。
相比于传统的数据访问技术,MyBatis让开发者能够更加直接地与数据库交互,从而有效地避免了大量繁琐的SQL语句编写工作。
mybatis field 参数全文共四篇示例,供读者参考第一篇示例:MyBatis是一款流行的Java持久层框架,它可以简化数据库操作,并且提供了许多强大的特性,其中之一就是Field参数。
Field参数可以用来指定要在SQL语句中操作的字段或属性,可以帮助开发人员更灵活地进行数据库操作。
在MyBatis中,Field参数可以在映射文件(Mapper.xml)中使用,用于指定实体类的属性与数据库表中的字段之间的映射关系。
通过Field参数,开发人员可以自定义SQL语句中操作的字段,而不仅仅是使用实体类中的属性名称。
在Mapper.xml文件中,可以通过Field参数来指定要操作的字段,例如:在上面的例子中,<if>标签中使用了Field参数来指定要更新的字段,如果属性值不为空,则会将对应字段更新为相应的值。
这样就可以在SQL语句中根据实体类的属性动态地生成更新语句。
除了在更新操作中使用Field参数,我们还可以在查询操作中使用Field参数。
在动态SQL中,可以根据不同的条件选择要查询的字段,例如:```javaUser getUserById(@Param("id") int id, @Param("field") String field);```在上面的例子中,通过@Param注解显式地指定了要操作的字段,在调用接口方法时可以传入相应的参数。
这样就可以在Java代码中更加灵活地操作数据库字段。
希望本文对您理解MyBatis中的Field参数有所帮助,也希望您能在实际开发中灵活运用Field参数,更好地实现您的功能需求。
感谢您的阅读!第二篇示例:MyBatis是一个优秀的持久层框架,它简化了与数据库的交互过程。
在MyBatis中,我们通常会涉及到一些参数,其中包括field参数。
在本文中,我们将深入探讨field参数的作用和用法。
让我们来了解一下什么是field参数。
MyBatis使用注意事项MyBatis是一种流行的数据库持久化框架,它能够映射数据库表和Java对象之间的关系,简化了数据库访问的操作。
在使用MyBatis的过程中,有一些注意事项需要注意,以确保应用程序的性能和稳定性。
以下是一些使用MyBatis的注意事项。
1.SQL语句的优化在编写SQL语句时,要尽量避免使用select *,而是指定所需的列。
这可以减少数据库传输的数据量,提高查询的性能。
还要避免在SQL语句中使用子查询和联合查询,因为这些操作的性能较差。
另外,如果可能的话,可以考虑使用数据库的索引来加速查询操作。
2.映射文件的维护MyBatis使用映射文件来执行数据库操作,因此要注意映射文件的维护。
映射文件应该与数据库表结构保持一致,并且要避免映射文件中的重复代码。
可以使用通用的ResultMap和BaseMapper来减少映射文件的复杂性。
3.数据库连接的管理MyBatis使用数据库连接来执行数据库操作,因此要注意数据库连接的管理。
要避免在代码中显式关闭数据库连接,而是使用连接池来管理连接的获取和释放。
可以使用框架或者连接池库来管理数据库连接,如Apache DataSource和Druid等。
4.事务管理MyBatis支持事务管理,可以在操作数据库时开启事务,确保操作的原子性和一致性。
在使用事务时,要注意事务的边界,避免长时间的事务操作。
可以使用注解或者编程方式来管理事务,根据具体的业务需求来选择合适的事务管理方式。
5.缓存管理MyBatis内置了一级缓存和二级缓存来提高查询性能。
一级缓存是默认开启的,它存储在会话级别的缓存中,可以提高重复查询的性能。
二级缓存是可选的,它存储在全局级别的缓存中,可以提高跨会话的查询性能。
在使用缓存时,要注意缓存的生命周期和失效机制,避免缓存导致的数据一致性问题。
6.分页查询在查询大量数据时,要使用分页查询来提高查询性能。
MyBatis提供了RowBounds和PageHelper两种方式来实现分页查询。
MyBatis学习总结(一)——MyBatis快速入门一、Mybatis介绍MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。
MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO (Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
二、mybatis快速入门2.1、准备开发环境1、创建测试项目,普通java项目或者是JavaWeb项目均可,如下图所示:2、添加相应的jar包【mybatis】mybatis-3.1.1.jar【MYSQL驱动包】mysql-connector-java-5.1.7-bin.jar3、创建数据库和表,针对MySQL数据库SQL脚本如下:1createdatabase mybatis;2use mybatis;3CREATETABLE users(id INTPRIMARYKEY AUTO_INCREMENT, NAME VARCHAR(20), age INT);4INSERTINTO users(NAME, age) VALUES('孤傲苍狼', 27);5INSERTINTO users(NAME, age) VALUES('白虎神皇', 27);将SQL脚本在MySQL数据库中执行,完成创建数据库和表的操作,如下:到此,前期的开发环境准备工作全部完成。
2.2、使用MyBatis查询表中的数据1、添加Mybatis的配置文件conf.xml在src目录下创建一个conf.xml文件,如下图所示:conf.xml文件中的内容如下:1<?xml version="1.0" encoding="UTF-8"?>2<!DOCTYPE configuration PUBLIC "-////DTD Config 3.0//EN" "/dtd/mybatis-3-config.dtd">3<configuration>4<environments default="development">5<environment id="development">6<transactionManager type="JDBC"/>7<!-- 配置数据库连接信息 -->8<dataSource type="POOLED">9<property name="driver" value="com.mysql.jdbc.Driver"/>10<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> 11<property name="username" value="root"/>12<property name="password" value="XDP"/>13</dataSource>14</environment>15</environments>1617</configuration>2、定义表所对应的实体类,如下图所示:User类的代码如下:1package me.gacl.domain;23/**4 * @author gacl5 * users表所对应的实体类6*/7publicclass User {89//实体类的属性和表的字段名称一一对应10privateint id;11private String name;12privateint age;1314publicint getId() {15return id;16 }1718publicvoid setId(int id) {19this.id = id;20 }2122public String getName() {23return name;24 }2526publicvoid setName(String name) { = name;28 }2930publicint getAge() {31return age;32 }3334publicvoid setAge(int age) {35this.age = age;36 }3738 @Override39public String toString() {40return "User [id=" + id + ", name=" + name + ", age=" + age + "]";41 }42 }3、定义操作users表的sql映射文件userMapper.xml创建一个me.gacl.mapping包,专门用于存放sql映射文件,在包中创建一个userMapper.xml文件,如下图所示:userMapper.xml文件的内容如下:1<?xml version="1.0" encoding="UTF-8" ?>2<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd">3<!-- 为这个mapper指定一个唯一的namespace,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的4例如namespace="erMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml文件去除后缀)5-->6<mapper namespace="erMapper">7<!-- 在select标签中编写查询的SQL语句,设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复8使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型9 resultType="er"就表示将查询结果封装成一个User类的对象返回10 User类就是users表所对应的实体类11-->12<!--13根据id查询得到一个user对象14-->15<select id="getUser" parameterType="int"16 resultType="er">17 select * from users where id=#{id}18</select>19</mapper>4、在conf.xml文件中注册userMapper.xml文件1<?xml version="1.0" encoding="UTF-8"?>2<!DOCTYPE configuration PUBLIC "-////DTD Config 3.0//EN""/dtd/mybatis-3-config.dtd">3<configuration>4<environments default="development">5<environment id="development">6<transactionManager type="JDBC"/>7<!-- 配置数据库连接信息 -->8<dataSource type="POOLED">9<property name="driver" value="com.mysql.jdbc.Driver"/>10<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>11<property name="username" value="root"/>12<property name="password" value="XDP"/>13</dataSource>14</environment>15</environments>1617<mappers>18<!-- 注册userMapper.xml文件,19 userMapper.xml位于me.gacl.mapping这个包下,所以resource写成me/gacl/mapping/userMapper.xml-->20<mapper resource="me/gacl/mapping/userMapper.xml"/>21</mappers>2223</configuration>5、编写测试代码:执行定义的select语句创建一个Test1类,编写如下的测试代码:package me.gacl.test;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import er;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;publicclass Test1 {publicstaticvoid main(String[] args) throws IOException {//mybatis的配置文件String resource = "conf.xml";//使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)InputStream is =Test1.class.getClassLoader().getResourceAsStream(resource);//构建sqlSession的工厂SqlSessionFactory sessionFactory = newSqlSessionFactoryBuilder().build(is);//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件) //Reader reader = Resources.getResourceAsReader(resource);//构建sqlSession的工厂//SqlSessionFactory sessionFactory = newSqlSessionFactoryBuilder().build(reader);//创建能执行映射文件中sql的sqlSessionSqlSession session = sessionFactory.openSession();/*** 映射sql的标识字符串,* erMapper是userMapper.xml文件中mapper标签的namespace属性的值,* getUser是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL*/String statement = "erMapper.getUser";//映射sql的标识字符串//执行查询返回一个唯一user对象的sqlUser user = session.selectOne(statement, 1);System.out.println(user);}}执行结果如下:可以看到,数据库中的记录已经成功查询出来了。
关于Mybatis的@Param注解及mybatisMapper中各种传递参数的⽅法关于Mybatis的@Param注解Mybatis 作为⼀个轻量级的数据持久化框架,⽬前(2018)的应⽤⾮常⼴泛,基本可以取代Hibernate。
关于 @param 这个注解的使⽤,作者这⾥整理了⼀些笔记。
关于Mybatis @Param 注解,官⽅⽂档:其中关于 @param部分的说明是:@Param Parameter N/A 如果你的映射器的⽅法需要多个参数, 这个注解可以被应⽤于映射器的⽅法参数来给每个参数⼀个名字。
否则,多参数将会以它们的顺序位置来被命名 (不包括任何 RowBounds 参数) ⽐如。
#{param1} , #{param2} 等 , 这是默认的。
使⽤ @Param(“person”),参数应该被命名为 #{person}。
也就是说如果有多个参数的时候,可以使⽤@Param 这个注解,但是不是⼀定需要⽤到 @Param 这个注解呢?作者在这⾥列出以下⼏种情景1.传递单个参数,不使⽤ @Param 注解代码如下:DAO 层CommodityDao.javapackage com.ljq.cs.dao;/*** @description: 商品信息 DAO 接⼝* @author: lujunqiang* @email: flying9001@* @date: 2017/12/17*/@Repositorypublic interface CommodityDao {// 查询某⼀件商品Commodity queryOne(Commodity commodity);// 省略其他⽅法}Mapper ⽂件: commoditymapper.xml<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd"><mapper namespace="modityDao" ><select id="queryOne" resultType="Commodity">select *from t_commodity comwhere id = #{id}</select></mapper>这⾥只有⼀个参数,java 接⼝不使⽤ @Param 注解,同时 mapper ⽂件也不需要使⽤ parameterType 这个参数,Mybatis会根据实体类(entity)的类型⾃动识别并匹配javaBean(这⼀部分在 spring配置⽂件关于数据源那⼀部分)2.传递单个参数,使⽤@Param注解代码如下:DAO 层CommodityDao.javapackage com.ljq.cs.dao;/*** @description: 商品信息 DAO 接⼝* @author: lujunqiang* @email: flying9001@* @date: 2017/12/17*/@Repositorypublic interface CommodityDao {// 查询某⼀件商品Commodity queryOne(@Param("commodity")Commodity commodity);// 省略其他⽅法}Mapper ⽂件: commoditymapper.xml<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd"><mapper namespace="modityDao" ><select id="queryOne" parameterType="modity" resultType="Commodity">select *from t_commodity comwhere id = #{commodity.id}</select></mapper>当使⽤javaBean作为对象的时候,在写 SQL 语句的时候,必须指定参数类型parameterType="modity",同时在#{ }取值的时候不能直接填⼊javaBean的属性,必须这样使⽤commodity.id ;否则,会抛出参数类型不匹配异常如果不是javaBean,则需要在写 SQL 语句的时候, #{ }中的属性必须与 @Param中定义的⼀致,eg: @Param("username") , #{username} ,这样才可以3.传递多个参数,使⽤ @Param 注解为了精简代码,作者这⾥只写关键部分DAO 层, UserInfoDao.java// ⽤户登录UserInfo signin(@Param("account")String account,@Param("passcode")String passcode);mapper⽂件userInfomapper.xml<!-- ⽤户登录 --><select id="signin" resultType="UserInfo">select *from t_userinfo infowhere account=#{account} and passcode=#{passcode}</select>这⾥ @Param 中定义的变量名必须和 mapper 中保持⼀致才可以4.传递多个参数,不使⽤ @Param 注解其实从第⼀种场景中已经可以实现传递多个参数了,即把多个参数封装到⼀个javaBean中就可以实现了,但是如果是两个或者多个javaBean 的时候,可以通过使⽤@Param注解的⽅式来实现,但是需要把每个javaBean中的属性全部拆分出来,这样就增加了巨⼤的代码量,因此不推荐这么做那么有没有可以不使⽤@Param注解,同样也可以传递多个参数(尤其是多个javaBean)呢?答案是有的,废话不多说,直接上代码同上,这⾥只贴出关键部分DAO 层, UserInfoDao.java// 搜索⽤户,对结果进⾏分页List searchUser(Map<String,Object>);使⽤DAO,UserService.javaUserInfo userInfo = new UserInfo();Pagination page = new Pagination();Map<String,Object> map = new HashMap<>;map.put("userInfo",userInfo);pam.put("page",page);userService.searchUser(map);mapper⽂件userInfomapper.xml<select id="searchUser" parameterType="java.util.Map" resultType="UserInfo">select *from t_userinfo userwhere 1 =1<if test="user.uname != null and ''!= user.uname ">and user.uname like '%${userInfo.uname}$%'</if><if test="page.order != null and page.order == 10" >order by user.id asc</if>limit ${page.pagenum * page.limitnum}, #{page.limitnum}</select>作者通过上边的4种情况,主要是为了说明,Mybatis⽆论是传单个参数,还是传递多个参数,没有必要使⽤@Param注解啊使⽤@param 注解增添了不少代码不说,还容易导致错误,尤其是在 mapper ⽂件中(paraterType属性)以上只是作者的列举的部分代码,源码请看这⾥:。
MyBatis实现原理一、概述MyBatis是一款优秀的持久层框架,其核心原理是基于数据访问对象(DAO)模式,通过将数据库操作与业务逻辑进行分离,提供了一种简洁、灵活的方式来访问数据库。
本文将从以下几个方面详细介绍MyBatis的实现原理。
二、MyBatis架构MyBatis的架构可以分为三层:SQL映射层、数据源层和事务层。
其中,SQL映射层负责处理SQL语句的解析和映射;数据源层负责对数据库进行操作;事务层则负责处理业务操作的事务。
2.1 SQL映射层2.1.1 SQL解析MyBatis通过XML配置或注解的方式来定义SQL语句,其中XML配置方式是主要的方式。
在解析XML配置文件时,MyBatis使用了XPath来定位SQL语句的位置,并利用Java的反射机制将SQL语句与对应的DAO接口方法绑定。
2.1.2 SQL映射在SQL映射过程中,MyBatis将SQL语句分为静态SQL和动态SQL。
静态SQL是指在XML配置文件中定义的固定的SQL语句,而动态SQL则是根据业务需求在运行时生成的SQL语句。
2.2 数据源层MyBatis使用数据源来管理数据库连接。
在数据源层,MyBatis提供了多种数据源的实现,包括JDBC数据源、连接池数据源等。
通过数据源,MyBatis可以很方便地获取数据库连接,并在数据操作完成后释放连接。
2.3 事务层事务管理是企业级应用中非常重要的一环。
MyBatis提供了对事务的支持,可以用于对数据库操作进行事务管理。
在事务层,MyBatis使用JDBC的事务机制或声明式事务来管理事务的提交和回滚,保证数据的原子性、一致性、隔离性和持久性。
三、MyBatis执行流程MyBatis的执行流程可以分为四个阶段:配置解析阶段、初始化阶段、SQL执行阶段和结果映射阶段。
3.1 配置解析阶段在配置解析阶段,MyBatis会读取XML配置文件或注解,解析出数据源配置、SQL 语句配置等信息,并将其加载到内存中。
Mybatis-Plus实战完整学习笔记(九)------条件构造器核⼼⽤法⼤全(上)⼀、Mybatisplus通⽤(公共⽅法)CRUD,⼀共17种(3.0.3版),2.3系列也是这么多,这个新版本⼀定程度进⾏了改造和删减。
⼆、构造器UML图(3.0.3)-----实体包装器,主要⽤于处理 sql 拼接,排序,实体参数查询等1. 注意: 使⽤的是数据库字段,不是 Java 属性!总体就是⼊上图的样式的结构,主要使⽤QueryWrapper 和UpdateWrapper,JDK1.8使⽤LambdaQueryWrapper和LambdaUpdateWrapper 注意2.3版本使⽤的是EntityWrapper实现条件构造器,这⾥将阐述和说明构造器拼接的⽅法实战演练:(3.0.3版)1、全部查询,拼接⼀个where过滤条件1 @Test2 public void selectWrapper() throws SQLException {345 // 条件构造器使⽤67 // 1、全部查询,拼接⼀个where过滤条件,如果是多个可以map中put多个,多个字段如果有某个字段是空的,就会默认添加空查询条件8 // SELECT id,last_name,email,gender,age FROM tbl_employee WHERE gender = ? AND age IS NULL9 Employee employee = new Employee();10 employee.setGender(1);1112 Map<String,Object> map = new HashMap<>(16);13 map.put("gender",employee.getGender());14 map.put("age",employee.getAge());1516 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().allEq(map));171819 if (!employeeList.isEmpty()) {20 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));21 }22 }View Code注意2.3版本的可以⽤EntityWrapper代替QureyWrapper,其他写法⼀样2、map添加的字段是否加到where的条件中1 @Test2 public void selectWrapper() throws SQLException {345 // 条件构造器使⽤6 Map<String,Object> map = new HashMap<>(16);7 map.put("gender",employee.getGender());8 map.put("age",employee.getAge());910 // 2、map添加的字段是否加到where的条件中,通过lambda表达式判断,如果是true就加⼊,反之,不加⼊,因为Map的key的String有gender,所以会过滤11 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().allEq((String,Object)->String.equals("gender"),map));121314 if (!employeeList.isEmpty()) {15 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));16 }17 }View Code3、and使⽤1 @Test2 public void selectWrapper() throws SQLException {34 // 条件构造器使⽤5 // 3、and使⽤67 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().and(i -> i.eq("last_name", "Betty0")));89 if (!employeeList.isEmpty()) {10 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));11 }View Code相当于SQL语句SELECT id,last_name,email,gender,age FROM tbl_employee WHERE ( last_name = ? )and前会有⼀个condition,判别是否加⼊到sql语句中的条件,默认是trueList<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().and(true,i -> i.eq("last_name", "Betty0")));4、apply拼接条件使⽤1 4、apply使⽤2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().apply("last_name='Betty0'"));345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code外部参数调⽤的话List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().apply("last_name= {0}","Betty0"));5、between使⽤⽅法1 5、between2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().between("age",20,50));34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code6、eq 等于 =1 6、eq 充当and使⽤2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().eq("last_name","Betty0"));34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code7、ge⼤于等于 >=1 7、ge⼤于等于23 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().ge("age","40"));456 if (!employeeList.isEmpty()) {7 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));8 }View Code8、gt⼤于1 // 8 、gt ⼤于2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().gt("age","40"));34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code9、分组操作1 // 9、分组操作2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().eq("id","25").groupBy("age","gender")); 34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code10、having使⽤1 10、having使⽤2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().eq("gender","1").having("age = {0}",30)); 34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code11、in使⽤1 // 11、in 操作2 List<Integer> idList = new ArrayList<>();3 idList.add(31);4 idList.add(32);56 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().in(true,"id",idList));7 if (!employeeList.isEmpty()) {8 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));9 }View Code12、inSql使⽤1 12、inSql使⽤2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().inSql("id", "12,22,23,24,25,26"));3 if (!employeeList.isEmpty()) {4 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));5 }View Code13、isNotNull字段值⾮空1 13、字段值⾮空2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().isNotNull("age"));34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code14、字段值为空的1 14、字段值为空的2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().isNull("age"));34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code15、结尾拼接sql语句,存在Sql注⼊风险,不建议使⽤1 15、结尾拼接sql语句2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().last("and age >30"));345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code16、⼩于等于 <=1 16、⼩于等于 <=2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().le("age", "20"));34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code17、⼩于1 17、⼩于2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().lt("age", "20"));345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code18、模糊查询1 18、模糊查询2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().like("age", "20"));345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code19、LikeLeft以什么结尾的查询1 19、 LikeLeft以什么结尾的查询2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().likeLeft("age", "20"));345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code20、likeRight以什么开头1 20、likeRight以什么开头2 // List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().likeRight("age", "20"));34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code21、ne不等于 <>⽤法1 21、ne不等于 <>⽤法2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().ne("age", "20"));345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code22、嵌套的查询1 22、嵌套的查询2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().nested(true,i -> i.eq("last_name", "Betty0")));3456 if (!employeeList.isEmpty()) {7 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));8 }View Code23、不在什么区间1 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().notBetween("age",20,50));23 if (!employeeList.isEmpty()) {4 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));5 }View Code24、不存在notexist1 24、不存在2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().notExists("select id from tbl_employee where age = 1")); 34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code25、存在exist1 25、存在2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().exists("select id from tbl_employee where age = 12")); 345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code26、not in 不在区间内1 List<Integer> idList = new ArrayList<>();2 idList.add(31);3 idList.add(32);4 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().notIn("id",idList));56 if (!employeeList.isEmpty()) {7 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));8 }View Code27、notSQL 不在区间内1 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().notInSql("id","12,22"));234 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code28、notLike 模糊查询没有这个关键字1 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().notLike("age", "2"));23 if (!employeeList.isEmpty()) {4 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));5 }View Code29、orderBy根据字段升序还是降序排序1 29、orderBy根据字段升序还是降序排序2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().orderBy(true, false, "age"));345 if (!employeeList.isEmpty()) {6 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));7 }View Code30、or或者1 30、or或者2 List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<Employee>().eq("id","25").or().eq("gender","1")); 34 if (!employeeList.isEmpty()) {5 ("++条件构造器查询员⼯信息+++++" + gson.toJson(employeeList));6 }View Code。
一、搭建开发环境1、在eclipse下建立web项目;2、将mybatis-3.2.0-SNAPSHOT.jar,mysql-connector-java-5.1.22-bin.jar 拷贝到web工程的lib目录;3、在mysql数据库里面创建数据库mybatis,并新建表user(省略详细步骤);4、在MyBatis 里面创建两个源码目录,分别为src_user, test_src,鼠标右键点击JavaResource;5、设置mybatis 配置文件:Configuration.xml, 在src_user目录下建立此文件,内容如下:< ?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-////DTD Config 3.0//EN""/dtd/mybatis-3-config.dtd"><configuration><typeAliases> //对应哪个类的别名和路径<typeAlias alias="User" type="er"/></typeAliases><!—下面是mysql数据库连接配置,固定--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" /><property name="username" value="root"/><property name="password" value="5201314"/></dataSource></environment></environments><mappers> //包含要映射的类的xml配置文件的路径<mapper resource="com/yihaomen/mybatis/model/User.xml"/></mappers></configuration>6、建立与数据库对应的java class,以及映射文件.在src_user下建立package:com.yihaomen.mybatis.model ,并在这个package 下建立User 类;主要包含属性和一些setter、getter方法;并在这个包下,建立于包外的Configuration.xml对应的User.xml文件:< ?xml version="1.0" encoding="UTF-8" ?>< !DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN""/dtd/mybatis-3-mapper.dtd">< mapper namespace="er"><select id="selectUserByID" parameterType="int" resultType="User">select * from `user` where id = #{id}</select>< /mapper>说明:1、Configuration.xml是mybatis 用来建立sessionFactory 用的,里面主要包含了数据库连接相关东西,还有java 类所对应的别名,比如<typeAlias alias="User"type="er"/> 这个别名非常重要,你在具体的类的映射中,比如User.xml 中resultType 就是对应这里的。
要保持一致;2、Configuration.xml 里面的<mapper resource="com/yihaomen/mybatis/model/User.xml"/>是包含要映射的类的xml配置文件。
3、在User.xml 文件里面主要是定义各种SQL 语句,以及这些语句的参数,以及要返回的类型等.到这里,mybatis就配置好了,下面就可以写测试程序了;在test_src文件夹下建立包,并建立test测试类:内容省略。
这种方式是用SqlSession实例来直接执行已映射的SQL语句:session.selectOne("erMapper.selectUserByID", 1);二、以接口的方式编程1、在src_user源码目录下建立com.yihaomen.mybatis.inter 这个包,并建立接口类IUserOperation ,内容如下:package com.yihaomen.mybatis.inter;import java.util.List;import er;public interface IUserOperation {public User selectUserByID(int id);// public List<User> selectUsers(String userName);}注意,这里面有一个方法名selectUserByID 必须与User.xml 里面配置的select 的id 对应(<select id="selectUserByID")并且要将User.xml的namespace改成namespace="com.yihaomen.mybatis.inter.IUserOperation"重写测试代码:public static void main(String[] args) {SqlSession session = sqlSessionFactory.openSession();try {IUserOperation userOperation = session.getMapper(IUserOperation.class);for(int i=1;i<5;i++){User user = userOperation.selectUserByID(i);System.out.println(user.getUserAddress());System.out.println(user.getUserName());System.out.println("-----------------");}} finally {session.close();}}完成测试;三、实现数据的增删改查1、查询数据:前面已经讲过简单的,主要看查询出列表的,查询出列表,也就是返回list, 在我们这个例子中也就是List<User> 这种方式返回数据,需要在User.xml 里面配置返回的类型resultMap, 注意不是resultType, 而这个resultMap 所对应的应该是我们自己配置的:public void getUserList(String userName){SqlSession session = sqlSessionFactory.openSession();try {IUserOperationuserOperation=session.getMapper(IUserOperation.class);List<User> users = userOperation.selectUsers(userName);for(User user:users){System.out.println(user.getId()+"、"+user.getUserName()+"、"+user.getUserAddress());}} finally {session.close();}}public static void main(String[] args) {Test2 testUser=new Test2();testUser.getUserList("%");}2、用mybatis 增加数据在IUserOperation 接口中增加方法:public void addUser(User user);在User.xml 中配置:< !--执行增加操作的SQL语句。
id和parameterType 分别与IUserOperation接口中的addUser方法的名字和参数类型一致。
以#{name}的形式引用Student参数的name属性,MyBatis将使用反射读取Student参数的此属性。
#{name}中name大小写敏感。
引用其他的gender等属性与此一致。
seGeneratedKeys设置为"true"表明要MyBatis获取由数据库自动生成的主键;keyProperty="id"指定把获取到的主键值注入到Student的id属性--><insert id="addUser" parameterType="User"useGeneratedKeys="true" keyProperty="id">insert into user(userName,userAge,userAddress)values(#{userName},#{userAge},#{userAddress})</insert>然后在Test 中写测试方法:/*** 测试增加,增加后,必须提交事务,否则不会写入到数据库.*/public void addUser(){User user=new User();user.setUserAddress("人民广场");user.setUserName("飞鸟");user.setUserAge(80);SqlSession session = sqlSessionFactory.openSession();try {IUserOperationuserOperation=session.getMapper(IUserOperation.class);userOperation.addUser(user);mit();System.out.println("当前增加的用户 id为:"+user.getId());} finally {session.close();}}3、用mybatis 更新数据方法类似,先在IUserOperation 中增加方法:public void addUser(User user);然后配置User.xml:<update id="updateUser" parameterType="User" >update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id}</update>然后在Test 中写测试方法:public void updateUser(){//先得到用户,然后修改,提交。