爬山的蜗牛旅程:七、springboot整合阿里Druid+SpringData Jpa+Spring JDBC+事务

学习springboot的旅程,就像蜗牛爬山,一点点的往上爬,一点点的欣赏旅途的风景

继续上一章的问题,小猿在遁入佛门前想起了数据库链接池没搞?数据持久层也没搞?

他想了想,先搞个阿里连接池先,然后选择 springdata 的 jpa模块 作为持久层实现。


Druid阿里连接池管理框架

  • 第一步:pom.xml 引入Druid和对应数据库驱动(我这里引入了oracle驱动)
		<!-- 引入druid依赖 -->
        <!-- 此处的引用有两种 -->
        <!-- 一种是直接引用druid包,另一种是引用starter方式 -->
        <!-- 在此处我引用的是start包,为什么呢,因为方便呀... -->
        <!--:如果没有该包,application.properties/application.yml 中将不会出现关于druid的提示 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!-- oracle驱动 -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.3</version>
            <scope>runtime</scope>
        </dependency>
  • 第二步:在application.properties(application.ymx)配置数据源和连接池信息
#####jdbc配置
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:ORCL
spring.datasource.username=hxz
spring.datasource.password=hxz
#这里是数据库驱动,以实际数据库为准
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

#连接池的设置
#初始化时建立物理连接的个数
spring.datasource.druid.initial-size=5
#最小连接池数量
spring.datasource.druid.min-idle=5
#最大连接池数量 maxIdle已经不再使用
spring.datasource.druid.max-active=20
#获取连接时最大等待时间,单位毫秒
spring.datasource.druid.max-wait=60000
#申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
spring.datasource.druid.test-while-idle=true
#既作为检测的间隔时间又作为testWhileIdel执行的依据
spring.datasource.druid.time-between-eviction-runs-millis=60000
#销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接
spring.datasource.druid.min-evictable-idle-time-millis=30000
#用来检测连接是否有效的sql 必须是一个查询语句
#mysql中为 select 'x'
#oracle中为 select 1 from dual
spring.datasource.druid.validation-query=select 1 from dual
#申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
spring.datasource.druid.test-on-borrow=false
#归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
spring.datasource.druid.test-on-return=false
#当数据库抛出不可恢复的异常时,抛弃该连接
#spring.datasource.druid.exception-sorter=true
#是否缓存preparedStatement,mysql5.5+建议开启 下面这个属性只有mysql有#spring.datasource.druid.pool-prepared-statements=true
#当值大于0时poolPreparedStatements会自动修改为true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
#配置扩展插件
spring.datasource.druid.filters=stat,wall
#通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
#合并多个DruidDataSource的监控数据
spring.datasource.druid.use-global-data-source-stat=true
#设置访问druid监控页的账号和密码,默认没有
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
  • 然后,就没然后了,已经配置好了,可以直接用了!

SpringData Jpa持久层

  • 第一步:pom.xml引入SpringData Jpa模块
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
  • 第二步:在application.properties(application.ymx)配置Jpa
#jpa设置
#指定数据库类型
spring.jpa.database=oracle
#控制台输出执行sql
spring.jpa.show-sql=true
#根据实体字段自动同步数据库表结构(直白说,根据实体创建数据库表)
spring.jpa.hibernate.ddl-auto=update
  • 到此Jpa的环境也搞好了。

简单的Jpa例子

  • 第一步:创建视图
import com.fasterxml.jackson.annotation.JsonFormat;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "AAAA")
public class User {
    @Id
    @GeneratedValue(generator = "faceset_generator")
    @GenericGenerator(name = "faceset_generator", strategy = "uuid")
    private String id;


    @Column(name="NAME",nullable = false ,length=1000)
    private String name;

    @Column(nullable = false)
    private String sex;

    @Column(nullable = false)
    private String age;

    @Column(nullable = false)
    private String address;

    @Column(nullable = false)
    private String remarks;

    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name="CREATETIME",nullable = false)
    private Date createtime;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getRemarks() {
        return remarks;
    }
    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }
    public Date getCreatetime() { return createtime; }
    public void setCreatetime(Date createtime) { this.createtime = createtime; }
}
  • 第二步:编写Jpa的接口(是接口,是接口,是接口,不是实现!!!!)
import com.example.hxzboot.Dome.Sys.User.Entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User,String> {
   //就是一个接口,什么实现都没有,你没看错!!就是这样!!!
}
  • 第三步:在业务层或者控制层注入,并使用增删查改
