Solon v3.0.3

十、数据访问、JDBC事务

</> markdown

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.添加 HikariCP 数据源配置(具体参考:《数据源的配置与构建》
solon.dataSources:
  db_order!: #数据源命名,且加类型注册(即默认)
    class: "com.zaxxer.hikari.HikariDataSource" #数据源类
    jdbcUrl: "jdbc:mysql://localdb:3306/rock?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true"
    driverClassName: "com.mysql.jdbc.Driver"
    username: "demo"
    password: "UL0hHlg0Ybq60xyb"

2、数据库操作框架集成

a.SqlUtils 集成

在 pom.xml 中引用 sqlutils 插件:

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-data-sqlutils</artifactId>
</dependency>

有了刚才的数据源配置后,直接就可以用了(不需要其它配置)。先以单数据源场景演示:

//使用示例
@Controller
public class DemoController{
    @Inject  
    SqlUtils sqlUtils;
    
    @Mapping("/user/")
    public UserModel geUser(long puid){
        return sqlUtils.sql("SELECT * FROM user WHERE puid=?", puid)
                       .queryRow()
                       .toBean(UserModel.class);
    }
}
b.Mybatis集成

在 pom.xml 中引用 mybatis 适配插件

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

使用 mybatis 时,还需要添加数据源相关的 mybatis mappers 及相关的属性配置

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

现在可以开始用了

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

3、使用事务注解

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

a.SqlUtils的事务
//使用示例
@Controller
public class DemoController{
    @Inject  
    SqlUtils sqlUtils;
    
    @Tran 
    @Mapping("/user/add")
    public Long addUser(UserModel user){
        return sqlUtils.sql("INSERT INTO user(puid,user_name) VALUES(?,?)", user.getPuid(), user.getUserName())
                       .updateReturnKey(); 
    }
}
b.Mybatis的事务
@Controller
public class DemoController{
    @Db  
    UserMapper userDao;  //UserMapper 已被 db_order mapperScan并已托管,也可用 @Inject 注入
    
    @Tran 
    @Mapping("/user/add")
    public Long addUser(UserModel user){
        return userDao.addUser(user); 
    }
}
c.混合多框架、多数据源的事务(这个时候,我们需要Service层参演)
@Component
public class UserService{
    @Inject("db_user")  //数据源1
    SqlUtils sqlUtils;
    
    @Tran 
    public Long addUser(UserModel user){
        return sqlUtils.sql("INSERT INTO user(puid,user_name) VALUES(?,?)", user.getPuid(), user.getUserName())
                       .updateReturnKey(); 
    }
}

@Component
public class AccountService{
    @Db("db_order")  //数据库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")
    public Long geUser(UserModel user){
        Long puid = userService.addUser(user);     //会执行 db_user 事务
        
        accountService.addAccount(user);    //会执行 db_order 事务
        
        return puid;
    }
}