Mybatis全解-03-ResultMap及分页
ResultMap
当实体类的属性与数据库中的表字段名不一致时出现的问题。
与之前的User类不同,这一次将其中的密码属性改为password。
而数据库中的表字段还是pwd。
public class User { private int id; //id private String name; //姓名 private String password; //密码和数据库不一样! //构造 //set/get //toString() }
接口和映射文件不变
//根据id查询用户 User selectUserById(int id);
<select id="selectUserById" resultType="user"> select * from user where id = #{id} </select>
测试
@Test public void testSelectUserById() { SqlSession session = MybatisUtils.getSession(); //获取SqlSession连接 UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(1); System.out.println(user); session.close(); }
结果发现,password='null'
结论:mybatis会根据查询的列名(自动将列名转化为小写,数据库不区分大小写),然后在对应的实体类中查找与列名对应的set方法设置值,由于找不到对应的setPwd();因此,查询的password值为空。
为了解决数据库列名与对象属性名不一致的问题,有下面两种解决方法。
1.为列名指定别名,别名和对象的属性名一致。 关键词:as
<select id="selectUserById" resultType="User"> select id , name , pwd as password from user where id = #{id} </select>
2.使用结果集映射。关键词:ResultMap
<resultMap id="UserMap" type="User"> <!-- id为主键 --> <id column="id" property="id"/> <!-- column是数据库表的列名 , property是对应实体类的属性名 --> <result column="name" property="name"/> <result column="pwd" property="password"/> </resultMap> <select id="selectUserById" resultMap="UserMap"> select id , name , pwd from user where id = #{id} </select>
ResultMap的设计思想是,对于简单的语句根本不需要配置显示的结果映射,而对于复杂一点的语句只需要描述他们之间的关系就好了。
日志工厂
日志的实现有多种工具,你只需要在mybatis核心配置文件mybatis-config.xml中配置即可。
标准的日志实现,配置好下面的设置之后,你就可以在控制台看到有大量的日志输出,有利于程序排错。
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
Log4j 最为常用的日志工具
通过Log4j,可以控制日志信息输出的目的地,如:控制台、文本、GUI组件...
并且可以控制每一条日志的输出格式。
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。所有的一切我们仅仅需要通过一个配置文件来完成,而不需要修改应用的代码。
使用Log4j的步骤:
1.在pom中导入Log4j的jar包
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
2.控制日志的配置文件编写
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/li.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
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
3.在mybatis核心配置文件中,添加Log4j的实现
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
4.在应用程序中使用Log4j进行输出
//注意导包:org.apache.log4j.Logger static Logger logger = Logger.getLogger(MyTest.class); @Test public void selectUser() { logger.info("info:进入selectUser方法"); logger.debug("debug:进入selectUser方法"); logger.error("error: 进入selectUser方法"); SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); List<User> users = mapper.selectUser(); for (User user: users){ System.out.println(user); } session.close(); }
5.结果
还生成了一个对应的日志文件
分页
limit分页
为什么需要分页,减少数据库的查询压力。
#语法 SELECT * FROM table LIMIT stratIndex,pageSize SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15 #为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1: SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last. #如果只给定一个参数,它表示返回最大的记录行数目: SELECT * FROM table LIMIT 5; //检索前 5 个记录行 #换句话说,LIMIT n 等价于 LIMIT 0,n。
示例:
//选择全部用户实现分页 List<User> selectUser(Map<String,Integer> map);
<select id="selectUser" parameterType="map" resultType="user"> select * from user limit #{startIndex},#{pageSize} </select>
注意公式:起始位置=(当前页面-1)*页面大小
//分页查询 , 两个参数startIndex , pageSize @Test public void testSelectUser() { SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); int currentPage = 1; //第几页 int pageSize = 2; //每页显示几个 Map<String,Integer> map = new HashMap<String,Integer>(); map.put("startIndex",(currentPage-1)*pageSize); map.put("pageSize",pageSize); List<User> users = mapper.selectUser(map); for (User user: users){ System.out.println(user); } session.close(); }
RowBounds分页
除了使用limit在sql层面实现分页,也可以使用RowBounds在java代码层面实现分页,了解即可,不推荐使用。
//选择全部用户RowBounds实现分页 List<User> getUserByRowBounds();
<select id="getUserByRowBounds" resultType="user"> select * from user </select>
@Test public void testUserByRowBounds() { SqlSession session = MybatisUtils.getSession(); int currentPage = 2; //第几页 int pageSize = 2; //每页显示几个 RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize); //通过session.**方法进行传递rowBounds,[此种方式现在已经不推荐使用了] List<User> users =session.selectList("com.li.mapper.UserMapper.getUserByRowBounds", null,rowBounds); for (User user: users){ System.out.println(user); } session.close(); }
第三方插件:PageHelper,还有MybatisPlus