import com.example.hxzboot.Dome.Sys.User.Entity.User;
import com.example.hxzboot.Dome.Sys.Core.Service.impl.CoreServiceImpl;
import com.example.hxzboot.Dome.Sys.User.Service.UserRepository;
import com.example.hxzboot.Dome.Sys.User.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
@Service("userService")
@Transactional
public class UserServiceImpl {
    //----注意-----看下面的说明
    /**
    *  1-UserRepository userRepository 就是上面第二步的接口(没有实现)
    *  2-不用实现UserRepository接口,能直接使用增删查改
    *  3-不用实现UserRepository接口,因为注入的UserRepository是由Jpa来实现
    **/
    @Autowired
    private UserRepository userRepository;

    @Override
    public List<User> findAll() {
        return userRepository.findAll();
    }
    @Override
    public User save(User user) {
        return userRepository.save(user);
    }
    @Override
    public User findById(String id) {
        return userRepository.findById(id).get();
    }
    @Override
    public void deleteById(String id) {
        userRepository.deleteById(id);
    }
}

springboot+JdbcTemplate+Jpa整合(实现既可以JDBC、又可以ORM)

  • 说明一下:springboot本身就已经实现对JdbcTemplate的支持
    • 只要配置数据源,就可以注入JdbcTemplate使用
    • 数据源配置请看:阿里连接池的第二步配置
  • 第一步:编写JDBC通用接口及实现(通用的),实现一次就够了!!!
import java.util.List;
import java.util.Map;
public interface CoreService {
    public List<Map<String,Object>> queryForList(String sql, Object ...obj);
    public void execute(String sql);
    public int update(String sql,Object ...obj);
    public int[] batchUpdate(String sql);
    public int[] batchUpdate(String sql,List<Object[]> lsobj);
}
import com.example.hxzboot.Dome.Sys.Core.Service.CoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service("coreService")
@Transactional
public class CoreServiceImpl implements CoreService {
    @Autowired
    protected JdbcTemplate jdbcTemplate;
    @Override
    public List<Map<String, Object>> queryForList(String sql, Object... obj) {
        return jdbcTemplate.queryForList(sql,obj);
    }
    @Override
    public void execute(String sql) {
        jdbcTemplate.execute(sql);
    }
    @Override
    public int update(String sql, Object... obj) {
        return jdbcTemplate.update(sql,obj);
    }
    @Override
    public int[] batchUpdate(String sql) {
        return jdbcTemplate.batchUpdate(sql);
    }
    @Override
    public int[] batchUpdate(String sql, List<Object[]> lsobj) {
        return jdbcTemplate.batchUpdate(sql, lsobj);
    }
}
  • 第二步:编写两个业务接口(jpa和jdbc),比如user
import com.example.hxzboot.Dome.Sys.User.Entity.User;
import com.example.hxzboot.Dome.Sys.Core.Service.CoreService;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* JDBC业务接口,必须继承JDBC通用接口CoreService 
* 注意:所有持久层方法,都在这定义,不用在Jpa业务接口上定义
*/
public interface UserService extends CoreService {
    public Page<User> findAllByProperty(User user, ExampleMatcher matcher,Pageable pageable);
    public List<User> findAllByProperty(User user, ExampleMatcher matcher);
    public Page<User> findAll(Pageable pageable);
    public List<User> findAll();
    public User save(User user) ;
    public User findById(String id);
    public void deleteById(String id);
}
import com.example.hxzboot.Dome.Sys.User.Entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Jpa的接口,啥都不用实现!!!
* 注意:持久层方法不在此定义!!在JDBC业务接口上定义
*/
@Repository
public interface UserRepository extends JpaRepository<User,String> {
}
  • 第三步:业务层实现(此处是业务实现,必须加事务
import com.example.hxzboot.Dome.Sys.User.Entity.User;
import com.example.hxzboot.Dome.Sys.Core.Service.impl.CoreServiceImpl;
import com.example.hxzboot.Dome.Sys.User.Service.UserRepository;
import com.example.hxzboot.Dome.Sys.User.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@Service("userService")
@Transactional//增加事务
public class UserServiceImpl extends CoreServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public List<User> findAllByProperty(User user, ExampleMatcher matcher) {
        Example<User> example;
        if(null==matcher){
            example = Example.of(user);
        }else{
            example = Example.of(user,matcher);
        }
        return userRepository.findAll(example);
    }

    @Override
    public Page<User> findAllByProperty(User user, ExampleMatcher matcher,Pageable pageable) {
        Example<User> example;
        if(null==matcher){
            example = Example.of(user);
        }else{
            example = Example.of(user,matcher);
        }
        return userRepository.findAll(example,pageable);
    }
    
    @Override
    public List<User> findAll() {
        return userRepository.findAll();
    }
    
    @Override
    public User save(User user) {
        return userRepository.save(user);
    }

    @Override
    public User findById(String id) {
        return userRepository.findById(id).get();
    }

    @Override
    public void deleteById(String id) {
        userRepository.deleteById(id);
    }

    @Override
    public Page<User> findAll(Pageable pageable) {
        return userRepository.findAll(pageable);
    }
}
  • 第四步:在controller使用
