一. Mango事务
mango支持编程式事务和使用TransactionTemplate进行事务;
编程式事务:
Transaction tx = TransactionFactory.newTransaction();
try {
//业务处理,比如下面的转账操作
dao.transferMoney(zhangsan, -money);
dao.transferMoney(lisi, money);
} catch (Throwable e) {
tx.rollback(); //事务回滚
return;
}
tx.commit(); //事务提交实例代码:
package com.lhf.mango.transaction;
import com.lhf.mango.dao.AccountDao;
import com.lhf.mango.entity.Account;
import org.jfaster.mango.datasource.DriverManagerDataSource;
import org.jfaster.mango.operator.Mango;
import org.jfaster.mango.transaction.Transaction;
import org.jfaster.mango.transaction.TransactionFactory;
import org.jfaster.mango.util.logging.MangoLogger;
import javax.sql.DataSource;
/**
* @ClassName: AccountMain1
* @Desc: 编程式事务
* @Author: liuhefei
* @Date: 2018/12/24 9:28
*/
public class AccountMain1 {
public static void main(String[] args){
MangoLogger.useLog4J2Logger(); // 使用log4j2输出日志,log4j2.xml文件在resources目录下
//定义数据源
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mango_example?useSSL=false";
String username = "root";
String passowrd = "root";
DataSource ds = new DriverManagerDataSource(driverClassName,url, username, passowrd);
Mango mango = Mango.newInstance(ds); //使用数据源初始化mango
AccountDao accountDao = mango.create(AccountDao.class);
Account account1 = new Account();
Account account2 = new Account();
account1.setUid(3);
account1.setName("小花");
account1.setMoney(1500);
accountDao.addAccount(account1);
account2.setUid(4);
account2.setName("小美");
account2.setMoney(1500);
accountDao.addAccount(account2);
//转账前
System.out.println("转账前:");
System.out.println(accountDao.getAccount(1).toString());
System.out.println(accountDao.getAccount(2).toString());
//开启事务
Transaction tx = TransactionFactory.newTransaction();
int money = 1500;
try{
accountDao.transferMoney(1, -money);
accountDao.transferMoney(2, money);
}catch (Throwable e){
tx.rollback(); //回滚
return;
}
tx.commit(); //提交事务
//转账后
System.out.println("转账后:");
System.out.println(accountDao.getAccount(1).toString());
System.out.println(accountDao.getAccount(2).toString());
}
}使用TransactionTemplate:
TransactionTemplate.execute(new TransactionAction() {
@Override
public void doInTransaction(TransactionStatus status) {
//业务处理,比如下面的转账操作
dao.transferMoney(zhangsan, -money);
dao.transferMoney(lisi, money);
}
});实例代码:
package com.lhf.mango.transaction;
import com.lhf.mango.dao.AccountDao;
import org.jfaster.mango.datasource.DriverManagerDataSource;
import org.jfaster.mango.operator.Mango;
import org.jfaster.mango.transaction.TransactionAction;
import org.jfaster.mango.transaction.TransactionStatus;
import org.jfaster.mango.transaction.TransactionTemplate;
import org.jfaster.mango.util.logging.MangoLogger;
import javax.sql.DataSource;
/**
* @ClassName: AccountMain2
* @Desc: 使用Mango的TransactionTemplate 进行事务控制
* @Author: liuhefei
* @Date: 2018/12/24 9:28
*/
public class AccountMain2 {
public static void main(String[] args){
MangoLogger.useLog4J2Logger(); // 使用log4j2输出日志,log4j2.xml文件在resources目录下
//定义数据源
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mango_example?useSSL=false";
String username = "root";
String passowrd = "root";
DataSource ds = new DriverManagerDataSource(driverClassName,url, username, passowrd);
Mango mango = Mango.newInstance(ds); //使用数据源初始化mango
final AccountDao accountDao = mango.create(AccountDao.class);
//转账前
System.out.println("转账前:");
System.out.println(accountDao.getAccount(3).toString());
System.out.println(accountDao.getAccount(4).toString());
final int money = 1000;
if(accountDao.getAccount(3).getMoney() > money){
TransactionTemplate.execute(new TransactionAction() {
public void doInTransaction(TransactionStatus transactionStatus) {
accountDao.transferMoney(3, -money); //减去
accountDao.transferMoney(4, money); //加上
}
});
}else{
System.out.println("余额不足,转账失败");
}
//转账后
System.out.println("转账后:");
System.out.println(accountDao.getAccount(3).toString());
System.out.println(accountDao.getAccount(4).toString());
}
}二. Mango日志
mango框架拥有强大的日志处理功能,能通过下面任意一个“日志工具”输出日志(能查看执行的SQL与参数):
Slf4J
Log4J2
Log4J
Console(控制台,也就是通过System.out输出)
(1)使用Slf4J输出日志:
准备配置文件
logback.xml 配置文件如下,需要注意的是logger的name为org.jfaster.mango,level为debug。
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.jfaster.mango" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<root level="error">
<appender-ref ref="STDOUT" />
</root>
</configuration>Main方法运行程序:
有了前面的配置文件,当我们直接使用Main方法运行程序时,只需将下面的代码放到Main方法的最前面,即可让mango框架使用Slf4J输出日志信息。
MangoLogger.useSlf4JLogger();
上面的代码中MangoLogger的类全名为org.jfaster.mango.util.logging.MangoLogger
WEB容器运行程序:
很多时候我们并不直接通过Main方法运行自己的程序,而是使用tomcat,jetty等WEB容器。这时我们只需将下面的“监听器”拷配到web.xml文件的最前面,即可让mango框架使用Slf4J输出日志信息。
<listener> <listener-class>org.jfaster.mango.plugin.listener.Slf4JLoggerListener</listener-class> </listener>
(2)使用Log4J2输出日志:
准备配置文件
log4j2.xml 配置文件如下,需要注意的是Logger的name为org.jfaster.mango,level为debug。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.jfaster.mango" level="debug" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>Main方法运行程序:
有了前面的配置文件,当我们直接使用Main方法运行程序时,只需将下面的代码放到Main方法的最前面,即可让mango框架使用Log4J2输出日志信息。
MangoLogger.useLog4J2Logger();
上面的代码中MangoLogger的类全名为org.jfaster.mango.util.logging.MangoLogger
WEB容器运行程序:
很多时候我们并不直接通过Main方法运行自己的程序,而是使用tomcat,jetty等WEB容器。这时我们只需将下面的“监听器”拷配到web.xml文件的最前面,即可让mango框架使用Log4J2输出日志信息。
<listener> <listener-class>org.jfaster.mango.plugin.listener.Log4J2LoggerListener</listener-class> </listener>
(3)使用Log4J输出日志:
准备配置文件
log4j.xml 配置文件如下,需要注意的是logger的name为org.jfaster.mango,level为debug。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n" />
</layout>
</appender>
<logger name="org.jfaster.mango" additivity="false">
<level value="debug" />
<appender-ref ref="console" />
</logger>
<root>
<level value="info" />
<appender-ref ref="console"/>
</root>
</log4j:configuration>Main方法运行程序:
有了前面的配置文件,当我们直接使用Main方法运行程序时,只需将下面的代码放到Main方法的最前面,即可让mango框架使用Log4J输出日志信息。
MangoLogger.useLog4JLogger();
上面的代码中MangoLogger的类全名为org.jfaster.mango.util.logging.MangoLogger
WEB容器运行程序:
很多时候我们并不直接通过Main方法运行自己的程序,而是使用tomcat,jetty等WEB容器。这时我们只需将下面的“监听器”拷配到web.xml文件的最前面,即可让mango框架使用Log4J输出日志信息。
<listener> <listener-class>org.jfaster.mango.plugin.listener.Log4JLoggerListener</listener-class> </listener>
(4)使用控制台输出日志:
使用System.out输出日志到控制台不需要配置文件。
Main方法运行程序:
只需要在Main方法的最前面加入如下代码,即可让Mango框架使用控制台输出日志信息:
MangoLogger.useConsoleLogger();
上面的代码中MangoLogger的类全名为org.jfaster.mango.util.logging.MangoLogger
WEB容器运行程序:
很多时候我们并不直接通过Main方法运行自己的程序,而是使用tomcat,jetty等WEB容器。这时我们只需将下面的“监听器”拷配到web.xml文件的最前面,即可让mango框架使用控制台输出日志信息。
<listener> <listener-class>org.jfaster.mango.plugin.listener.ConsoleLoggerListener</listener-class> </listener>
三. Mango集成Spring
在项目开发中,一般都会使用spring管理对象,进行依赖注入。 我们能通过mango自带的spring插件,便捷的将mango集成到spring中。
纯配置文件集成:
纯配置文件集成是最简单的集成方式,所有的集成操作均在spring配置文件中,由spring容器创建数据库源工厂,mango对象和扫描使用@DB注解修饰的DAO类。
Mango框架使用SimpleDataSourceFactory连接单一数据库,
使用MasterSlaveDataSourceFactory连接主从数据库,
使用MultipleDatabaseDataSourceFactory连接混合数据库集群,
下面将分别给出这3种方式连数据库的配置实例。
(1)连单一数据库配置实例:
<beans> <!-- 配置数据源工厂 --> <bean id="dsf" class="org.jfaster.mango.datasource.SimpleDataSourceFactory"> <property name="dataSource"> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> </property> </bean> <!-- 配置mango对象 --> <bean id="mango" class="org.jfaster.mango.operator.Mango" factory-method="newInstance"> <property name="dataSourceFactory" ref="dsf" /> </bean> <!-- 配置扫描使用@DB注解修饰的DAO类 --> <bean class="org.jfaster.mango.plugin.spring.MangoDaoScanner"> <property name="packages"> <list> <!-- 扫描包名 --> <value>org.jfaster.mango.example.spring</value> <!-- <value>其他需要扫描的包</value> --> </list> </property> </bean> </beans>
上面的配置主要包含3部分。
配置数据源工厂。DriverManagerDataSource数据源是mango框架对DataSource的简单实现,仅供测试使用,如果是生产环境,请使用HikariCP,c3p0,dbcp等高性能数据源。
配置mango对象。创建mango对象的最佳途径是通过Mango类的静态方法newInstance,所以使用了factory-method指定静态方法。
配置扫描使用@DB注解修饰的DAO类。MangoDaoScanner类是一个扫描DAO的扫描器,它能自动扫描packages属性中指定包下的所有类,识别出@DB注解修饰的DAO类,并将他自动加载到spring大工厂中,这样我们既能从ApplicationContext中直接getBean获得dao实例,也能将dao实例直接Autowired到所有由spring管理的类上。需要注意的是所有DAO类必须以DAO或Dao结尾,才能被扫描器识别。
(2)连主从数据库配置实例:
<beans> <!-- 配置主从数据源工厂 --> <bean id="dsf" class="org.jfaster.mango.datasource.MasterSlaveDataSourceFactory"> <property name="master"> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example_master" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> </property> <property name="slaves"> <list> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example_slave1" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example_slave2" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> </list> </property> </bean> <!-- 配置mango对象 --> <bean id="mango" class="org.jfaster.mango.operator.Mango" factory-method="newInstance"> <property name="dataSourceFactory" ref="dsf" /> </bean> <!-- 配置扫描使用@DB注解修饰的DAO类 --> <bean class="org.jfaster.mango.plugin.spring.MangoDaoScanner"> <property name="packages"> <list> <!-- 扫描包名 --> <value>org.jfaster.mango.example.spring</value> <!-- <value>其他需要扫描的包</value> --> </list> </property> </bean> </beans>
(3)连多个数据库集群配置实例:
<beans> <!-- 配置简单数据源工厂 --> <bean id="simpleDataSourceFactory" class="org.jfaster.mango.datasource.SimpleDataSourceFactory"> <property name="name" value="dsf1" /> <property name="dataSource"> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> </property> </bean> <!-- 配置主从数据源工厂 --> <bean id="masterSlaveDataSourceFactory" class="org.jfaster.mango.datasource.MasterSlaveDataSourceFactory"> <property name="name" value="dsf2" /> <property name="master"> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example_master" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> </property> <property name="slaves"> <list> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example_slave1" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <bean class="org.jfaster.mango.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mango_example_slave2" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> </list> </property> </bean> <!-- 配置mango对象 --> <bean id="mango" class="org.jfaster.mango.operator.Mango" factory-method="newInstance"> <property name="dataSourceFactories"> <list> <ref bean="simpleDataSourceFactory" /> <ref bean="masterSlaveDataSourceFactory" /> </list> </property> </bean> <!-- 配置扫描使用@DB注解修饰的DAO类 --> <bean class="org.jfaster.mango.plugin.spring.MangoDaoScanner"> <property name="packages"> <list> <!-- 扫描包名 --> <value>org.jfaster.mango.example.spring</value> <!-- <value>其他需要扫描的包</value> --> </list> </property> </bean> </beans>
配置文件加代码集成:
一般情况下使用纯配置文件集成就能完成大多数项目需求,但在有些项目中,我们需要自己管理数据源工厂,以便在线上动态切换数据源。这时数据源工厂和mango对象对象就不能简单的交由spring管理,我们需要使用配置文件加代码的方式来完成集成。
至此,关于Mango的系列分享就完了,由于工作的原因,没能及时分享出来,望见谅,同时感谢诸君的支持!
代码见github: https://github.com/JavaCodeMood/mango-example1
共同學習,寫下你的評論
評論加載中...
作者其他優質文章