5、日志
5.1、搭建日志
在MyBatis的配置中,有settings标签,内部的属性可以配置日志,常用的日志是:LOG4J 、 STDOUT_LOGGING
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J 、LOG4J 、 LOG4J2 、 JDK_LOGGING 、COMMONS_LOGGING 、STDOUT_LOGGING、NO_LOGGING、 |
---|
-
STDOUT_LOGGING:直接在settings里配置即可使用
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
-
LOG4J :不能直接使用,需要配置依赖
-
pom文件导入依赖
<!-- log4j 日志--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
配置log4j.properties文件
### 设置日志级别和输出位置 ### log4j.rootLogger=DEBUG,console,logFile log4j.additivity.org.apache=true #日志输出级别 log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG # 输出到控制台(console) log4j.appender.console=org.apache.log4j.ConsoleAppender # 输出级别最低为DEBUG log4j.appender.console.Threshold=DEBUG # 表示所有消息都会被立即输出 log4j.appender.console.ImmediateFlush=true #输出日志到控制台的方式 log4j.appender.console.Target= System.out # 灵活布局输出日志 log4j.appender.console.layout=org.apache.log4j.PatternLayout #设定以怎样的格式显示消息。 log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] -%m%n # 日志文件(logFile) log4j.appender.logFile=org.apache.log4j.FileAppender log4j.appender.logFile.Threshold=DEBUG log4j.appender.logFile.ImmediateFlush=true log4j.appender.logFile.Append=true log4j.appender.logFile.File=D:/logs/log.log4j log4j.appender.logFile.layout=org.apache.log4j.PatternLayout log4j.appender.logFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] -%m%n
-
mybatis-config.xml配置settings
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
-
5.2、Log4j
Log4j有三个主要的组件:
-
Loggers(记录器):设定系统日志的类别和级别。(分别设置系统日志级别和输出级别,Log4j只输出级别不低于设定级别的日志信息)
等级(从高到低) OFF 最高级别关闭所有日志记录 FATAL 打印将会导致应用程序退出的错误 ERROR 发生错误事件,但仍不影响系统的继续运行,打印错误和异常,不会输出太多的日志信息 WARN 警告,即潜在的错误情形 INFO 用于粗粒度级别上,强调应用程序的运行全程,打印感兴趣或重要信息 DEBUG 用于细粒度级别上,对调试应用程序有帮助,主要用于打印一些运行信息 ALL 最低等级,用于打开所以的日志记录 log4j.rootLogger = [ 日志最低级别 ] , 指定日志信息要输出到哪里, 指定日志信息要输出到哪里, … log4j.rootLogger=debug,console,file #最低debug,输出到控制台和文件 log4j.additivity.org.apache=true #表示Logger会不会在父Logger的appender里输出
-
Appenders (输出源):日志要输出的地方。可设置控制台(Console)、文件(Files)等等
org.apache.log4j.ConsoleAppender(输出到控制台) Threshold=WARN:日志信息的最低输出级别,默认为DEBUG。 ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出 Target=System.err:输出日志到控制台的方式.认值是System.out。err是当错误输出为红色 org.apache.log4j.FileAppender(输出为文件) Threshold=WARN:日志信息的最低输出级别,默认为DEBUG。 ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出 Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。 File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。 org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件) Threshold=WARN :定日志信息的最低输出级别,默认为DEBUG。 ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。 Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。 File=D:/log/log.log4j:指定当前消息输出到那个文件中。 DatePattern:多久产生一个新文件,当前月的名字为设定的名字,前面的日志文件名为:设定名.时间。 '.'yyyy-MM:每月 '.'yyyy-ww:每周 '.'yyyy-MM-dd:每天 '.'yyyy-MM-dd-a:每天两次 '.'yyyy-MM-dd-HH:每小时 '.'yyyy-MM-dd-HH-mm:每分钟 org.apache.log4j.RollingFileAppender(文件达到指定大小的时候产生一个新的文件) Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。 ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。 Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。 File=D:/log/log.log4j:指定消息输出到loglog4j文件中。 MaxFileSize=10KB:后缀可以是KB, MB 或者GB。在日志文件到达该大小时,将会自动滚动 MaxBackupIndex=2:指定可以产生的滚动文件的最大数, org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
-
Layouts(布局):加在Appenders 之后,确定日志以何种形式输出
org.apache.log4j.HTMLLayout(以HTML表格形式布局) LocationInfo=true:输出java文件名称和行号,默认值是false。 Title=My Logging: 默认值是Log4J Log Messages。 org.apache.log4j.PatternLayout(灵活地指定布局模式) ConversionPattern=%m%n:设定以怎样的格式显示消息。 %p:输出日志信息的优先级 %d:输出日志时间点的日期或时间 %r:输出自应用程序启动到输出该log信息耗费的毫秒数 %t:输出产生该日志事件的线程名。 %%:输出一个"%“字符。 %L::输出代码中的行号。 %F:输出日志消息产生时所在的文件名称。 %M:输出产生日志信息的方法名。 %c:输出日志信息所属的类的全名。 %l:输出日志事件的发生位置 org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串) org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)
6、注解开发
很多时候后使用XML的映射文件会有一些繁琐,所以Mybatis提供了一些注解代替XML映射文件。
-
Mapper包的扫描:有三种方式
-
@Mapper注解:在Mapper接口上添加,就可以不用在XML文件中配置了
-
@MapperScan({“包1”,“包2”……}):用在核心配置类上,用来扫描mapper接口所在包,可以扫描多个包。不用每个接口都添加@Mapper了
-
在Spring的XML配置文件中通过配置 MapperScannerConfigurer 扫描
<!--注入mapper接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--扫描mapper接口所在的包--> <property name="basePackage" value="com.yu.mapper"/> </bean>
-
-
增删改查
- @Insert(“SQL语句”):新增
- @Delete(“SQL语句”):删除
- @Update(“SQL语句”):更新
- @Select (“SQL语句”):查询
public interface UserMapper { //根据id查询用户名 @Select("select user.username from user where user.user_id = #{id} ") String getUserNameByI(int id); //新增一个用户 @Insert("insert into user(username, password) values (#{username} ,#{password} )") void insetUser(User user); //修改 @Update("update user set username=#{username} ,password=#{password} ") void updateUser(User user); //删除 @Delete("delete from user where user_id = #{id} ") void deleteUser(int id); }
-
复杂关系映射:实现复杂关系映射之前我们可以在映射文件中通过配置
<resultMap>
来实现,在使用注解开发时我们需要借助@Results 注解,@Result 注解,@One 注解,@Many 注解。-
@Results:与@Result 一起使用,封装多个结果集,@Results({@Result(),@Result()})
-
@Result :结果集封装,代替了
<id>
标签和<result>
标签@Result 中的属性 介绍 id 是否是主键字段 column 数据库的列名 property 需要装配的属性名 one 需要使用的@One 注解(@Result(one=@One)())) many 需要使用的@Many 注解(@Result(many=@many)())) -
@ResultMap:引用@Results 定义的封装
public interface ClassesMapper { @Select("select * from classes where c_id=#{id} ") @Results(id="classesMap",value = { @Result(id = true, column = "c_id", property = "cId"), @Result(column = "classes_name", property = "classesName"), @Result(column = "is_deleted", property = "isDeleted") }) Classes getClassesByID(int id); @Select("select * from classes") @ResultMap("classesMap") List<Classes> getClassesAll(); }
-
@One:一对一结果集封装,代替了
<assocation>
标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。@Result(column=" “,property=”“,one=@One(select=”")) -
@Many:一对多结果集封装,代替了
<collection>
标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。@Result(property=“”,column=“”,many=@Many(select=“”))public interface StudentMapper { @Select("select * from student,classes where s_id = #{id} and c_id = student.classes_id") @Results(id="StudentMap",value = { @Result(id=true,column = "s_id",property = "sId"), @Result(column = "student_name",property = "studentName"), @Result(column = "classes_id",property = "classes", one = @One(select = "com.yu.mapper.ClassesMapper.getClassesByID") ) //映射为对象,一对多就用many=@Many(select="") }) Student getStudentByID(int id); }
-
-
@SelectProvider(type=xxxx.class,method=”xxxx”):反射一个自定义的类,使用类中的方法构造SQL语句。这个类可以使用方法返回SQL语句,添加SelectProvider后就能映射到自定义的类,还能用来拼接动态sql
public interface StudentMapper { @Select("select * from student,classes where s_id = #{id} and c_id = student.classes_id") @Results(id = "StudentMap", value = { @Result(id = true, column = "s_id", property = "sId"), @Result(column = "student_name", property = "studentName"), @Result(column = "classes_id", property = "classes", one = @One(select = "com.yu.mapper.ClassesMapper.getClassesByID") ) //映射为对象 }) Student getStudentByID(int id); //查询1班内所有学生 @SelectProvider(type = StudnetSQLProvider.class, method = "selectUser") @ResultMap("StudentMap") List<Student> selectUser(String Classesname); @SelectProvider(type = StudnetSQLProvider.class, method = "getStudentNameByID") String getStudentNameByID(int id); }
//SelectProvider映射的文件 public class StudnetSQLProvider { public String selectUser(String Classesname){ //使用SQL对象动态化sql语句 String sql = new SQL() {{ SELECT("*"); FROM("classes", "student"); WHERE("classes_id=c_id"); if(!StringUtils.isEmpty(Classesname)){ WHERE("classes_name='"+Classesname+"'"); } }}.toString(); System.out.println(sql); return sql; } public String getStudentNameByID(int id){ //返回一个sql语句 return "select student_name from classes,student where classes_id=c_id and s_id = '"+id+"'"; } }
-
@CacheNamespace:用于Mapper上,是用来实现二级缓存的
-
@Param(value=“id”):用来方法传递的参数上,解决参数名字不匹配的问题