电脑网站制作软件,3d溜溜网室内设计图库,烟台电子商务网站,wordpress增加幻灯片一、mybatis动态SQL update 表名 set name?,age? where id? 如果我们的前台没有传参#xff0c;比如没有传入我们的name值#xff0c;name就会把字段值改为null#xff0c;这就违背了我们编码的初衷。 许多人会使用类似于where 1 1 来作为前缀#xff0c;在代码中会用i…一、mybatis动态SQL update 表名 set name?,age? where id? 如果我们的前台没有传参比如没有传入我们的name值name就会把字段值改为null这就违背了我们编码的初衷。 许多人会使用类似于where 1 1 来作为前缀在代码中会用if判断是否为null再用and进行一个sql拼接。 我们可以用常用的几个标签 1、if 再if标签里面test里面的条件满足了才会把后面的sql语句进行拼接 !-- 示例 --
select idupdateByPrimaryKeySelective parameterTypecom.tgq.model.BookSELECT * FROM Book WHERE price 9.9if testname ! null and name ! AND name like %${name}%/if
/select
2、foreach 我们再调用删除的方法的时候通常会与SQL语句中的IN查询条件结合使用。 delete from student where id in parameterType为List链表或者Array数组后面在引用时参数名必须为list或者array。如在foreach标签中collection属性则为需要迭代的集合由于入参是个List所以参数名必须为list。 select idselectById resultTypecom.tgq.model.Book parameterTypejava.util.List selectinclude refidBase_Column_List/from t_mvc_bookwhere bid inforeach collectionbids itembid open( separator, close)#{bid}/foreach/select 测试一下结果 Testpublic void selectById() {ListInteger bids Arrays.asList(new Integer[]{30, 31, 32, 33});bookbiz.selectById(bids).forEach(System.out::println);} 3、choose、when、otherwise 你可以使用choose、when和otherwise元素来实现类似于switch语句的逻辑。 select idgetUser parameterTypeint resultTypeUserSELECT * FROM usersWHERE 11choosewhen testid ! nullAND id #{id}/whenwhen testname ! nullAND name #{name}/whenotherwiseAND status ACTIVE/otherwise/choose
/select如果传入的id不为空则会在SQL语句中包含AND id #{id}这个条件如果传入的name不为空则会在SQL语句中包含AND name #{name}这个条件否则会在SQL语句中包含AND status active这个条件。 二、mybatis模糊查询 我们写入一个xml文件log4j2.xml 用于打印出来你的sql语句 ?xml version1.0 encodingUTF-8?!-- status : 指定log4j本身的打印日志的级别.ALL Trace DEBUG INFO WARN ERROR FATAL OFF。 monitorInterval : 用于指定log4j自动重新配置的监测间隔时间单位是s,最小是5s. --
Configuration statusWARN monitorInterval30Properties!-- 配置日志文件输出目录 ${sys:user.home} --Property nameLOG_HOME/root/workspace/lucenedemo/logs/Propertyproperty nameERROR_LOG_FILE_NAME/root/workspace/lucenedemo/logs/error/propertyproperty nameWARN_LOG_FILE_NAME/root/workspace/lucenedemo/logs/warn/propertyproperty namePATTERN%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%n/property/PropertiesAppenders!--这个输出控制台的配置 --Console nameConsole targetSYSTEM_OUT!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) --ThresholdFilter leveltrace onMatchACCEPTonMismatchDENY /!-- 输出日志的格式 --!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间 %p : 日志输出格式 %c : logger的名称%m : 日志内容即 logger.info(message) %n : 换行符 %C : Java类名 %L : 日志输出所在行数 %M: 日志输出所在方法名 hostName : 本地机器名 hostAddress : 本地ip地址 --PatternLayout pattern${PATTERN} //Console!--文件会打印出所有信息这个log每次运行程序会自动清空由append属性决定这个也挺有用的适合临时测试用 --!--append为TRUE表示消息增加到指定文件中false表示消息覆盖指定的文件内容默认值是true --File namelog fileNamelogs/test.log appendfalsePatternLayoutpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n //File!-- 这个会打印出所有的info及以下级别的信息每次大小超过size 则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩作为存档 --RollingFile nameRollingFileInfo fileName${LOG_HOME}/info.logfilePattern${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch --ThresholdFilter levelinfo onMatchACCEPTonMismatchDENY /PatternLayoutpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n /Policies!-- 基于时间的滚动策略interval属性用来指定多久滚动一次默认是1 hour。 modulatetrue用来调整时间比如现在是早上3aminterval是4那么第一次滚动是在4am接着是8am12am...而不是7am. --!-- 关键点在于 filePattern后的日期格式以及TimeBasedTriggeringPolicy的interval 日期格式精确到哪一位interval也精确到哪一个单位 --!-- log4j2的按天分日志文件 : info-%d{yyyy-MM-dd}-%i.log --TimeBasedTriggeringPolicy interval1modulatetrue /!-- SizeBasedTriggeringPolicy:Policies子节点 基于指定文件大小的滚动策略size属性用来定义每个日志文件的大小. --!-- SizeBasedTriggeringPolicy size2 kB / --/Policies/RollingFileRollingFile nameRollingFileWarn fileName${WARN_LOG_FILE_NAME}/warn.logfilePattern${WARN_LOG_FILE_NAME}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.logThresholdFilter levelwarn onMatchACCEPTonMismatchDENY /PatternLayoutpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n /PoliciesTimeBasedTriggeringPolicy /SizeBasedTriggeringPolicy size2 kB //Policies!-- DefaultRolloverStrategy属性如不设置则默认为最多同一文件夹下7个文件这里设置了20 --DefaultRolloverStrategy max20 //RollingFileRollingFile nameRollingFileError fileName${ERROR_LOG_FILE_NAME}/error.logfilePattern${ERROR_LOG_FILE_NAME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd-HH-mm}-%i.logThresholdFilter levelerror onMatchACCEPTonMismatchDENY /PatternLayoutpattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n /Policies!-- log4j2的按分钟 分日志文件 : warn-%d{yyyy-MM-dd-HH-mm}-%i.log --TimeBasedTriggeringPolicy interval1modulatetrue /!-- SizeBasedTriggeringPolicy size10 MB / --/Policies/RollingFile/Appenders!--然后定义logger只有定义了logger并引入的appenderappender才会生效 --Loggers!--过滤掉spring和mybatis的一些无用的DEBUG信息 --logger nameorg.springframework levelINFO/loggerlogger nameorg.mybatis levelINFO/logger!-- 第三方日志系统 --logger nameorg.springframework levelERROR /logger nameorg.hibernate levelERROR /logger nameorg.apache.struts2 levelERROR /logger namecom.opensymphony.xwork2 levelERROR /logger nameorg.jboss levelERROR /!-- 配置日志的根节点 --root levelallappender-ref refConsole /appender-ref refRollingFileInfo /appender-ref refRollingFileWarn /appender-ref refRollingFileError //root/Loggers/Configuration 1、mybatis模糊查询的三种方式
第一种 select idlike01 resultTypecom.tgq.model.Book parameterTypejava.util.Listselectinclude refidBase_Column_List/from t_mvc_bookwhere bname like #{bname}/select 测试的结果 Testpublic void like01() {bookbiz.like01(%圣%).forEach(System.out::println);}第二种$需要单引号$传参是占位符的形式 select idlike02 resultTypecom.tgq.model.Book parameterTypejava.util.Listselectinclude refidBase_Column_List/from t_mvc_bookwhere bname like ${bname}/select 测试的结果 Testpublic void like02() {bookbiz.like02(%圣%).forEach(System.out::println);}第三种 select idlike03 resultTypecom.tgq.model.Book parameterTypejava.util.Listselectinclude refidBase_Column_List/from t_mvc_bookwhere bname like concat(%,#{bname},%)/select 测试的结果 Testpublic void like03() {bookbiz.like03(%圣%).forEach(System.out::println);}2、mybatis中#与$的区别 $是占位符赋值#是预处理SQL。外在形式$传参不带引号#传参自带引号。$传参存在sql注入#不存在。$可以用来做动态列完成动态sql的开发。 三、MyBatis结果映射单表多表查询 resultMap idBaseResultMap typecom.tgq.model.BookconstructoridArg columnbid jdbcTypeINTEGER javaTypejava.lang.Integer/arg columnbname jdbcTypeVARCHAR javaTypejava.lang.String/arg columnprice jdbcTypeREAL javaTypejava.lang.Float//constructor/resultMap 这个代码中column属性写的是数据库里面的字段里面有一个name的属性是实体类里面的字段当数据库里面的字段喝实体类里面的字段是一样的可以不用写name属性 如果数据库里面出现了下划线比如data_time就需要在 arg columndata_time,nameDataTime jdbcTypeVARCHAR javaTypejava.lang.String/ 使用mybatis的各种场景 使用mybatis的各种场景返回的结果是多样的resultType/resultMap 返回单表的对应的实体类仅有一个查询结果可以用resultType/resultMap。 使用了resultType select idselectresultType resultTypecom.tgq.model.Book parameterTypejava.lang.Integerselectinclude refidBase_Column_List/from t_mvc_bookwhere bid #{bid,jdbcTypeINTEGER}/select 编写接口实现接口 Book selectresultType(Integer bid); Overridepublic Book selectresultType(Integer bid) {return bookMapper.selectresultType(bid);} 测试方法 Testpublic void selectresultType() {System.out.println(测试resultType查询);Book book bookbiz.selectByPrimaryKey(12);System.out.println(book);} 测试结果 返回单表的对应的实体类有多个查询结果可以用resultType/resultMap。 resultType/resultMap。resultType一个或多个都用实体对象 select idselectresultType01 resultTypecom.tgq.model.Bookselectinclude refidBase_Column_List/from t_mvc_book/selectselect idselectresultMap01 resultMapBaseResultMapselectinclude refidBase_Column_List/from t_mvc_book/select 编写接口方法和实现接口 ListBook selectresultType01();ListBook selectresultMap01(); Overridepublic ListBook selectresultType01() {return bookMapper.selectresultType01();}Overridepublic ListBook selectresultMap01() {return bookMapper.selectresultMap01();} 测试方法 Testpublic void selectresultType01() {bookbiz.selectresultType01().forEach(System.out::println);}Testpublic void selectresultMap01() {bookbiz.selectresultMap01().forEach(System.out::println);}测试结果是一样的返回多表的对应的实体类仅有一个查询结果通常用resultType也可以用resultMap。返回多表的对应的实体类有多个查询结果通常用resultType也可以用resultMap。 编写配置我们可以不用配置的表可以调用其他的表 select idselect01 resultTypejava.util.Map parameterTypejava.util.Mapselect s.*, sc.cid, sc.scorefrom t_mysql_student s,t_mysql_score scwhere s.sid sc.sidand sc.sid #{sid}and sc.cid #{cid}/selectselect idselect02 resultTypejava.util.Map parameterTypejava.util.Mapselect s.*, sc.cid, sc.scorefrom t_mysql_student s,t_mysql_score scwhere s.sid sc.sid/select 编写接口和实现类 Map select01(Map map);ListMap select02(Map map); Overridepublic Map select01(Map map) {return bookMapper.select01(map);}Overridepublic ListMap select02(Map map) {return bookMapper.select02(map);} 测试方法 Testpublic void select01() {Map map new HashMap();map.put(sid, 01);map.put(cid, 01);System.out.println(bookbiz.select01(map));}Testpublic void select02() {Map map new HashMap();map.put(sid, 01);map.put(cid, 01);bookbiz.select02(map).forEach(System.out::println);} 测试结果返回单个列表仅有一个查询结果就用resultType。返回单个列表有多个查询结果就用resultType。 配置xml !--单个--select idselectByString01 resultTypejava.lang.String parameterTypejava.lang.Integerselect bnamefrom t_mvc_bookwhere bid #{bid,jdbcTypeINTEGER}/select!--多个--select idselectByString02 resultTypejava.lang.String parameterTypejava.lang.Stringselect bnamefrom t_mvc_bookwhere bname like concat(%, #{bname}, %)/select 编写接口和实现接口 String selectByString01(Integer bid);ListString selectByString02(String bname); Overridepublic String selectByString01(Integer bid) {return bookMapper.selectByString01(bid);}Overridepublic ListString selectByString02(String bname) {return bookMapper.selectByString02(bname);} 测试方法 Testpublic void selectByString01() {System.out.println(bookbiz.selectByString01(60));}Testpublic void selectByString02() {Map map new HashMap();map.put(sid, 01);map.put(cid, 01);bookbiz.selectByString02(圣墟).forEach(System.out::println);} 测试结果 resultType对应返回类型。 resultMap对应返回映射关系指的是实体类与数据表字段关系。 单表查询返回单列返回多表查询结果是用resultType 查询的结果需要有关属性的体现那么就用resultMap 上一章【mybatis入门Idea搭建】