• Solon Web 开发,五、数据访问、事务与缓存应用


    1、数据源的配置与构建(例:HikariCP DataSource)

    HiKariCP是数据库连接池的一个后起之秀,号称性能最好,可以完美地PK掉其他连接池。

    a.引入依赖
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>4.0.3</version>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>
    
    b.添加配置
    test.db1:
        schema: "rock"
        jdbcUrl: "jdbc:mysql://localdb:3306/rock?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true"
        driverClassName: "com.mysql.cj.jdbc.Driver"
        username: "demo"
        password: "UL0hHlg0Ybq60xyb"
        maxLifetime: 1000000
    
    c.配置HikariCP数据源

    建议这种操作,都安排在 @Configuration 配置类里执行。

    //注解模式
    //
    @Configuration
    public class Config{
        // 同时支持 name 和 类型 两种方式注入(注入时没有name,即为按类型注入)
        //
        @Bean(value = "db1", typed = true)   
        pubblic DataSource dataSource(@Inject("${test.db1}") HikariDataSource ds){
            return ds;
        }
    }
    
    //静态类模式(或纯手动模式)
    //
    //public class Config{
    //    pubblic static HikariDataSource dataSource = Solon.cfg().getBean("test.db1", HikariDataSource.class);
    //}
    

    之后就可以通过@Inject注解得到这个数据源了。一般会改用加强注解对数据源进行自动转换;所有与solon对接的ORM框架皆采用这种方案。

    2、数据库操作框架集成

    a.Weed3集成

    Wee3是一个轻巧的ORM框架,配置起来也简单。

    在pom.xml中引用weed3扩展组件

    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>weed3-solon-plugin</artifactId>
    </dependency>
    

    刚才的Config配置类即可复用。先以单数据源场景演示:

    //使用示例
    @Controller
    public class DemoController{
        //@Db 按类型注入  //或 @Db("db1") 按名字注入  
        //@Db是weed3在Solon里的扩展注解 //可以注入 Mapper, BaseMapper, DbContext
        //
        @Db  
        BaseMapper<UserModel> userDao;
        
        @Mapping("/user/")
        pubblic UserModel geUser(long puid){
            return userDao.selectById(puid);
        }
    }
    
    b.Mybatis集成

    在pom.xml中引用mybatis扩展组件

    <dependency>
        <groupId>org.noear</groupId>
        <artifactId>mybatis-solon-plugin</artifactId>
    </dependency>
    

    添加mybatis mappers及相关的属性配置

    mybatis.db1: #db1 要与数据源的bean name 对上
        typeAliases:    #支持包名 或 类名(.class 结尾)
            - "webapp.model"
        mappers:        #支持包名 或 类名(.class 结尾)或 xml(.xml结尾);配置的mappers 会 mapperScan并交由Ioc容器托管
            - "webapp.dso.mapper.UserMapper.class"
    

    刚才的Config配置类即也可复用

    //使用示例
    @Controller
    public class DemoController{
        //@Db 是  mybatis-solon-plugin 里的扩展注解,可注入 SqlSessionFactory,SqlSession,Mapper
        //
        @Db    
        UserMapper userDao;  //UserMapper 已被 db1 自动 mapperScan 并已托管,也可用 @Inject 注入
        
        @Mapping("/user/")
        pubblic UserModel geUser(long puid){
            return userDao.geUser(puid);
        }
    }
    

    3、使用事务注解

    Solon 中推荐使用@Tran注解来申明和管理事务。它适用于被动态代理的Bean,如:@Controller、 @Service、@Dao 注解的类;支持多数据源事务,使用方便。体验与Springboot的事务注解差不多。

    a.Weed3的事务
    //使用示例
    @Controller
    public class DemoController{
        @Db  //@Db("db1") 为多数据源模式
        BaseMapper<UserModel> userDao;
        
        @Tran 
        @Mapping("/user/add")
        pubblic Long addUser(UserModel user){
            return userDao.insert(user, true); 
        }
    }
    
    b.Mybatis的事务
    @Controller
    public class DemoController{
        @Db  
        UserMapper userDao;  //UserMapper 已被 db1 mapperScan并已托管,也可用 @Inject 注入
        
        @Tran 
        @Mapping("/user/add")
        pubblic Long addUser(UserModel user){
            return userDao.addUser(user); 
        }
    }
    
    c.混合多源事务(这个时候,我们需要Service层参演了)
    @Service
    public class UserService{
        @Db("db1")  //数据库1
        UserMapper userDao;  
        
        @Tran
        public void addUser(UserModel user){
            userDao.insert(user);
        }
    }
    
    @Service
    public class AccountService{
        @Db("db2")  //数据库2
        AccountMapper accountDao;  
        
        @Tran
        public void addAccount(UserModel user){
            accountDao.insert(user);
        }
    }
    
    @Controller
    public class DemoController{
        @Inject
        AccountService accountService; 
        
        @Inject
        UserService userService; 
        
        @Tran
        @Mapping("/user/add")
        pubblic Long geUser(UserModel user){
            Long puid = userService.addUser(user);     //会执行db1事务
            
            accountService.addAccount(user);    //会执行db2事务
            
            return puid;
        }
    }
    

    4、使用缓存注解

    构建缓存服务

    @Configuration
    public class DemoConfig{
        @Bean
        public CacheService cache(){
            //其实,默认已经有一个本地缓存服务存在了
            return new LocalCacheService();
        }
    }
    

    简单的缓存应用

    //比如,加在 Service 类上
    @Service
    public class AccountService{
        @Db("db2")  
        AccountMapper accountDao;  
        
        @Tran
        public void addAccount(UserModel user){
            accountDao.insert(user);
        }
        
        //当有缓存,则直接读取缓存;没有,则执行并缓存
        @Cache
        public UserModel getAccount(long userId){
            return accountDao.getById(userId);
        }
    }
    

    更详细的缓存使用,请参考后面的章节。

  • 相关阅读:
    ServletContext 类 EL表达式
    tomcat HttpServlet 的请求方式和域对象存储数据的两种方式
    最新的vue没有dev-server.js文件,如何进行后台数据模拟?
    小程序的全局变量 定义和使用
    vue 生命周期钩子函数
    slice方法可以将“类似数组的对象”变成真正的数组 (遇到时候再研究一次)
    JS中一个new到底做了哪些事情?
    关于JS中的call()方法和apply() 暂时只接触到call() 等接触到apply()再回头来看
    关于 prototype与__proto__ (用到的时候再看一次 加深理解)
    关于闭包最好最容易的理解 -- 很好很强大留作自用
  • 原文地址:https://www.cnblogs.com/noear/p/15820802.html
Copyright © 2020-2023  润新知