我们在测试SQL的时候,要是能够在控制台输出 SQL 的话,是不是就能够有更快的排错效率?
是的,输出 SQL 可以帮助我们更好地理解代码的执行流程和结果。在控制台输出 SQL 可以让我们看到实际执行的 SQL 语句,这样就能够更轻松地检查 SQL 查询、插入或更新语句是否正确。此外,通过输出 SQL,还可以查看实际执行过程中的参数和变量的值,从而更好地调试代码问题。因此,在测试 SQL 的时候,输出 SQL 可以帮助我们提高排错效率,并提高代码质量。
为了方便开发者进行日志记录,Mybatis内置了日志工厂。该日志工厂支持多种具体的日志实现,包括以下几种工具:
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
介绍一下Log4j:
Log4j是Apache开源项目之一,它提供了灵活的日志功能,可以控制日志信息的输出目的地,如控制台、文本、GUI组件等。同时,我们也可以定义每条日志信息的输出格式,并通过定义不同级别的日志来更加精细地控制日志的生成过程。最为方便的是,这些设置都可以通过一个配置文件进行灵活配置,而无需修改应用程序的代码。
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
//注意导包: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();
}
为什么需要使用分页?
在使用持久层框架(如Mybatis)进行数据访问操作时,最常用的就是数据库的查询操作。当需要查询大量数据时,我们往往会采取分页的方式进行查询,即每次只查询一小部分数据。这样做的好处在于可以有效地减轻数据库的负担,保证系统的可靠性和稳定性。同时,通过分页操作还可以使查询结果更加清晰明了,方便用户查看相关数据。
#语法
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。
<select id="selectUser" parameterType="map" resultType="user">
select * from user limit #{startIndex},#{pageSize}
</select>
//选择全部用户实现分页
List<User> selectUser(Map<String,Integer> map);
//分页查询 , 两个参数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实现分页
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.kuang.mapper.UserMapper.getUserByRowBounds", null, rowBounds);
for (User user: users){
System.out.println(user);
}
session.close();
}
面向接口编程
总的来说,这些概念都是软件开发中的基础概念,对于系统的整体架构和开发方式都有很大的影响。
sql 类型主要分成 : @select () @update () @Insert () @delete ()
这是 SQL 语言中常用的四个操作类型:
这些操作类型是 SQL 语言中最基础的操作,用于对数据库进行增删改查等操作。在实际应用中,我们可以通过组合使用这些操作类型来完成更加复杂的操作,例如多表联合查询、批量更新等。掌握这些操作类型对于开发 SQL 数据库和进行数据处理非常重要。
//查询全部用户
@Select("select id,name,pwd password from user")
public List<User> getAllUser();
<!--使用class绑定接口-->
<mappers>
<mapper class="com.kuang.mapper.UserMapper"/>
</mappers>
@Test
public void testGetAllUser() {
SqlSession session = MybatisUtils.getSession();
//本质上利用了jvm的动态代理机制
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.getAllUser();
for (User user : users){
System.out.println(user);
}
session.close();
}
image.png
//获取SqlSession连接
public static SqlSession getSession(){
return getSession(true); //事务自动提交
}
public static SqlSession getSession(boolean flag){
return sqlSessionFactory.openSession(flag);
}
//根据id查询用户
@Select("select * from user where id = #{id}")
User selectUserById(@Param("id") int id);
@Test
public void testSelectUserById() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
session.close();
}
//添加一个用户
@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
@Test
public void testAddUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(6, "xx", "123456");
mapper.addUser(user);
session.close();
}
//修改一个用户
@Update("update user set name=#{name},pwd=#{pwd} where id = #{id}")
int updateUser(User user);
@Test
public void testUpdateUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(6, "xxxx", "3456");
mapper.updateUser(user);
session.close();
}
//根据id删除用
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id")int id);
@Test
public void testDeleteUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.deleteUser(6);
session.close();
}
关于 @Param 注解的用法,主要是为方法中的参数指定一个名称,以便在 SQL 语句中引用。以下是一些使用原则:
总之,使用 @Param 注解可以提高代码的可读性和可维护性,特别是在方法接收多个参数的情况下。而对于 JavaBean,则不需要使用 @Param 注解,因为 MyBatis 能够自动处理 JavaBean 属性名和参数名的映射关系。
public interface UserMapper {
/**
* 根据用户id查询用户信息
*
* @param userId 用户id
* @return 查询结果
*/
@Select("SELECT * FROM users WHERE id = #{userId}")
User getUserById(@Param("userId") Long userId);
/**
* 根据用户名和密码查询用户信息
*
* @param username 用户名
* @param password 密码
* @return 查询结果
*/
@Select("SELECT * FROM users WHERE username = #{username} AND password = #{password}")
User getUserByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
/**
* 插入新的用户记录
*
* @param user 用户对象
* @return 影响的行数
*/
@Insert("INSERT INTO users(username, password) VALUES(#{user.username}, #{user.password})")
int insertUser(@Param("user") User user);
/**
* 更新用户信息
*
* @param user 用户对象
* @return 影响的行数
*/
@Update("UPDATE users SET password = #{user.password} WHERE id = #{user.id}")
int updateUser(@Param("user") User user);
/**
* 删除用户记录
*
* @param userId 用户id
* @return 影响的行数
*/
@Delete("DELETE FROM users WHERE id = #{userId}")
int deleteUserById(@Param("userId") Long userId);
}
在 MyBatis 中,#{}
和 ${}
是用于 SQL 语句中参数占位的两种方式。
public interface UserMapper {
/**
* 根据用户名和密码查询用户信息
*
* @param username 用户名
* @param password 密码
* @return 查询结果
*/
@Select("SELECT * FROM users WHERE username = #{username} AND password = #{password}")
User getUserByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
/**
* 动态查询用户记录
*
* @param condition 查询条件
* @param orderField 排序字段
* @param orderType 排序方式
* @param limitStart 分页起始位置
* @param limitSize 分页大小
* @return 查询结果
*/
@Select("<script>"
+ "SELECT * FROM users"
+ "<where>"
+ "<if test='condition != null'>"
+ "<![CDATA[AND (username LIKE CONCAT('%',#{condition},'%') OR email LIKE CONCAT('%',#{condition},'%'))]]>"
+ "</if>"
+ "</where>"
+ "<if test='orderField != null and orderType != null'>"
+ "<![CDATA[ORDER BY ${orderField} ${orderType}]]>"
+ "</if>"
+ "<if test='limitStart != null and limitSize != null'>"
+ "<![CDATA[LIMIT #{limitStart},#{limitSize}]]>"
+ "</if>"
+ "</script>")
List<User> listUsers(@Param("condition") String condition, @Param("orderField") String orderField, @Param("orderType") String orderType, @Param("limitStart") Integer limitStart, @Param("limitSize") Integer limitSize);
}
仓库地址:https://github.com/webVueBlog/JavaGuideInterview