开发一个基于Seasar2框架的S2Dao来完成数据库数据的CURD操作,基于自动注入(DI)的方式,不是基于配置文件的方式,S2Dao类似于Mybatis,不同于Hibernate,因为不是想Hibernate完成数据的映射,使用S2Dao功能时,必须作成JavaBeans(数据库映射的实体类),Dao(.java),dicon文件,SQL文件(.sql,非必须是sql文件,但是必须要有SQL文),S2Dao的特点是,Dao直接就是带有逻辑操作的对象,不需要Dao的实现类,直接可以注入接口对象。
工程结构
对于S2Dao这个项目来说,Dao包的实现类是不需要的,因为本生的类就可以完成简单的逻辑操作,我们将需要处理的复杂数据,可以放到service层
S2Dao环境搭建
S2Dao是基于SeaSar2的框架的,所以我们必须在前面案例的基础上,然后再搭建环境
pom.xml
S2Dao 依赖s2-dao、s2-dao-tiger 、commons-beanutils、log4j、s2-extension等,简单说一下
s2-dao是核心包,用于处理所有的业务逻辑
s2-dao-tiger 是注解包,用于添加注解
s2-extension 这个是负责数据库连接池的操作
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>seasar</groupId>
<artifactId>demo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>demo Maven Webapp</name>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>aliyunmaven</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
<repository>
<id>seasar</id>
<url>https://www.seasar.org/maven/maven2/</url>
</repository>
<repository>
<id>ojdbc6</id>
<url>http://www.datanucleus.org/downloads/maven2/</url>
</repository>
</repositories>
<dependencies>
<!-- 导入jsp -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<!-- 导入servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- seasar框架 的容器 BEGIN-->
<dependency>
<groupId>org.seasar.container</groupId>
<artifactId>s2-framework</artifactId>
<version>2.3.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jboss/javassist -->
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.21.0-GA</version>
</dependency>
<!-- https://mvnrepository.com/artifact/ognl/ognl -->
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>2.6.9-patch-20070624</version>
</dependency>
<!-- Jta需要加入,不然就会报java.lang.NoClassDefFoundError: javax/transaction/TransactionManager -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!-- seasar框架 的容器 END-->
<!--seasar框架 Dao-->
<!-- 不同版本的s2-dao依赖的s2-framework不一样 -->
<dependency>
<groupId>org.seasar.dao</groupId>
<artifactId>s2-dao</artifactId>
<version>1.0.50</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seasar.container/s2-extension -->
<dependency>
<groupId>org.seasar.container</groupId>
<artifactId>s2-extension</artifactId>
<version>2.3.23</version>
</dependency>
<!-- 注解需要,对于实体类,需要这个包 -->
<dependency>
<groupId>org.seasar.dao</groupId>
<artifactId>s2-dao-tiger</artifactId>
<version>1.0.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/oracle/ojdbc6 -->
<!-- <dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<!-- 通过mysql 数据连接,我不想用oracle,因为是公司的数据,怕整错了 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<!-- 配置war包的名称 -->
<warName>hello</warName>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.6.v20170531</version>
<configuration>
<scanIntervalSecond>10</scanIntervalSecond>
<webApp>
<contextPath>/users</contextPath>
</webApp>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
app.dicon
需要配置拦截器(org.seasar.framework.aop.interceptors.InterceptorChain),调用dao.dicon下的interceport拦截器,同时还需要配置S2Dao自动注入的组建(org.seasar.framework.container.autoregister.AspectAutoRegister),配置了这两个,我们才可以愉快的使用自动注入完成数据库查询了
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components >
<!--dao.dicon 我们必须配置这个dao.dicon,而且还必须有j2ee这个dao文件,这个是s2-dao-1.0.50.jar包下面默认配置的,我草,真尼玛是坑啊-->
<include path="dao.dicon"/>
<!-- ==================================================================== -->
<!-- Interceptor Chains -->
<!-- ==================================================================== -->
<!-- DAO Interceptor Chain -->
<component name="daoChain" class="org.seasar.framework.aop.interceptors.InterceptorChain">
<!-- 调用dao.dicon下的interceport拦截器, -->
<initMethod name="add"><arg>dao.interceptor</arg></initMethod>
</component>
<!-- ==================================================================== -->
<!-- Component Auto Register -->
<!-- ==================================================================== -->
<!-- Component Auto Register -->
<component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
<!-- DAO -->
<initMethod name="addClassPattern" >
<arg>"com.yellowcong.dao"</arg>
<arg>".*Dao"</arg>
</initMethod>
<!-- Business Logic -->
<initMethod name="addClassPattern" >
<arg>"com.yellowcong.service"</arg>
<arg>".*Impl"</arg>
</initMethod>
</component>
<!-- ==================================================================== -->
<!-- Aspect Auto Register -->
<!-- ==================================================================== -->
<!-- S2Dao Interceptor Auto Register -->
<component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
<property name="interceptor">daoChain</property>
<initMethod name="addClassPattern" >
<arg>"com.yellowcong.dao"</arg>
<arg>".*Dao"</arg>
</initMethod>
</component>
</components>
j2ee.dicon
数据库配置,我修改为了mysql了,这个是自己建立的库,所以不害怕删错东西,数据库连接池是Seasar提供的(org.seasar.extension.dbcp.impl.ConnectionPoolImpl)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container//EN"
"http://www.seasar.org/dtd/components.dtd">
<components namespace="j2ee">
<component name="transactionManager"
class="org.seasar.extension.jta.TransactionManagerImpl"/>
<component name="requiredTx"
class="org.seasar.extension.tx.RequiredInterceptor"/>
<component name="requiresNewTx"
class="org.seasar.extension.tx.RequiresNewInterceptor"/>
<component name="mandatoryTx"
class="org.seasar.extension.tx.MandatoryInterceptor"/>
<component name="notSupportedTx"
class="org.seasar.extension.tx.NotSupportedInterceptor"/>
<component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory"/>
<component class="org.seasar.extension.jdbc.impl.BasicStatementFactory"/>
<component name="xaDataSource"
class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
<property name="driverClassName">
"com.mysql.jdbc.Driver"
</property>
<!-- 数据库配置-->
<!--
<property name="URL">"jdbc:oracle:thin:@10.0.7.170:1522:ORCL5"</property>
<property name="user">"SOFINAM_HENSEI"</property>
<property name="password">"SOFINAM_HENSEI"</property>
-->
<property name="URL">"jdbc:mysql:///seasar2"</property>
<property name="user">"root"</property>
<property name="password">"root"</property>
</component>
<component name="connectionPool"
class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl">
<property name="timeout">600</property>
<property name="maxPoolSize">10</property>
<property name="allowLocalTx">true</property>
<destroyMethod name="close"/>
</component>
<component name="dataSource"
class="org.seasar.extension.dbcp.impl.DataSourceImpl"/>
</components>
log4j.xml
必须配置日志,不然就会报错,说找不到日志配置
<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- STDOUT -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{yyyy/MM/dd HH:mm:ss}] %-5p [%c{1}]: %m%n"/>
</layout>
</appender>
<category name="org.seasar" additivity="false">
<priority value="DEBUG"/>
<appender-ref ref="CONSOLE"/>
</category>
<category name="com.yellowcong" additivity="false">
<priority value="DEBUG"/>
<appender-ref ref="CONSOLE"/>
</category>
<root>
<priority value ="INFO" />
<appender-ref ref="CONSOLE" />
</root>
</log4j:configuration>
案例
查询seasar2数据库里面user表中的所有数据
User.java
实体类,需要和Mysql里面的数据需要对应,Mysql中的字段比如 user_age可以自动映射为userAge,这个是有点特别的地方,框架中,会自动将自动中的_
替换掉,然后弄成驼峰命名的方式映射Bean,同时我们需要配置@Bean(talbe=”User”)来指定所对应的表,还可以通过 @Column(“user_name”)指定字段和名称,这个注解需要在getXX上面使用
package com.yellowcong.service.entity;
import java.io.Serializable;
import org.seasar.dao.annotation.tiger.Bean;
/**
*
* 作者:yellowcong 日期:2017/08/30 時間:9:26:25 描述:
*/
@Bean(table="USER")
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String username;
private Integer id;
private String nickname;
private String password;
private Integer sex;
private Integer age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
UserDao
配置Userdao,需要使用注解@S2Dao(bean=User.class) 来表明是哪一个表,然后可以拥有@Query注解可以直接查询操作。
常用的注解
@Arguments 设定Sql的参数 用 /username/这种方式调用
@Sql 直接执行sql查询语句
@Query 执行查询语句,与@Sql不同的是,可以不用写(select * From xx where),直接查@S2Dao标注的这张表
@ProcedureCall 存储过程
对于删除,更新,添加这种带有事物的操作,需要以下面这种方式命名方法名
void deleteXx()
void addXX()
void update XX()
package com.yellowcong.dao;
import java.util.List;
import org.seasar.dao.annotation.tiger.S2Dao;
import org.seasar.dao.annotation.tiger.Sql;
import com.yellowcong.service.entity.User;
/**
*
*作者:yellowcong
*日期:2017/08/29
*時間:16:16:38
*描述:用户操作的Dao
*/
@S2Dao(bean=User.class)
public interface UserDao {
/**
* 获取用户名称
* @param username
* @return
*/
@Sql("SELECT * FROM USER ")
List<User> list();
}
UserService
package com.yellowcong.service;
import java.util.List;
import com.yellowcong.service.entity.User;
/**
*
*作者:yellowcong
*日期:2017/08/29
*時間:16:48:46
*描述:
*/
public interface UserService {
/**
* 获取用户名称
* @param username
* @return
*/
List<User> list();
}
UserServiceImpl
package com.yellowcong.service.impl;
import java.util.List;
import com.yellowcong.dao.UserDao;
import com.yellowcong.service.UserService;
import com.yellowcong.service.entity.User;
/**
*
*作者:yellowcong
*日期:2017/08/29
*時間:16:49:32
*描述:
*/
public class UserServiceImpl implements UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public List<User> list() {
return this.userDao.list();
}
}
测试代码
package com.yellowcong.test;
import java.util.List;
import org.junit.Test;
import org.seasar.dao.unit.S2DaoTestCase;
import com.yellowcong.service.UserService;
import com.yellowcong.service.entity.User;
/**
*
*作者:yellowcong
*日期:2017/08/30
*時間:8:51:02
*描述:
*/
public class Demo2 extends S2DaoTestCase{
private UserService userService ;
public void setUserService(UserService userService) {
this.userService = userService;
}
protected void setUp() throws Exception {
super.setUp();
include("app.dicon");
}
@Test
public void test() {
List<User> users = this.userService.list();
for(User user:users) {
System.out.println(user.getNickname()+" "+user.getPassword());
}
}
}
查询结果
查询的数据,直接默认的日志会显示我们的操作
[2017/08/30 10:42:51] DEBUG [ConnectionPoolImpl]: 物理的なコネクションを取得しました
[2017/08/30 10:42:51] DEBUG [DataSourceImpl]: 論理的なコネクションを取得しました
[2017/08/30 10:42:51] DEBUG [ConnectionWrapperImpl]: 論理的なコネクションを閉じました
[2017/08/30 10:42:51] DEBUG [DataSourceImpl]: 論理的なコネクションを取得しました
[2017/08/30 10:42:51] DEBUG [ConnectionWrapperImpl]: 論理的なコネクションを閉じました
[2017/08/30 10:42:52] DEBUG [DataSourceImpl]: 論理的なコネクションを取得しました
[2017/08/30 10:42:52] DEBUG [BasicHandler]: SELECT * FROM USER
[2017/08/30 10:42:52] DEBUG [ConnectionWrapperImpl]: 論理的なコネクションを閉じました
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
yes test
null test
null test
null test
yes test
test test
[2017/08/30 10:42:52] DEBUG [ConnectionWrapperImpl]: 物理的なコネクションを閉じました