11.【Mybatis中的注解开发】

环境搭建

在这里插入图片描述

单表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);
    }

二级缓存

  1. SqlMapConfig中配置开启二级缓存
<configuration>
    <!--配置开启二级缓存-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
    
    //...
</configuration>
  1. 在接口上开启二级缓存的使用:@CacheNamespace(blocking = true)
@CacheNamespace(blocking = true)
public interface IUserDao {
	...
}
  1. 测试方法
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();
    }
}
发布了36 篇原创文章 · 获赞 14 · 访问量 3586

猜你喜欢

转载自blog.csdn.net/qq_39720594/article/details/105232021