环境搭建
单表CRUD操作(代理Dao方式)
1. 查询所有用户
实体类
public class User implements Serializable{
private Integer userId;
private String userName;
private String userAddress;
private String userSex;
private Date userBirthday;
// ...
}
接口
/**
* 查询所有用户
**/
@Select("select * from user")
List<User> findAll();
Test
/**
* 测试基于注解的MyBatis使用
* @param args
*/
public static void main(String[] args) throws Exception {
// 1.获取字节输入流
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.根据字节输入流构建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
// 3.根据SqlSessionFactory生产一个SqlSession
SqlSession sqlSession = factory.openSession();
// 4.使用sqlSession获取Dao的代理对象
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
// 5.执行Dao方法
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
// 6.释放资源
sqlSession.close();
in.close();
}
2. 保存用户
接口
/**
* 保存用户
*/
@Insert("insert into user(username,address,sex,birthday)
values(#{username},#{address},#{sex},#{birthday})")
void saveUser(User user);
Test
public class AnnocationCRUDTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before
public void init() throws Exception {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
sqlSession = factory.openSession();
userDao = sqlSession.getMapper(IUserDao.class);
}
@After
public void destroy() throws Exception {
sqlSession.commit();
sqlSession.close();
in.close();
}
@Test
public void testSave() {
User user = new User();
user.setUsername("mybatis annotation");
user.setAddress("天津");
userDao.saveUser(user);
}
}
3. 更新用户
接口
/**
* 更新用户
*/
@Update("update user set username=#{username},sex=#{sex},
birthday=#{birthday},address=#{address} where id=#{id}")
void updateUser(User user);
Test
@Test
public void testUpdate(){
User user = new User();
user.setId(51);
user.setUsername("mybatis annotation update");
user.setAddress("北京市海淀区");
user.setSex("男");
user.setBirthday(new Date());
userDao.updateUser(user);
}
4. 删除用户
接口
/**
* 删除用户
*/
@Delete("delete from user where id=#{id} ")
void deleteUser(Integer userId);
Test
@Test
public void testDelete(){
userDao.deleteUser(50);
}
5. 根据id查询用户
接口
/**
* 根据id查询用户
*/
@Select("select * from user where id=#{id} ")
User findById(Integer userId);
Test
@Test
public void testFindOne(){
User user = userDao.findById(52);
System.out.println(user);
}
6. 根据用户名称模糊查询
接口
/**
* 根据用户名称模糊查询
* 还有一种写法:
* @Select("select * from user where username like '%${value}%' ")
*/
@Select("select * from user where username like #{username} ")
List<User> findUserByName(String username);
Test
@Test
public void testFindByName(){
List<User> users = userDao.findUserByName("%mybatis%");
//List<User> users = userDao.findUserByName("mybatis");
for(User user : users){
System.out.println(user);
}
}
7. 查询总用户数量
接口
/**
* 查询总用户数量
*/
@Select("select count(*) from user ")
int findTotalUser();
Test
@Test
public void testFindTotal(){
int total = userDao.findTotalUser();
System.out.println(total);
}
多表查询操作
1. 多对一
实体类
Account
package cn.luis.domain;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
/**
* 多对一(mybatis中称之为一对一)的映射:一个账户只能属于一个用户
*/
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
// ...
}
接口
IAccount.java
/**
* 查询所有账户,并且获取每个账户所属的用户信息
*/
@Select("select * from account")
@Results(id="accountMap",value = {
@Result(id=true,column = "id",property = "id"),
@Result(column = "uid",property = "uid"),
@Result(column = "money",property = "money"),
// 封装user属性
@Result(property = "user",column = "uid",
one=@One(select="com.luis.dao.IUserDao.findById",
fetchType= FetchType.EAGER))
})
List<Account> findAll();
IUserDao.java
/**
* 根据id查询用户
* value = {"userMap"}
* 若属性只有一个的时候value可省略:{"userMap"}
* 若数组中只有一个元素时{}可省略: "userMap"
*/
@Select("select * from user where id=#{id} ")
// 在前面定义过了,直接引用
@ResultMap(value = {"userMap"})
User findById(Integer userId);
Test
@Test
public void testFindAll(){
List<Account> accounts = accountDao.findAll();
for(Account account : accounts){
System.out.println("----每个账户的信息-----");
System.out.println(account);
System.out.println(account.getUser());
}
2. 一对多
-
查询所有用户 以及对应的账户信息**【一对多】**
一对多关系映射:一个用户对应多个账户
实体类
public class User implements Serializable{
private Integer userId;
private String userName;
private String userAddress;
private String userSex;
private Date userBirthday;
/**
* 一对多关系映射:一个用户对应多个账户
*/
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
//...
}
注意
-
解决属性和数据库表名不同 @Results、 @Result
-
select:指定要执行操作的全限定类名
-
fetchType
:指定加载的时机
接口
IUserDao.java
/**
* @Description 查询所有用户
* 解决属性和数据库表名不同 @Results、 @Result
* select:指定要执行操作的全限定类名
* fetchType:指定加载的时机
**/
@Select("select * from user")
@Results(id = "userMap", value = {
@Result(id=true,column = "id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "address",property = "userAddress"),
@Result(column = "sex",property = "userSex"),
@Result(column = "birthday",property = "userBirthday"),
@Result(property = "accounts",column = "id",
many = @Many(select = "cn.luis.dao.IAccountDao.findAccountByUid",
fetchType = FetchType.LAZY))
})
List<User> findAll();
IAccountDao.java
/**
* 根据用户id查询账户信息
*/
@Select("select * from account where uid = #{userId}")
List<Account> findAccountByUid(Integer userId);
Test
@Test
public void testFindAll(){
List<User> users = userDao.findAll();
for(User user : users){
System.out.println("---每个用户的信息----");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
3. 缓存的配置
一级缓存
若有缓存,只查询一次,第二次直接获取
UserTest.java
/**
* 测试一级缓存
*/
@Test
public void testFindOne(){
User user = userDao.findById(51);
System.out.println(user);
User user2 = userDao.findById(51);
System.out.println(user2);
}
二级缓存
- 在
SqlMapConfig
中配置开启二级缓存
<configuration>
<!--配置开启二级缓存-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
//...
</configuration>
- 在接口上开启二级缓存的使用:
@CacheNamespace(blocking = true)
@CacheNamespace(blocking = true)
public interface IUserDao {
...
}
- 测试方法
public class SecondLevelCatchTest {
private InputStream in;
private SqlSessionFactory factory;
@Before
public void init() throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
}
@After
public void destroy() throws Exception{
in.close();
}
/**
* 测试mabatis的二级缓存
* 【配置SqlMapConfig.xml】
* 【配置接口:IUserDao】
*/
@Test
public void testFindOne(){
SqlSession session = factory.openSession();
IUserDao userDao = session.getMapper(IUserDao.class);
User user = userDao.findById(51);
System.out.println(user);
//释放一级缓存
session.close();
//再次打开session
SqlSession session1 = factory.openSession();
IUserDao userDao1 = session1.getMapper(IUserDao.class);
User user1 = userDao1.findById(51);
System.out.println(user1);
session1.close();
}
}