import com.alibaba.fastjson.JSONObject;
import com.example.hxzboot.Dome.Sys.User.Entity.User;
import com.example.hxzboot.Dome.Sys.User.Service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags="用户管理")
@RestController
@RequestMapping("/restuser")
public class RestUserController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserService userService;

    @ApiOperation(value = "获取用户数据列表", notes = "获取所有用户数据列表")
    @RequestMapping(value = "/alluser" , method = {RequestMethod.GET,RequestMethod.POST})
    public List<User> usersList(){
        List<Map<String,Object>> ls=this.userService.queryForList("select * from aaaa");
        return userService.findAll();
    }

    /**
     * 获取列表数据
     * @return
     */
    @RequestMapping(value = "/query",method = {RequestMethod.POST,RequestMethod.GET})
    public String query(HttpServletRequest request,User user){
        Map<String,Object>   map=new HashMap<String,Object>();

        //获取当前页数
        String  pageNumber=  request.getParameter("pageNumber");
        int page=1;
        if(!StringUtils.isEmpty(pageNumber)){
            page=Integer.valueOf(pageNumber);
        }

        //设置查询条件
        User u=new User();
        if(user.getName()!=null&&user.getName()!=""){
            u.setName(user.getName());
        }
        if(user.getSex()!=null&&user.getSex()!=""){
            u.setSex(user.getSex());
        }
        if(user.getAge()!=null&&user.getAge()!=""){
            u.setAge(user.getAge());
        }
        if(user.getAddress()!=null&&user.getAddress()!=""){
            u.setAddress(user.getAddress());
        }
        if(user.getRemarks()!=null&&user.getRemarks()!=""){
            u.setRemarks(user.getRemarks());
        }

        //设置查询条件
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查询,即%{name}%
                .withMatcher("sex" ,ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查询,即%{name}%
                .withMatcher("age" ,ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查询,即%{name}%
                .withMatcher("address" ,ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查询,即%{name}%
                .withMatcher("remarks" ,ExampleMatcher.GenericPropertyMatchers.contains());//全部模糊查询,即%{name}%

        //查询总条数
        List<User> users = userService.findAllByProperty(u,matcher);
        int sum=users.size()/10;
        if(users.size()%10>0){
            sum=++sum;
        }
        map.put("sum",sum);

        //在总数据里提取分页数据
        List<User> datas=new ArrayList<User>();
        for(int i=(page-1)*10;i<users.size()&&i<((page-1)*10+10);i++){
            datas.add(users.get(i));
        }
        
        map.put("list",datas);
        return JSONObject.toJSONString(map);
    }

    @ApiOperation(value = "更新用户", notes = "更新用户数据")
    @RequestMapping(value = "/updateuser" ,  method = RequestMethod.POST)
    public Map<String,Object> updateUser(User user)throws Exception{
        Map<String,Object> map=new HashMap<String,Object>();
        if(userService.save(user) != null){
            map.put("msg","更新成功");
            map.put("state","200");
            map.put("user",user);
        }else{
            map.put("msg","更新失败");
            map.put("state","500");
        }
        return map;
    }

    @ApiOperation(value = "获取用户", notes = "根据用户id获取用户")
    @RequestMapping(value="/getuserbyid",method = RequestMethod.POST)
    public User selectUserById(String id){
        return userService.findById(id);
    }

    @ApiOperation(value = "删除用户", notes = "根据用户id删除用户")
    @RequestMapping(value="/deleteuser",method = RequestMethod.POST)
    public Map<String,Object> deleteUser(String id){
        userService.deleteById(id);
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("msg","删除成功");
        map.put("state","200");
        return map;
    }

    @ApiOperation(value = "保存用户", notes = "保存用户数据")
    @RequestMapping(value="/saveuser",method = {RequestMethod.POST,RequestMethod.GET})
    public Map<String,Object> saveUser(User user)throws Exception{
        Map<String,Object> map=new HashMap<String,Object>();
        if(userService.save(user) != null&&user.getId()!=null){
            map.put("msg","新增成功");
            map.put("state","200");
            map.put("user",user);
        }else{
            map.put("msg","新增失败");
            map.put("state","500");
        }
        return map;
    }
}
  • 自此全部搞定。如果你不想千篇一律的写不用实现Jpa和JDBC的业务接口,你可以编写成代码模板,根据代码模板生成代码!这一块我就不说了!

现在小猿同学终于可以安心去出家了!!!就在小猿同学准备再次出家的时候,口袋的手机响了!!经理打电话来说:“小猿啊,系统的菜单加载好慢啊,你给想想办法给搞搞啊!!”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值