mybatis编程Mybatis

【Mybatis】05 - Mybatis注解开发

2020-09-06  本文已影响0人  itlu

1. Mybatis注解开发

1.1 创建项目

  1. 创建一个Maven工程不使用骨架。
  1. 创建实体类:
/**
 * 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方法
}
  1. 编写UserDao持久层接口,并编写查询所有的方法;使用@Select注解标注。
/**
 * User持久层接口
 * @author lyp
 */
public interface UserDao {

    /**
     * 查询所有用户信息
     * @return
     */
    @Select("select * from user")
    List<User> findAll();
}
  1. 编写数据库连接信息配置文件 jdbcConfig.properties文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
  1. 在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>
  1. 编写测试类进行测试 :

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

  1. 在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);
}
  1. 编写测试类进行测试 :
/**
* 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 实体类属性和数据库列的对应关系

  1. 新建一个项目使用 一对多的项目 。 修改实体类属性如下所示:
/**
 * 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方法
}
  1. 这里进行查询将会出现实体类属性名称和列名不对应,导致数据封装不进去的情况:
实体类属性名称和数据库列名不对应导致数据封装不进去
  1. 第一种方式:可以采用为数据库列名起别名的方式。第二种方式是使用@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 一对一 , 查询每个账户下的用户信息

  1. 编写账户实体类 :
    /**
 * 账户实体类
 */
public class Account implements Serializable {
    private Integer id;
    private Integer userId;
    private Double money;
    // setter 和 getter toString方法
}
  1. 编写Account账户持久层接口:
/**
 * @author lyp
 * Account 持久层接口
 */
public interface AccountDao {
    /**
     * 查询所有账户信息
     * @return
     */
    @Select("select * from account")
    List<Account> findAll();

}
  1. 在账户实体中配置一对一(其实是一对多,在Mybatis中一对多就代表一对一)关系映射:
/**
 * 账户实体类
 */
public class Account implements Serializable {
    private Integer id;
    private Integer userId;
    private Double money;
    private User user;
    // 省略setter 和getter方法 toString 方法
}
在Account实体中配置一对一关系映射
  1. 使用 @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. 在一对多查询多个的时候需要使用延迟加载

  2. 在一对一查询一的时候需要使用立即加载

1.5 一对多,查询每个用户下的多个用户信息

  1. 在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 方法
} 
  1. 配置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. 缓存配置 (二级缓存)

  1. 首先演示未使用缓存的情况:
 @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();
    }
  1. 未使用缓存的控制台打印如下 :
为使用缓存查询控制台的打印情况
  1. 配置缓存 : 首先在全局配置文件SqlMapConfig.xml配置文件下加上对二级缓存的支持。然后在持久层接口上加上注解@CacheNamespace(blocking = true)注解。
   <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
/**
 * User持久层接口
 * @author lyp
 * 在接口上开启对二级缓存的支持
 */
@CacheNamespace(blocking = true)
public interface UserDao {....}
  1. 配置二级缓存之后 :
配置二级缓存之后
上一篇 下一篇

猜你喜欢

热点阅读