【Mybatis】05 - Mybatis注解开发
2020-09-06 本文已影响0人
itlu
1. Mybatis注解开发
1.1 创建项目
- 创建一个Maven工程不使用骨架。
- 创建实体类:
/**
* User实体类
* @author lyp
*/
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// 省略 setter 和 getter toString方法
}
- 编写UserDao持久层接口,并编写查询所有的方法;使用@Select注解标注。
/**
* User持久层接口
* @author lyp
*/
public interface UserDao {
/**
* 查询所有用户信息
* @return
*/
@Select("select * from user")
List<User> findAll();
}
- 编写数据库连接信息配置文件 jdbcConfig.properties文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
- 在resources目录下创建SqlMapConfig.xml全局配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--使用配置文件方式引入数据库配置-->
<properties resource="jdbcConfig.properties"/>
<typeHandlers>
<package name="com.lyp.domain.User"/>
</typeHandlers>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<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.lyp.dao"/>
</mappers>
</configuration>
- 编写测试类进行测试 :
public class MybatisAnnotationTest {
public static void main(String[] args) throws IOException {
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
UserDao userDao = session.getMapper(UserDao.class);
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
session.close();
}
}
1.2 Mybatis注解开发实现对数据库的CRUD
- 在UserDao接口中编写对应的方法,并使用 @Select 、 @Insert 、 @Update、@Delete等注解进行sql语句的编写:
/**
* User持久层接口
* @author lyp
*/
public interface UserDao {
/**
* 查询所有用户信息
* @return
*/
@Select("select * from user")
List<User> findAll();
/**
* 保存用户信息
* @param user
*/
@Insert("insert into user (username , birthday,address,sex) values (#{username},#{birthday},#{address},#{sex})")
void saveUser(User user);
/**
* 修改用户信息
* @param user
*/
@Update("update user set username = #{username} , birthday = #{birthday} , sex = #{sex} where id = #{id}")
void updateUser(User user);
/**
* 根据用户id查询用户信息
* @param uid
* @return
*/
@Select("select * from user where id = #{uid}")
User findById(Integer uid);
/**
* 查询当前用户数
* @return
*/
@Select("select count(*) from user")
int findTotal();
/**
* 根据用户id删除用户信息
* @param uid
*/
@Delete("delete from user where id = #{id}")
void deleteById(Integer uid);
/**
* 根据用户名进行模糊查询
* @param username
* @return
*/
@Select("select * from user where username like #{username}")
List<User> findUserByUsername(String username);
}
- 编写测试类进行测试 :
/**
* Mybatis 注解开发 实现对数据库的CRUD
* @author lyp
*/
public class MybatisAnnotationCrud {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private UserDao userDao;
@Before
public void init() throws IOException {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
session = factory.openSession();
userDao = session.getMapper(UserDao.class);
}
@After
public void destroy() {
session.commit();
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (session != null) {
session.close();
}
}
/**
* 保存用户信息
*/
@Test
public void testSaveUser() {
User user = new User();
user.setUsername("Mybatis Annotation save User");
user.setAddress("重庆市渝北区");
userDao.saveUser(user);
}
/**
* 修改用户信息
*/
@Test
public void testUpdateUser() {
User user = new User();
user.setId(62);
user.setUsername("Mybatis Annotation update User");
user.setBirthday(new Date());
user.setSex("男");
userDao.updateUser(user);
}
/**
* 根据用户id进行查询
*/
@Test
public void testFindById() {
User user = userDao.findById(62);
System.out.println(user);
}
/**
* 查询所有用户数
*/
@Test
public void testFindTotal() {
int total = userDao.findTotal();
System.out.println(total);
}
/**
* 根据用户id删除用户信息
*/
@Test
public void testDeleteById() {
userDao.deleteById(60);
}
/**
* 根据用户名模糊查询用户信息
*/
@Test
public void testFindUserByUsername() {
List<User> users = userDao.findUserByUsername("%晓%");
for (User user : users) {
System.out.println(user);
}
}
}
1.3 实体类属性和数据库列的对应关系
- 新建一个项目使用 一对多的项目 。 修改实体类属性如下所示:
/**
* User实体类
* @author lyp
*/
public class User implements Serializable {
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
//setter 和 getter 方法 和 toString方法
}
- 这里进行查询将会出现实体类属性名称和列名不对应,导致数据封装不进去的情况:
- 第一种方式:可以采用为数据库列名起别名的方式。第二种方式是使用@Result注解的方式。这里将使用第二种。
/**
* 查询所有用户信息
* @return
*/
@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();
@Result 注解
引用ResultMap
1.4 一对一 , 查询每个账户下的用户信息
- 编写账户实体类 :
/**
* 账户实体类
*/
public class Account implements Serializable {
private Integer id;
private Integer userId;
private Double money;
// setter 和 getter toString方法
}
- 编写Account账户持久层接口:
/**
* @author lyp
* Account 持久层接口
*/
public interface AccountDao {
/**
* 查询所有账户信息
* @return
*/
@Select("select * from account")
List<Account> findAll();
}
- 在账户实体中配置一对一(其实是一对多,在Mybatis中一对多就代表一对一)关系映射:
/**
* 账户实体类
*/
public class Account implements Serializable {
private Integer id;
private Integer userId;
private Double money;
private User user;
// 省略setter 和getter方法 toString 方法
}
在Account实体中配置一对一关系映射
- 使用 @Results、@Results、@One等注解配置:
/**
* @author lyp
* Account 持久层接口
*/
public interface AccountDao {
/**
* 查询所有账户信息
*
* @return
*/
@Select("select * from account")
@Results(id = "accountMap", value = {
@Result(column = "id", property = "id"),
@Result(column = "uId", property = "userId"),
@Result(column = "money", property = "money"),
@Result(column = "uid", property = "user", one = @One(select = "com.lyp.dao.UserDao.findById", fetchType = FetchType.LAZY))
})
List<Account> findAll();
}
使用到的注解
-
在一对多查询多个的时候需要使用延迟加载
-
在一对一查询一的时候需要使用立即加载
1.5 一对多,查询每个用户下的多个用户信息
- 在User实体中添加一对多关系映射:
/**
* User实体类
* @author lyp
*/
public class User implements Serializable {
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
private List<Account> accounts;
// setter 和 getter 方法 toString 方法
}
- 配置UserDao持久层接口中的@Results注解配置:
/**
* 查询所有用户信息
* @return
*/
@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"),
@Result(column = "id",property = "accounts" ,
many = @Many(select = "com.lyp.dao.AccountDao.findByUId",fetchType = FetchType.LAZY))
})
List<User> findAll();
一对多映射配置
2. 缓存配置 (二级缓存)
- 首先演示未使用缓存的情况:
@Test
public void testFindById() {
SqlSession session1 = factory.openSession();
UserDao userDao1 = session1.getMapper(UserDao.class);
User user1 = userDao1.findById(62);
System.out.println(user1);
session1.close();
SqlSession session2 = factory.openSession();
UserDao userDao2 = session2.getMapper(UserDao.class);
User user2 = userDao2.findById(62);
System.out.println(user2);
session2.close();
}
- 未使用缓存的控制台打印如下 :
- 配置缓存 : 首先在全局配置文件SqlMapConfig.xml配置文件下加上对二级缓存的支持。然后在持久层接口上加上注解@CacheNamespace(blocking = true)注解。
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
/**
* User持久层接口
* @author lyp
* 在接口上开启对二级缓存的支持
*/
@CacheNamespace(blocking = true)
public interface UserDao {....}
- 配置二级缓存之后 :