Spring Boot 企业级实战程序员Java学习笔记

Spring Boot JAP + MySQL实战

2017-12-31  本文已影响103人  固安李庆海

可参考使用STS创建Spring Boot 项目创建一个新的Spring Boot 项目,创建项目时选择Web、JPA和MySQL等选项。

application.yml中的配置信息

spring:
  datasource:
    url: jdbc:mysql://192.168.10.58:3306/jianshu?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
    username: root
    password: infcn123
    platform: mysql
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    database: mysql
    show-sql: true
    
  http:
    encoding:
      force: true
      charset: UTF-8
      enabled: true
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    joda-date-time-format: yyyy-MM-dd HH:mm:ss
    time-zone:
      GMT+8
    serialization:
      fail-on-empty-beans: false
security:
  basic:
    enabled: false
server:
  tomcat:
    uri-encoding: UTF-8
  port: 8080

实体Bean配置

用户配置

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.Size;
import org.springframework.data.annotation.CreatedDate;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * 系统用户
 * 
 * @author 李庆海
 */
@Data
@Accessors(chain = true)
@Entity
@Table(name = "SYS_USER")
public class User implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
    /***/
    @Id
    @Column(name = "ID", unique = true, nullable = false, length = 32)
    private String id;

    /** 登录账号 */
    @Column(name = "LOGIN_NAME", nullable = false, length = 50)
    @Size(max = 50)
    private String loginName;

    /** 用户名称 */
    @Column(name = "USER_NAME", nullable = true, length = 50)
    private String userName;

    /** 登录密码 */
    @Column(name = "PASSWORD", nullable = false, length = 32)
    @JsonIgnore
    private String password;

    /** 注册日期 */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATE_DATE", nullable = false)
    @CreatedDate
    private Date registDate;

    /** 用户状态 */
    @Column(name = "ENABLED", nullable = false, length = 1)
    private Integer enabled;

    /**
     * 用户的角色
     */
    @ManyToOne(cascade = {}, fetch = FetchType.EAGER)
    @JoinColumn(name = "ROLE_ID")
    private Role role;

}

角色配置

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * 系统角色
 * 
 * @author 李庆海
 *
 */
@Data
@Accessors(chain = true)
@Entity
@Table(name = "SYS_ROLE")
public class Role implements Serializable {
    private static final long serialVersionUID = -2139369027015540299L;

    /** 主键 */
    @Id
    @Column(name = "ID", unique = true, length = 32, nullable = false)
    private String id;

    /** 角色描述 */
    @Column(name = "DES", length = 255, nullable = false)
    private String des;

    /** 角色名称 */
    @Column(name = "TITLE", length = 20, nullable = true)
    private String title;

    /** 角色排序 */
    @Column(name = "SORTER", length = 3, nullable = false)
    private Integer sorter;

}

基于JPA接口的简单应用

JpaRepository实现了PagingAndSortingRepository接口,PagingAndSortingRepository接口实现了CrudRepository接口,CrudRepository接口实现了Repository接口。save方法既可以新增又可以更新,只是在更新一个数据库中不存在的对象时会添加一个指定id的实例对象。findBy系列只能实现简单的、固定参数的查询,对于动态查询无能为力。

继承JpaRepository的RoleRepository 角色接口

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import cn.com.infcn.jianshu.model.Role;
/**
 * 系统角色数据访问类
 * @author 李庆海
 *
 */
public interface RoleRepository extends JpaRepository<Role, String> {
    @Query("select max(t.sorter) from Role t")
    Integer getMaxSorter();
}

RoleService服务类

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.com.infcn.jianshu.dao.RoleRepository;
import cn.com.infcn.jianshu.model.Role;
import cn.com.infcn.jianshu.util.StringUtil;

/**
 * 系统角色Service类
 * 
 * @author 李庆海
 *
 */
@Service
public class RoleService {
    @Autowired
    private RoleRepository roleRepository;

    /**
     * 创建角色
     * SORTER字段是获取数据库最大的sorter字段加1
     * @param title 角色名称
     * @param des 角色描述
     * @return Role
     */
    @Transactional
    public Role create(String title,String des) {
        Integer sorter = roleRepository.getMaxSorter();
        if(null==sorter){
            sorter=0;
        }
        Role model =new Role()
            .setId(StringUtil.generateUUID())
            .setTitle(title)
            .setDes(des)
            .setSorter(sorter+1);
        return this.roleRepository.save(model);
    }

    /**
     * 删除角色
     * 
     * @param id  角色主键
     */
    @Transactional
    public void delete(String id) {
        this.roleRepository.delete(id);
    }

    /**
     * 根据主键获取Model
     * 
     * @param id  角色主键
     * @return Role
     */
    public Role read(String id) {
        return this.roleRepository.findOne(id);
    }

    /**
     * 判断是否存在同名的角色
     * 
     * @param name
     *            名称
     * @return true 或 false
     */
    public boolean exists(String name) {
        ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("title", GenericPropertyMatchers.exact());
        Example<Role> ex = Example.of(new Role().setTitle(name), matcher);
        return this.roleRepository.exists(ex);
    }

    /**
     * 查询所有角色
     * 
     * @return
     */
    public List<Role> findRoles() {
        return this.roleRepository.findAll();
    }
}

多表多条件动态组合查询

要想实现多表多条件动态组合查询还需要多继承一个接口JpaSpecificationExecutor。

