6、Spring Data JPA 之 单表的CRUD操作

实体类

/**
 * 1.实体类和表的映射关系
 *      @Entity
 *      @Table
 * 2.类中属性和表中字段的映射关系
 *      @Id
 *      @GeneratedValue
 *      @Column
 */
@Entity
@Table(name="users")
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Integer userId;
    @Column(name = "user_name")
    private String userName;
    @Column(name = "gender")
    private String gender;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Users{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

接口

/**
 * 符合Spring Data Jpa 的 dao层接口规范
 *      JpaRepository<操作的实体类类型,实体类中主键属性的类型>
 *          #封装了基本CRUD操作
 *      JpaSpecificationExecutor <操作的实体类类型>
 *          #封装了复杂查询(分页)
 */
public interface UsersDao extends JpaRepository<Users, Integer>,JpaSpecificationExecutor<Users>{
}

单表的基础CRUD操作

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
public class UsersDaoTest {
    @Autowired
    private UsersDao usersDao;

    /**
     * 根据id查询(立即加载)
     */
    @Test
    public void testFindOne(){
        Users user = usersDao.findOne(1);
        System.out.println(user);
    }

    /**
     * save:保存或更新
     *      根据传递的对象是否存在主键id,
     *      如果没有id主键属性,保存
     *      存在id主键属性,根据id查询数据,更新数据
     *          (SpringDataJPA内部会根据id查询是否存在该数据,有才更新)
     */
    @Test
    public void testSave(){
        Users users = new Users();
        users.setUserName("小陈");

        usersDao.save(users);
    }

    /**
     * 如果直接更新某条数据的某个字段这其他没有改的字段会变成null
     * 所以执行更新时,先查询再更新
     */
    @Test
    public void testUpdate(){
        Users users = new Users();
        users.setUserId(4);
        users.setUserName("小张");

        usersDao.save(users);
    }
    /**
     * 删除
     */
    @Test
    public void testDelete(){
        usersDao.delete(3);
    }

    /**
     * 查询所有
     */
    @Test
    public void testFindAll(){
        List<Users> list = usersDao.findAll();
        for (Users users: list
             ) {
            System.out.println(users);
        }
    }

    /**
     *  使用count函数进行查询
     */
    @Test
    public void testCount(){
        long count = usersDao.count(); //查询全部的客户数量
        System.out.println(count);
    }

    /**
     * 判断id为4的用户是否存在
     *      1.可以查询以下id为4的客户
     *          如果值为空,代表不存在,如果不为空,则存在
     *      2.判断数据库中id为4的客户的数量
     *          如果数量为0,表示不存在,大于0则存在
     */
    @Test
    public void testExists(){
        boolean isExists = usersDao.exists(4);
        System.out.println(isExists);
    }

    /**
     *  根据id从数据库查询
     *      @Transactional: 保证getOne正常运行
     *  findOne:
     *      em.find()       立即加载
     *  getOne:
     *      em.getReference     延迟加载
     *      返回的是一个客户的动态代理对象
     *      什么时候用,什么时候查询
     */
    @Test
    @Transactional
    public void testGetOne(){
        Users user = usersDao.getOne(4);
        System.out.println(user);
    }
}

单表的JPQL查询

JPQL方法需要自己在接口上定义抽象方法

------- 抽象方法
/**
 * 根据用户名查询用户
 *      使用jpql语句,使用@Query注解
 *      select * from user where user_name = ?
 * @param username
 * @return
 */
@Query(value = "from com.example.pojo.Users where userName = ?")
List<Users> findUsersByUsername(String username);

------ 测试
/**
 * 通过用户名查询用户
 */
@Test
public void testGetUserByName(){
    List<Users> list = usersDao.findUsersByUsername("小白");
    System.out.println(list);
}
--------------- 抽象方法
/**
 * 根据用户名称和用户id查询用户
 *      select from users where usrename = ? and userId = ?
 *
 *  对于多个占位符参数
 *      赋值时,默认情况下,占位符的位置需要和方法参数总的位置保持一致
 */
@Query("from com.example.pojo.Users where userName=? and userId=?")
Users findUsersByUserNameAndUserId(String Name, Integer id);

-------------- 测试
/**
 * 多占位符的赋值
 */
@Test
public void testGetUserByNameAndUserId(){
    Users user = usersDao.findUsersByUserNameAndUserId("小白", 2);
    System.out.println(user);
}
---------- 抽象方法
/**
 *  如果占位符取值与参数顺序不符时,需要在占位符后添加取值位置
 * @param Name
 * @param id
 * @return
 */
@Query("from com.example.pojo.Users where userName=?2 and userId=?1")
Users findUsersByUserNameAndUserId2(Integer id, String Name);

----------测试
/**
 * 多占位符的赋值
 */
@Test
public void testGetUserByNameAndUserId2(){
    Users user = usersDao.findUsersByUserNameAndUserId2(2,"小白");
    System.out.println(user);
}
---------- 抽象方法
/**
 * 使用JPQL完成更新操作
 *  根据id更新用户的名称
 *      update users set user_name = ? where user_id = ?
 *  @Modifying
 *      当前执行的是一个更新操作
 */
@Query("update com.example.pojo.Users set userName = ? where userId = ?")
@Modifying
void updateUsernameByUserId(String name, Integer id);

---------- 测试
/**
 * 使用JPQL完成更新操作
 *      springDataJpa中使用jpql完成更新、删除操作
 *             需要手动添加书屋的支持
 *             默认会执行结束之后,回滚事务
 *      @Rollback 设置是否自动回滚(如果@Transactional注解标注在接口方法上,则不需要配置@Rollback注解)
 */
@Test
@Transactional
@Rollback(value = false)
public void  testUpdateCustomer(){
    usersDao.updateUsernameByUserId("小陈",2);
}

SQL语句查询

Spring Data JPA 同样支持原生sql的CRUD操作,方法由自己定义在到接口中

----------- 抽象方法
/**
 * 使用sql的形式查询
 *  查询全部的用户 select * from users
 *  nativeQuery = true就是该查询为sql查询
 */
@Query(value = "select * from users", nativeQuery = true)
List<Object []> sqlQueryFindAllUsers();

------------ 测试
 /**
  * sql语句查询所有
  */
 @Test
 public void testSqlQueryFindAllUsers(){
     List<Object[]> list = usersDao.sqlQueryFindAllUsers();

     for (Object[] obj: list
          ) {
         System.out.println(Arrays.toString(obj));
     }
 }
------------ 抽象方法
/**
  * 模糊查询
  * 使用sql的形式查询
  *  查询全部的用户 select * from users
  *  nativeQuery = true就是该查询为sql查询
  */
 @Query(value = "SELECT * FROM users WHERE user_name LIKE ?", nativeQuery = true)
 List<Object []> sqlQueryFindUsers(String name);

------------ 测试
 /**
   * sql语句模糊查询
   */
  @Test
  public void testSqlQueryFindUsers(){
      List<Object[]> list = usersDao.sqlQueryFindUsers("%小%");
      for (Object[] obj : list
              ) {
          System.out.println(Arrays.toString(obj));
      }
  }

方法名称规则查询

同样需要在接口中定义该方法

提示

/**
 * 方法名称规则查询
 *      是对jpql查询,更加深入的一层封装,我们只需要按照SpringDataJpa提供的方法名称
 *      规则定义方法,不需要再去配置jpql语句,完成查询
 *  SpringDataJpa 的运行阶段会根据方法名称进行解析,
 *      findBy + 实体类属性名称(条件查询)
 *      findBy + 实体类属性名称 + 查询方式(like,is null,between等)
 *      findBy + 实体类属性名 + 查询方式 + 多条件连接符(and|or) +  实体类属性 + 查询方式
 *              模糊匹配需要写查询方式,精准匹配可以不写
 */
------------- 抽象方法
/**
 * 方法名称规则查询
 *      find 查询
 *          对象中的属性名称(首字母大写)作为查询条件
 *      如:findByUserName  以userName属性为查询条件,进行条件查询
 * 注意:方法名称规则查询不需要添加@Query注解
 */
 Users findByUserName(String name);

------------- 测试
/**
 *  条件查询
 *  用户名作为条件进行查询
 */
@Test
public void testFindByUserName(){
    Users user = usersDao.findByUserName("小黑");
    System.out.println(user);
}
------------ 抽象方法
/**
 * 模糊查询
 * 对用户名进行模糊查询
 * @return
 */
List<Users> findByUserNameLike(String name);

----------- 测试
/**
 *  模糊查询
 *  通过用户名进行模糊查询
 */
@Test
public void testFindByUserNameLike(){
    List<Users> list = usersDao.findByUserNameLike("小%");
    for (Users user : list
            ) {
        System.out.println(user);
    }
}
------------ 抽象方法
/**
 *  多条件查询
 *  用户姓名模糊查询和id精准配置
 *  userName是模糊查询必须写上查询方式(like)
 *  userId是精准匹配不写写查询方式
 */
Users findByUserNameLikeAndUserId(String name, Integer id);

------------- 测试
@Test
public void testFindByUserNameLikeAndUserId(){
    Users user = usersDao.findByUserNameLikeAndUserId("小%", 1);
    System.out.println(user);
}
posted @ 2020-08-18 08:40  lawrence林  阅读(216)  评论(0编辑  收藏  举报