数据库中的字段如果和javabean里面的实体类的属性名不一致的话。怎么查询
User{id=1, name='狂神', password='null'} 查询出来发现 password 为空 . 说明出现了问题! 分析: select * from user where id = #{id} 可以看做 select id,name,pwd from user where id = #{id} mybatis会根据这些查询的列名(会将列名转化为小写,数据库不区分大小写) , 去对应的实体类中查找相应列名的set方法设值 , 由于找不到setPwd() , 所以password返回null ; 【自动映射】运行的结果是:由password='null’改为正常
User{id=1, name='狂神', password='123456'}把UserMaspper.xml中的resultType改为resultMap
<!--可以给实体类起别名--> <typeAliases> <package name="com.zhou.pojo"/> </typeAliases> <!--结果集映射,返回值类型,User类型,因为我引入了包的别名 那个resultMap中的值要和resultMap的id保持一致 --> <resultMap id="UserMap" type="User"> <!--column数据库中的字段,property实体类的属性--> <result column="id" property="id"/> <result column="name" property="name"/> <!--也可以只写下面这个,哪个需要就写哪个--> <result column="pwd" property="password"/> </resultMap> <select id="getUserById" resultMap="UserMap"> <!--select * from mybatis.user where id=#{id}--> select * from mybatis.user where id=#{id} </select>这样也可以
如果一个数据库,出现了异常,我们需要排错,日志就是最好的助手 曾经的:sout,debug 现在:日志工厂 Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具: SLF4J Apache Commons Logging Log4j 2 Log4j(掌握) JDK logging
在主配置中引入配置文件 <!--引入外部的配置文件--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>测试,可以看到控制台有大量输出!我们可以通过这些输出来判断到底是哪里出现了bug。
什么是log4j
Log4j是Apache的一个开源项目通过使用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件…我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。 导入log4j的包 <!--在项目中pom.xml中导入依赖log4j--> <dependencies> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> 在resources中创建配置文件。log4j.properties #将等级为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/zhou.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 在mybatis_config.xml配置中引入外部的配置文件 <!--引入外部的配置文件--> <settings> <setting name="logImpl" value="LOG4J"/> </settings> 直接运行之前的通过id查询方法测试 简单的使用,如果要在输出日志的类中加入相关的语句,在程序中使用Log4j进行输出log文件前面有?,解决方法:https://blog.csdn.net/hahah1024/article/details/108086744?utm_medium=distribute.pc_relevant.none-task-blog-title-7&spm=1001.2101.3001.4242
// 提升作用域 static Logger logger = Logger.getLogger(UserMapperTest.class); @Test public void test3(){ // 调用配置的对象 logger.info("info:进入selectUser方法"); logger.debug("debug;进入selectUser方法"); logger.error("error:进入selectUser方法"); }思考:为什么需要分页?
在学习mybatis等持久层框架的时候,会经常对数据进行增删改查操作,使用最多的是对数据库进行查询操作,如果查询大量数据的时候,我们往往使用分页进行查询,也就是每次处理小部分数据,这样对数据库压力就在可控范围内。
# 语法 select * from user limit straIndex,pageSize; -- startIndex是从什么索引开始查,pageSize是每页规定查多少索引 # 如果limit后面只有单个数的话,那么从[0,n]那个数就是n select * from user limit 3; -- 就是从[0,3] select * from user limit 5, 10; -- 检测的记录行为6~15 。从索引6开始,一共到索引x,一共有10个,所以 x=15.如果快速记住则两个数相加 实现分页功能 写接口,实现分页:返回值类型是User对象,并且分页后User对象不止一个,所以返回值类型就是List ,名字:SelectUser。参数类型:有两个参数,startIndex和pageSize。 List<User> selectUser(Map<String,Integer> map); 修改Mapper的配置 注意:这里的sql的参数,没有像之前id=#{id},这样是因为这两个参数,数据库的表中是没有对应的字段的。所以不能用=,赋值。直接写对应的参数 <!--分页查询,注意这个参数和返回值类型,我把这个resultType改为resultMap那个对象的属性就不是null了--> <select id="selectUser" parameterType="map" resultMap="UserMap"> select * from user limit #{startIndex},#{pageSize} </select> 在测试类中传入参数进行测试 // 分页查询,在测试类中传入参数进行测试 @Test public void testSelectUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); HashMap<String, Integer> map = new HashMap<>(); // map使用的是put放数据进去,简单的测试可以放具体的数字 map.put("startIndex",0); map.put("pageSize",2); // 把参数给弄进去 List<User> users = mapper.selectUser(map); for (User user : users) { System.out.println(user); } // 关闭sqlSession sqlSession.close(); } 如果是使用抽象的参数:推测:起始位置:(当前页面 - 1)* 页面大小 @Test public void testSelectUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 给从第几个开始,假设从当前页为2 int currentPage = 1; int pageSize = 2; // 每页显示2个 HashMap<String, Integer> map = new HashMap<>(); // map使用的是put放数据进去,简单的测试可以放具体的数字 map.put("startIndex",(currentPage-1)*pageSize); map.put("pageSize",pageSize); // 把参数给弄进去 List<User> users = mapper.selectUser(map); for (User user : users) { System.out.println(user); } // 关闭sqlSession sqlSession.close(); }Limit在SQL层面实现分页,也可以使用RowBounds在Java代码层面实现分页,当然此种方式作为了解即可。
mapper接口 //选择全部用户RowBounds实现分页 List<User> getUserByRowBounds(); mapper配置 <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.kuang.mapper.UserMapper.getUserByRowBounds", null, rowBounds); for (User user: users){ System.out.println(user); } session.close(); }官方文档:https://pagehelper.github.io/