五 .解决属性名和字段名不一样的问题
测试视图类字段不一致的情况。
属性名:
@Alias("user1")
public Class User{
private int id;
private String name;
private String password;
public User(){
}
}
实体类的password对应的是pwd字段。我们需要取别名来解决不一致的情况。
select id.name,pwd as passwrod from mybatis.user where id =#{id}
五 .1 resultMap结果集映射
<!-- 结果集映射-->
<resultMap id="UserMap" type="user">
<!-- colum数据库中的字段,property实体类中的属性-->
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
</resultMap>
<select id="getUserById" resultMap="UserMap" >
select id,name,pwd from mybatis.user where id = #{id}
</select>
- resultMap元素是Mybatis种最重要最强大地元素。
- ResultMap的设计思想是,对于简单的语句做到零配置,对于一些复杂的语句,只需要昴宿语句之间的关系就行了。
- ResultMap的优秀之处在于,完全可以不用显示的配置他们。
- 显示使用外部的ResutMap会怎么样,这也是解决列名不匹配的另一种方式。
六.日志
六.1 日志工厂
在Mybatis中具体使用哪个日志实现,在设置设定。
STDOUT_LOGING标准日志输出
在mybatis-config.xml中配置STDOUT_LOGGING日志:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
六.2 LOG4J
什么是LOG4J?
-
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等
-
我们也可以控制每一条日志的输出格式
-
可以通过一个配置文来灵活地进行配置,而不需要修改应用的代码。
-
导入lo4g包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- 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
- 文件输出的相关设置
og4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.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
- 配置lo4g日志的实现
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
- 使用:
- 在要使用Log4j的类中,导入包import org.apache.log4j.Logger;
- 日志对象,加载参数为当前类的class
static Logger logger = Logger.getLogger(UserDaoTest.class);
- 日志级别
logger.info("info:进入了testLo4g");
logger.debug("DEBUG:进入了testLo4g");
logger.error("error:进入了testLo4g");
七.分页
分页的作用
- 较少数据的处理
select * from user limit 2,2;# 第二个开始的两个
七.1 使用Limit分页
使用Mybatis实现分页,核心SQL
- 接口
// 分页查询
List<User> getUserByLimit(Map<String,Integer> map);
- 接口实现文件Mapper.xml
<select id="getUserByLimit" resultType="com.example.mybatistest.bean.User" parameterType="map">
select * from user limit #{startIndex},#{pageSize}
</select>
- 测试
@Test
public void getUserByLimit(){
SqlSession sqlSession = MybatisUntils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
HashMap<String, Integer> map = new HashMap<>();
map.put("startIndex",1);
map.put("pageSize",2);
List<User> list = mapper.getUserByLimit(map);
for (User user : list) {
System.out.println(user.toString());
}
sqlSession.close();
}
七.2 RowBounds分页
使用java自带的RowBounds类实现分页
sql不需要使用分页
- 接口
//使用RowBounds实现分页
List<User> getRowBounds();
- mapper.xml
<!-- 结果集映射-->
<resultMap id="UserMap" type="com.example.mybatistest.bean.User">
<!-- colum数据库中的字段,property实体类中的属性-->
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="password" property="password"/>
</resultMap>
<select id="getRowBounds" resultMap="UserMap">
select * from user;
</select>
- 测试
//测试RowBounds
@Test
public void getRowBounds(){
//RowBounds实现
RowBounds rowBounds = new RowBounds(0, 2);
SqlSession sqlSession = MybatisUntils.getSqlSession();
List<User> userList = sqlSession.selectList("com.example.mybatistest.dao.UserDao.getRowBounds",null,rowBounds);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
七.3 分页插件
Mybatis分页插件PageHelper
八. 使用注解开发
八.1 面向接口编程
- 大家之前都学过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程
- 根本原因:解耦,可拓展,提高复用,分层开发中,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好
- 在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了;
- 而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。
关于接口的理解
- 从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
- 接口的本身反映了系统设计人员对系统的抽象理解。
接口应有两类: - 第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);
- 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
- 一个体有可能有多个抽象面。抽象体与抽象面是有区别的。
三个面向区别:
- 面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法.
- 面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现
- 接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题更多的体现就是对系统整体的架构
八.2 使用注解开发
- 接口
package com.example.mybatistest.dao;
import com.example.mybatistest.bean.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
}
- 注册mapper-cpnfig.xml
<mappers>
<mapper resource="mybatis/UserMapper.xml"/>
<mapper class="com.example.mybatistest.dao.UserMapper"/>
</mappers>
- 测试
// 测试
@Test
public void getUsers(){
SqlSession sqlSession = MybatisUntils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUsers();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
实现的本质是反射机制
mybatis执行过程
- Resource获取全局配置文件
- 实例化SqlsessionFactoryBuilder
- 解析配置文件流XMLCondigBuilder
- Configration所有的配置信息
- SqlSessionFactory实例化
- transactional事务管理
- 创建executor执行器
- 创建SqlSession
- 实现CRUD
- 查看是否执行成功
- 提交事务
- 关闭
八.3 CRUD
在工具类创建的时候自动提交事务
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}
- 绑定接口注册
<mappers>
<mapper class="com.example.mybatistest.dao.UserMapper"/>
</mappers>
- 编写接口,增加注解
public interface UserMapper {
@Select("select * from user")
List<User> getUsers();
//方法存在多个参数,所有的参数前面必须加上@Param("id")注解,sql中用的是注解中的id
@Select("select * from user where id=#{id}")
User getUsersById(@Param("id") int id);
@Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
int addUser(User user);
@Update("update user set name=#{name},pwd=#{password} where id=#{id}")
int uptateUser(User user);
@Delete("delete from user where id=#{id}")
int deleteUser(@Param("id") int id);
}
- 测试
package com.example.mybatistest;
import com.example.mybatistest.bean.User;
import com.example.mybatistest.dao.UserMapper;
import com.example.mybatistest.util.MybatisUntils;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class UserMapperTest {
@Test
public void getUsers(){
SqlSession sqlSession = MybatisUntils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUsers();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
@Test
public void getUsersById(){
SqlSession sqlSession = MybatisUntils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUsersById(2);
System.out.println(user);
sqlSession.close();
}
@Test
public void addUser(){
SqlSession sqlSession = MybatisUntils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.addUser(new User(6, "高启强", "66666"));
sqlSession.close();
}
@Test
public void uptateUser(){
SqlSession sqlSession = MybatisUntils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.uptateUser(new User(5, "高启盛", "111111"));
sqlSession.close();
}
@Test
public void deleteUser(){
SqlSession sqlSession = MybatisUntils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.deleteUser(4);
sqlSession.close();
}
}
八.4 关于@Param()注解
- 基本类型的参数或者String类型,需要加上
- 引用类型不需要加上
- 如果只有一个基本类型的话,可以忽略,但是建议加上。
- 我们在SQL中引用的就是@Param()中设定的属性名。