根本原因:解耦,可扩展、提高复用、在分层开发中上层设计和底层实现分离(即上层不用管底层的实现),大家都遵守共同的标准,使得开发变得容易,规范性好
关于接口的理解
3个面向的区别
上图就是mybatis官方文档对于使用注解开发的说明,我们需要从中理解到以下几点
实际操作
创建一个新model,mybatis-05,复制粘贴mybatis-04中的文件,测试model是否搭建成功
对于上面的输出有点乱,我们把log4j删除,直接使用标准日志输出来查看,前面官方文件上也说了,可以不使用mapper.xml文件了,那我们就把UserMapper.xml也删除
<configuration>
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="123"/>
properties>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
<typeAliases>
<package name="com.thhh.pojo"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
configuration>
package com.thhh.dao;
import com.thhh.pojo.User;
import org.apache.ibatis.annotations.Select;
//在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了
public interface UserMapper {
@Select("Select * from user")
User getUserList(int id);
}
<mappers>
<mapper class="com.thhh.dao.UserMapper"/>
mappers>
注意:现在由于没有了mapper.xml,所有现在映射SQL语句就只能依靠class或包扫描,这里使用的是class映射
package com.thhh.dao;
import com.thhh.pojo.User;
import com.thhh.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UserDaoTest {
static Logger logger = Logger.getLogger(UserDaoTest.class);
@Test
public void testGetUserByRowbounds(){
//1、获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
}
但是我们还是需要注意一下,使用注解查询出来的这个结果并不规范,因为password属性为null,原因就是我们在学习resultMap的时候将实体类User的pwd属性修改为了password,这就使得实体类的属性名称和数据表中的字段名称不一样,原来使用mapper.xml文件的时候,我们还可以通过设置resultMap来实现映射,现在使用注解,就不能使用resultMap了,所以官方文档才说复杂的操作还是推荐我们使用mapper.xml实现SQL语句的映射
首先我们修改一下工具类MyBatisUtils的代码,主要就是sqlSessionFactory的openSession()的参数
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession(true);
}
package com.thhh.dao;
import com.thhh.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
//在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了
public interface UserMapper {
@Select("Select * from user")
List<User> getUserList();
@Select("select * from user where id = #{id}")
User getUserById(@Param("id") int id);
}
注意:使用注解开发的时候,只要有参数,我们就需要在它的前面加上一个"**@Param(“属性值”)"**的注解,虽然只有一个参数的时候可以不加,但是为了规范和习惯,推荐只要有参数,我们都把参数写上
package com.thhh.dao;
import com.thhh.pojo.User;
import com.thhh.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;
public class UserDaoTest {
static Logger logger = Logger.getLogger(UserDaoTest.class);
@Test
public void testGetUserById(){
//1、获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserById(2);
System.out.println(user);
sqlSession.close();
}
}
通过对比,我们可以发现,SQL去参数值的时候是去取注解中的那个参数,而不是我们定义的方法中的那个参数
package com.thhh.dao;
import com.thhh.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
//在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了
public interface UserMapper {
//1、查询所有用户
@Select("Select * from user")
List<User> getUserList();
//2、按照id查询用户
@Select("select * from user where id = #{id}")
User getUserById(@Param("id") int id);
//3、新增用户
@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
int addUser(User user);
}
@Test
public void testAddUser(){
//1、获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int result = mapper.addUser(new User(8,"赵八","123"));
System.out.println("数据库受影响行数 = "+result);
sqlSession.close();
}
注意:上面我们并没有显式的提交事务,但是由测试结果我们可以发现,数据已经持久化到了数据库中,原因就是我们前面向openSession()中传入参数true,这就使得这个sqlsession对象会自动的提交事务
package com.thhh.dao;
import com.thhh.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
//在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了
public interface UserMapper {
//1、查询所有用户
@Select("Select * from user")
List<User> getUserList();
//2、按照id查询用户
@Select("select * from user where id = #{id}")
User getUserById(@Param("id") int id);
//3、新增用户
@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
int addUser(User user);
//4、修改用户信息
@Update("update user set name = #{name},pwd = #{password} where id = #{id}")
int updateUser(User user);
}
@Test
public void testUpdateUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(new User(2,"李四","123"));
sqlSession.close();
}
package com.thhh.dao;
import com.thhh.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
//在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了
public interface UserMapper {
//1、查询所有用户
@Select("Select * from user")
List<User> getUserList();
//2、按照id查询用户
@Select("select * from user where id = #{id}")
User getUserById(@Param("id") int id);
//3、新增用户
@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
int addUser(User user);
//4、修改用户信息
@Update("update user set name = #{name},pwd = #{password} where id = #{id}")
int updateUser(User user);
//5、删除用户
@Delete("delete from user where id = #{id}")
int deleteUser(int id);
}
@Test
public void testDeleteUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(8);
sqlSession.close();
}
MyBatis中使用parameterType向SQL语句传参,parameterType后的类型可以是基本类型int,String,HashMap和java自定义类型。
在SQL中引用这些参数的时候,可以使用两种方式#{parameterName}或者${parameterName}。
区别
#{}:#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号
$ {}:$将传入的数据直接显示生成在sql中
概念
重点