继承JpaRepository和JpaSpecificationExecutor的UserRepository 用户接口

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import cn.com.infcn.jianshu.model.User;

/**
 * 系统用户数据访问类
 * @author 李庆海
 *
 */
public interface UserRepository extends JpaRepository<User, String>,JpaSpecificationExecutor<User> {
    /**
     * 根据登录账号和登录密码查询用户
     * @param loginName 登录账号
     * @param password 登录密码
     * @return User
     */
    @Query("from User t where t.loginName=:loginName and t.password=:password and t.enabled=1")
    public User findUser(@Param(value = "loginName") String loginName, @Param(value = "password") String password);

    /**
     * 根据登录账号查询用户信息
     * @param loginName 登录账号
     * @return User
     */
    @Query("from User t where t.loginName=:loginName")
    public User findUserByLoginName(@Param(value = "loginName")String loginName);

    /**
     * 重置密码
     * @param id 用户编号
     * @param password 新密码
     */
    @Modifying
    @Query("update User u set u.password=:password where u.id=:id")
    public void updatePassword(@Param(value = "id") String id, @Param(value = "password") String password);

    
    /**
     * 更新系统用户的状态
     * @param id 用户编号
     * @param enabled 用户状态
     */
    @Modifying
    @Query("update User u set u.enabled=:enabled where u.id=:id")
    public void updateEnabled(@Param(value = "id") String id, @Param(value = "enabled") int enabled);
}

UserService服务类

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.com.infcn.jianshu.dao.UserRepository;
import cn.com.infcn.jianshu.model.Role;
import cn.com.infcn.jianshu.model.User;
import cn.com.infcn.jianshu.util.StringUtil;

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    /**
     * 添加用户,注册
     * 
     * @param loginName
     *            登录账号
     * @param password
     *            登录密码
     * @param userName
     *            用户名称
     * @param roleId
     *            用户角色
     * @return
     */
    @Transactional
    public User create(String loginName, String password, String userName,String roleId) {
        User user = new User()
            .setLoginName(loginName)
            .setUserName(userName)
            .setPassword(password)
            .setRegistDate(new Date())
            .setEnabled(1)
            .setRole(new Role().setId(roleId))
            .setId(StringUtil.generateUUID());
        return this.userRepository.saveAndFlush(user);
    }

    /**
     * 根据登录账号和密码查询用户
     * 
     * @param loginName
     *            登录账号
     * @param password
     *            登录密码
     * @return
     */
    public User login(String loginName, String password) {
        return this.userRepository.findUser(loginName, password);
    }

    /**
     * 根据登录账号查询用户信息
     * 
     * @param loginName
     *            登录账号
     * @return
     */
    public User getUser(String loginName) {
        return this.userRepository.findUserByLoginName(loginName);
    }

    /**
     * 重置密码
     * 
     * @param id
     *            用户编号
     * @param password
     *            新密码
     */
    @Transactional
    public void updatePassword(String id, String password) {
        this.userRepository.updatePassword(id, password);
    }

    /**
     * 注销用户,不是删除
     * 
     * @param id
     *            用户编号
     */
    @Transactional
    public void cancel(String id) {
        this.userRepository.updateEnabled(id, 0);
    }

    /**
     * 判断登录账号是否已经存在,登录账号唯一
     * 
     * @param loginName
     *            登录账号
     * @return
     */
    public boolean exists(String loginName) {
        ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("loginName", GenericPropertyMatchers.exact());
        Example<User> ex = Example.of(new User().setLoginName(loginName), matcher);
        return this.userRepository.exists(ex);
    }

    /**
     * 根据主键获取用户信息
     * 
     * @param id
     *            用户编号
     * @return
     */
    public User getOne(String id) {
        return this.userRepository.getOne(id);
    }

    /**
     * 多条件查询用户
     * 
     * @param userName
     *            用户名称
     * @param roleId
     *            用户角色编号
     * @param start
     *            注册开始日期
     * @param end
     *            注册结束日期
     * @param page
     *            分页,从0开始
     * @param size
     *            每页的行数
     * @return
     */
    public Page<User> findDatas(String userName, String roleId, Date start, Date end, int page, int size) {
        Pageable pr = new PageRequest(page, size, new Sort(Direction.DESC, "registDate"));
        return this.userRepository.findAll(new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery,
                    CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                // root.get("xx属性")表示获取xx属性这个字段名称,like表示执行like查询,%zt%表示值
                if (null != userName) {
                    Predicate p = criteriaBuilder.like(root.get("userName"), "%" + userName + "%");
                    list.add(p);
                }
                if (null != roleId) {
                    //关联查询,User关联Role
                    Predicate p = criteriaBuilder.equal(root.join("role", JoinType.INNER).get("id"), roleId);
                    list.add(p);
                }
                if (null != start) {
                    Predicate p = criteriaBuilder.greaterThanOrEqualTo(root.get("registDate"), start);
                    list.add(p);
                }
                if (null != end) {
                    Predicate p = criteriaBuilder.lessThanOrEqualTo(root.get("registDate"), end);
                    list.add(p);
                }

                Predicate[] ps = new Predicate[list.size()];
                // 将查询条件联合起来之后返回Predicate对象
                return criteriaBuilder.and(list.toArray(ps));
            }
        }, pr);
    }
}
上一篇下一篇

猜你喜欢

热点阅读