为了方便查看测试结果以及方便调试,先熟悉和配置日志。
如果一个数据库操作出现了异常、需要进行排错,可以通过查看日志的方式实现。
Mybatis内置的日志工厂能够提供日志功能,具体的日志实现有以下几种:
SLF4J
LOG4J(3.5.9 起废弃)
LOG4J2 | JDK_LOGGING
COMMONS_LOGGING
STDOUT_LOGGING
NO_LOGGING
在Mybatis中具体使用哪个日志实现,可以通过配置文件进行配置。如:设置标准日志输出(STDOUT_LOGGING)
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
logImpl
可选的值有:SLF4J
、LOG4J
、LOG4J2
、JDK_LOGGING
、COMMONS_LOGGING
、STDOUT_LOGGING
、NO_LOGGING
,或者是实现了接口org.apache.ibatis.logging.Log
,且构造方法是以字符串为参数的类的完全限定名。
导入依赖
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
在CLASSPATH下建立log4j.properties
log4j.rootLogger=debug,stdout,D,E
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %p %c\:%L - %m%n
log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
#修改到自己的路径下
log4j.appender.D.File=coding\JAVAIDEA\log\log.log
log4j.appender.D.Append=true
log4j.appender.D.Threshold=DEBUG
log4j.appender.D.layout=org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %p %c\:%L - %m%n
log4j.appender.E=org.apache.log4j.DailyRollingFileAppender
#修改到自己的路径下
log4j.appender.E.File=coding\JAVAIDEA\log\error.log
log4j.appender.E.Append=true
log4j.appender.E.Threshold=ERROR
log4j.appender.E.layout=org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
配置log4j为日志实现
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
使用
(1)创建日志对象(Logger),参数为当前类的Class
static Logger logger = Logger.getLogger(TestUserDao.class);
(2)注意导入的包为下面这个
import org.apache.log4j.Logger;
(3)日志级别
logger.info("info:进入了testLog4j");
logger.debug("debug:进入了testLog4j");
logger.error("error:进入了testLog4j");
使用分页可以减少数据的处理量。在java层面可以使用RowBounds
实现分页,市场上也有一些分页插件如:PageHelper
PageHelper
:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
在数据库中我们通常使用Limit来处理分页
SELECT * FROM user LIMIT startIndex, pageSize;
SELECT * FROM user LIMIT 3; #[0,n]
使用Mybatis实现分页(核心是SQL)
(1)接口
//分页
List<User> getUserByLimit(Map<String, Integer> map);
(2)Mapper.xml
<select id="getUserByLimit" parameterType="map" resultType="com.louis.pojo.User">
select * from mybatis.user limit #{startIndex}, #{pageSize}
select>
(3)测试
@Test
public void getUserByLimit(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Integer> map = new HashMap<>();
map.put("startIndex", 0);
map.put("pageSize", 2);
List<User> userByLimit = mapper.getUserByLimit(map);
for (User user : userByLimit) {
logger.info(user);
}
}
在接口上实现注解
@Select("select * from user")
List<User> getUsers();
在核心配置文件中绑定接口
<mappers>
<mapper class="com.louis.dao.UserMapper"/>
mappers>
数据库的部分操作需要设置提交事务。在工具类中自动提交事务,这样就不用再次commit
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}
编写接口,添加注解
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
//方法存在多个参数,所有的参数前面必须加上@Param注解
@Select("select * from user where id = #{id}")
User getById(@Param("id") int id);
@Insert("insert into user(id, name, pwd) values (#{id}, #{name}, #{pwd})")
int addUser(User user);
@Update("update user set name = #{name}, pwd = #{pwd} where id = #{id}")
int update(User user);
@Delete("delete from user where id = #{id}")
int delete(@Param("id") int id);
}
测试
@Test
public void getUserByLimit(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User userById = mapper.getById(1);
logger.info(userById);
sqlSession.close();
}
@Test
public void addUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.addUser(new User(6, "露露", "cty345"));
sqlSession.close();
}
@Test
public void update(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.update(new User(1, "Alex", "1234"));
logger.info(mapper);
sqlSession.close();
}
@Test
public void delete(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.delete(1);
logger.info(mapper);
sqlSession.close();
}
注意:在有多个实体类的接口时,我们必须要将接口注册绑定到我们的核心配置文件中。
@Param()
注解
Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不需要再写getter、setter或equals方法,只要有一个注解,就有一个功能齐全的构建器、自动记录变量等等。
在IDEA中安装Lombok插件
在项目中导入jar包
地址:https://mvnrepository.com
使用(标记表示常用)
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor
, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@StandardException
@val
@var
experimental @var
@UtilityClass
@Data
:可以帮助我们生成get, set, tostring, hashcode, equals
@AllArgsConstructor
:有参构造方法
@NoArgsConstructor
:无参构造方法