使用注解开发,可以减少Mapper映射文件的编写。
1、myBatis常用注解
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
2、使用注解实现基本CRUD
2.1、主配置文件
<configuration>
<!-- 引入外部配置文件 -->
<properties resource="jdbc.properties"/>
<!-- 实体类别名配置 -->
<typeAliases>
<package name="com.junlong.domain"/>
</typeAliases>
<!-- 环境配置 -->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 持久层接口配置 -->
<mappers>
<package name="com.junlong.dao"/>
</mappers>
</configuration>
2.2、持久层接口(注解开发)
public interface UserDao {
/**
* 查询所有用户
*
* @return 返回所有用户列表 List<User>
*/
@Select("select * from user")
@Results(
id = "userMap",
value = {
@Result(id = true, column = "id", property = "userId"),
@Result(column = "username", property = "userName"),
@Result(column = "birthday", property = "userBirthday"),
@Result(column = "sex", property = "userSex"),
@Result(column = "address", property = "userAddress")
}
)
List<User> findAll();
/**
* 根据用户id查询用户信息
*
* @param id 用户id
* @return 返回用户对象 User
*/
@Select("select * from user where id = #{id}")
@ResultMap("userMap")
User findById(int id);
/**
* 新增用户
*
* @param user 用户对象
*/
@Insert("insert into user (username, birthday, sex, address) VALUES (#{userName}, #{userBirthday}, #{userSex}, #{userAddress})")
@SelectKey(keyColumn = "id", keyProperty = "userId", resultType = Integer.class, before = false, statement = "select last_insert_id()")
void saveUser(User user);
/**
* 更新用户信息
*
* @param user 用户对象
*/
@Update("update user set username = #{userName}, address = #{userAddress}, birthday = #{userBirthday}, sex = #{userSex} where id = #{userId}")
void updateUser(User user);
/**
* 根据用户id删除用户(物理删除)
*
* @param id 用户id
*/
@Delete("delete from user where id = #{id}")
void deleteUser(Integer id);
/**
* 聚合函数查询总记录数
*
* @return 返回总记录数
*/
@Select("select count(*) from user")
int findTotal();
/**
* 根据用户名模糊查询
*
* @param name 用户名(带 %)
* @return 返回符合条件的用户列表
*/
@Select("select * from user where username like #{username}")
@ResultMap("userMap")
List<User> findByName(String name);
}
2.3、 测试
public class UserTest {
private InputStream inputStream;
private SqlSession sqlSession;
private UserDao userDao;
@Before
public void init() throws IOException {
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();
userDao = sqlSession.getMapper(UserDao.class);
}
@After
public void destroy() throws IOException {
sqlSession.commit();
sqlSession.close();
inputStream.close();
}
/**
* 测试查询所有用户
*/
@Test
public void testFindAll() {
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
/**
* 测试根据用户id查询用户
*/
@Test
public void testFindById() {
User user = userDao.findById(51);
System.out.println(user);
}
/**
* 测试新增用户
*/
@Test
public void testSaveUser() {
User user = new User();
user.setUserName("new user");
user.setUserBirthday(new Date());
user.setUserSex("女");
user.setUserAddress("阿尔及利亚");
System.out.println("保存前:" + user);
userDao.saveUser(user);
System.out.println("保存后:" + user);
}
/**
* 测试更新用户信息
*/
@Test
public void testUpdateUser() {
User user = userDao.findById(51);
user.setUserName("updateUser");
user.setUserAddress("刚果金");
userDao.updateUser(user);
}
/**
* 测试删除用户
*/
@Test
public void testDeleteUser() {
userDao.deleteUser(50);
}
/**
* 测试查询总记录数(聚合函数查询)
*/
@Test
public void testFindTotal() {
int total = userDao.findTotal();
System.out.println("共 " + total + " 条记录");
}
/**
* 测试根据用户名模糊查询
*/
@Test
public void testFindByName() {
List<User> users = userDao.findByName("%王%");
for (User user : users) {
System.out.println(user);
}
}
}
3、基于注解的二级缓存
3.1、主配置文件
<configuration>
<!-- 外部配置文件 -->
<properties resource="jdbc.properties"/>
<!-- 开启二级缓存 -->
<settings>
<!-- cacheEnabled 默认取值为 true,可以省略不配 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 实体类别名 -->
<typeAliases>
<package name="com.junlong.domain"/>
</typeAliases>
<!-- 环境配置 -->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- dao路径 -->
<mappers>
<package name="com.junlong.dao"/>
</mappers>
</configuration>
3.2、用户持久层接口开启二级缓存(注解开发)
// 配置二级缓存
@CacheNamespace(blocking = true)
public interface UserDao {
/**
* 根据用户id查询用户
*
* @param id 用户id
* @return 返回用户对象
*/
@Select("select * from user where id = #{id}")
User findById(Integer id);
}
3.3、测试
public class UserTest {
private InputStream inputStream;
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException {
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@After
public void destroy() throws IOException {
inputStream.close();
}
/**
* 测试根据用户id查询用户(二级缓存)
*
* 注意:只有当sqlSession被 提交 或 关闭 后,二级缓存才能生效
*/
@Test
public void testFindById() {
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserDao userDao1 = sqlSession1.getMapper(UserDao.class);
User user1 = userDao1.findById(51);
System.out.println(user1);
sqlSession1.commit();
sqlSession1.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserDao userDao2 = sqlSession2.getMapper(UserDao.class);
User user2 = userDao2.findById(51);
System.out.println(user2);
sqlSession2.commit();
sqlSession2.close();
System.out.println(user1 == user2);
}
}
官方参考:mybatis中文网
https://mybatis.net.cn/