1.RestFul风格是一种URL规则,传递参数的时候不用?改用/
@RestMapping(“/list/{id}”)通过@PathVariable()可以接收url中传过来的参数,@RestMapping(“/list/{id}”)中接收参数使用大括号加上变量名称@PathVariable(“id”)中的变量名称要和@RestMapping(“/list/{id}”)中的变量名称相同
2. Mysql中建表时给字段添加注释:①CREATE TABLE groups(gid INT PRIMARY KEY AUTO_INCREMENT COMMENT '设置主键自增')②查看表注释:SHOW CREATE TABLE communication_group③查看列注释:SHOW FULL COLUMNS FROM groups
3. 这个::是java 8里引入lambda后的一种用法,表示引用,比如静态方法的引用String::valueOf;
比如构造器的引用,ArrayList::new
4.各种校验:
//联系电话校验
String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(16[([0-3]|[5-9])])|(17[([0-3]|[5-9])])|(18[0,5-9]))\\d{8}$";
//联系邮箱校验
String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
5. @JsonIgnoreProperties(ignoreUnknown = true),将这个注解写在类上之后,就会忽略类中不存在的字段,若这个字段存在则不会忽略。这个注解还可以指定要忽略的字段(不管是空还是非空)。使用方法如下@JsonIgnoreProperties({ "internalId", "secretKey" }),@JsonIgnore此注解用于属性或者方法上(最好是属性上),序列化和反序列化就会忽略该属性(不管该属性是空还是非空),以上的三个注解都是在序列化和反序列化的时候起作用。
@JsonInclude()注解:该注解只对javaBean序列化为json对象时起作用,反序列化的时候不起作用
使用jackson进行序列化时,往往会遇到后台某个实体对象的属性为null,当序列化成json时对应的属性也为null;这样在某些前端组件上应用该json对象会报错。(例如:echarts)
下面总结了两种方法,解决了当属性为null时不参与序列化:
方法一:
1.实体上使用如下注解 @JsonInclude(Include.NON_NULL) 将该标记放在属性上,如果该属性为NULL则不参与序列化 ;如果放在类上边,那对这个类的全部属性起作用。具体取值有:
//Include.Include.ALWAYS 默认
//Include.NON_DEFAULT 属性为默认值不序列化
//Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化
//Include.NON_NULL 属性为NULL 不序列化
注:使用了该注解,那么在import时需要把一下两个类引入到源文件中
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
2.代码上使用如下方法:
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
User user = new User(1,"",null);
String outJson = mapper.writeValueAsString(user);
System.out.println(outJson);
通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化 。具体取值有:
//Include.Include.ALWAYS 默认
//Include.NON_DEFAULT 属性为默认值不序列化
//Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化
//Include.NON_NULL 属性为NULL 不序列化
6. 学习JackJson
7. MySql相关
①当某一列发生变化需要修改的时候执行如下面的语句(前提是列名没有发生变化,只是数据类型和约束发生了变化):
ALTER TABLE HRSC_ORDER_BATCH MODIFY COLUMN FAIL_REAS INT(3) COMMENT '失败原因【批量派出失败原因:字典值';
②如果想在一个已经建好的表中添加一列,可以用诸如:
alter table t1 add column addr varchar(20) not null;
这条语句会向已有的表t1中加入一列addr,这一列在表的最后一列位置。如果我们希望添加在指定的一列,可以用:
alter table t1 add column addr varchar(20) not null COMMENT ‘注释的东西’ after user1;
注意,上面这个命令的意思是说添加addr列到user1这一列后面。如果想添加到第一列的话,可以用:
alter table t1 add column addr varchar(20) not null first;
将表web1.new_table change中,列名def改为unit
alter table web1.new_table change def unit char;
将表web1.new_table change中,列名def的列删除
alter table web1.new_table drop column def ;
if等的用法:
8.@Value("${db.driverclass}"):获取配置文件(.properties结尾)的db.driverclass的值,并自动注入到类的某个setter方法上
有的时候我们定义了Properties文件,并且使用Spring的PropertyPlaceholderConfigurer类在Spring配置文件中以占位符的方式替换数据库等配置文件,那么万一我们想将这些属性也同时注入到某个bean中呢?
这里做个说明,网上很多资料说的<util:properties>方式我们这里不做介绍,有兴趣的自己去看。我们这里只介绍使用PropertyPlaceholderConfigurer管理起来的方式。
其实很简单,比如你在db.properties中配置的db.driverclass=com.mysql.jdbc.Driver,则在我们的bean的某个set方法上可以用@Value("${db.driverclass}")来完成注入,
也可以在成员变量上注入。
例子代码如:
@Service
public class DatabaseInfo {
private String driverClass; //也可以在这里注入
private void setDriverClass(String dc) {
this.driverClass = dc;
}
}
9. lombok 注解:
lombok 提供的注解不多,可以参考官方视频的讲解和官方文档。
Lombok 注解在线帮助文档:http://projectlombok.org/features/index.
下面介绍几个我常用的 lombok 注解:
@Data :注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
@Setter:注解在属性上;为属性提供 setting 方法
@Getter:注解在属性上;为属性提供 getting 方法
@Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
lombok是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写,即通过采用注解的方式,消除代码中的构造方法,getter/setter等代码,使我们写的类更加简洁,当然,这带来的副作用就是不易阅读…不过,还是能看得懂吧,废话不多说,先看一下lombok支持的一些常见的注解。
@NonNull
@Cleanup
@Getter/@Setter
@ToString
@EqualsAndHashCode
@NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor
@Data
@Value
@SneakyThrows
@Synchronized
@Log
@NonNull
这个注解可以用在成员方法或者构造方法的参数前面,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常,举个例子来看看:
//成员方法参数加上@NonNull注解public String getName(@NonNull Person p){
return p.getName();
}
实际效果相当于:
public String getName(@NonNull Person p){
if(p==null){
throw new NullPointerException("person");
}
return p.getName();
}
用在构造方法的参数上效果类似,就不再举例子了。
@Cleanup
这个注解用在变量前面,可以保证此变量代表的资源会被自动关闭,默认是调用资源的close()方法,如果该资源有其它关闭方法,可使用@Cleanup(“methodName”)来指定要调用的方法,就用输入输出流来举个例子吧:
public static void main(String[] args) throws IOException {
@Cleanup InputStream in = new FileInputStream(args[0]);
@Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[1024];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
实际效果相当于:
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
if (out != null) {
out.close();
}
}
} finally {
if (in != null) {
in.close();
}
}
}
是不是简化了很多。
@Getter/@Setter
这一对注解从名字上就很好理解,用在成员变量前面,相当于为成员变量生成对应的get和set方法,同时还可以为生成的方法指定访问修饰符,当然,默认为public,直接来看下面的简单的例子:
public class Programmer{
@Getter
@Setter
private String name;
@Setter(AccessLevel.PROTECTED)
private int age;
@Getter(AccessLevel.PUBLIC)
private String language;
}实际效果相当于:
public class Programmer{
private String name;
private int age;
private String language;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
protected void setAge(int age){
this.age = age;
}
public String getLanguage(){
return language;
}
}这两个注解还可以直接用在类上,可以为此类里的所有非静态成员变量生成对应的get和set方法。
@ToString/@EqualsAndHashCode
这两个注解也比较好理解,就是生成toString,equals和hashcode方法,同时后者还会生成一个canEqual方法,用于判断某个对象是否是当前类的实例,生成方法时只会使用类中的非静态和非transient成员变量,这些都比较好理解,就不举例子了。
当然,这两个注解也可以添加限制条件,例如用@ToString(exclude={“param1”,“param2”})来排除param1和param2两个成员变量,或者用@ToString(of={“param1”,“param2”})来指定使用param1和param2两个成员变量,@EqualsAndHashCode注解也有同样的用法。
@NoArgsConstructor/@RequiredArgsConstructor /@AllArgsConstructor
这三个注解都是用在类上的,第一个和第三个都很好理解,就是为该类产生无参的构造方法和包含所有参数的构造方法,第二个注解则使用类中所有带有@NonNull注解的或者带有final修饰的成员变量生成对应的构造方法,当然,和前面几个注解一样,成员变量都是非静态的,另外,如果类中含有final修饰的成员变量,是无法使用@NoArgsConstructor注解的。
三个注解都可以指定生成的构造方法的访问权限,同时,第二个注解还可以用@RequiredArgsConstructor(staticName=”methodName”)的形式生成一个指定名称的静态方法,返回一个调用相应的构造方法产生的对象,下面来看一个生动鲜活的例子:
@RequiredArgsConstructor(staticName = "sunsfan")@AllArgsConstructor(access = AccessLevel.PROTECTED)@NoArgsConstructorpublic class Shape {
private int x;
@NonNull
private double y;
@NonNull
private String name;
}实际效果相当于:
public class Shape {
private int x;
private double y;
private String name;
public Shape(){
}
protected Shape(int x,double y,String name){
this.x = x;
this.y = y;
this.name = name;
}
public Shape(double y,String name){
this.y = y;
this.name = name;
}
public static Shape sunsfan(double y,String name){
return new Shape(y,name);
}
}
@Data/@Value
呃!!
@Data注解综合了3,4,5和6里面的@RequiredArgsConstructor注解,其中@RequiredArgsConstructor使用了类中的带有@NonNull注解的或者final修饰的成员变量,它可以使用@Data(staticConstructor=”methodName”)来生成一个静态方法,返回一个调用相应的构造方法产生的对象。这个例子就也省略了吧…
@Value注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法。
@SneakyThrows
这个注解用在方法上,可以将方法中的代码用try-catch语句包裹起来,捕获异常并在catch中用Lombok.sneakyThrow(e)把异常抛出,可以使用@SneakyThrows(Exception.class)的形式指定抛出哪种异常,很简单的注解,直接看个例子:
public class SneakyThrows implements Runnable {
@SneakyThrows(UnsupportedEncodingException.class)
public String utf8ToString(byte[] bytes) {
return new String(bytes, "UTF-8");
}
@SneakyThrows
public void run() {
throw new Throwable();
}
}
实际效果相当于:
public class SneakyThrows implements Runnable {
@SneakyThrows(UnsupportedEncodingException.class)
public String utf8ToString(byte[] bytes) {
try{
return new String(bytes, "UTF-8");
}catch(UnsupportedEncodingException uee){
throw Lombok.sneakyThrow(uee);
}
}
@SneakyThrows
public void run() {
try{
throw new Throwable();
}catch(Throwable t){
throw Lombok.sneakyThrow(t);
}
}
}
@Synchronized
这个注解用在类方法或者实例方法上,效果和synchronized关键字相同,区别在于锁对象不同,对于类方法和实例方法,synchronized关键字的锁对象分别是类的class对象和this对象,而@Synchronized得锁对象分别是私有静态final对象LOCK和私有final对象lock,当然,也可以自己指定锁对象,例子也很简单,往下看:
public class Synchronized {
private final Object readLock = new Object();
@Synchronized
public static void hello() {
System.out.println("world");
}
@Synchronized
public int answerToLife() {
return 42;
}
@Synchronized("readLock")
public void foo() {
System.out.println("bar");
}
}实际效果相当于:
public class Synchronized {
private static final Object $LOCK = new Object[0];
private final Object $lock = new Object[0];
private final Object readLock = new Object();
public static void hello() {
synchronized($LOCK) {
System.out.println("world");
}
}
public int answerToLife() {
synchronized($lock) {
return 42;
}
}
public void foo() {
synchronized(readLock) {
System.out.println("bar");
}}}
@Log
这个注解用在类上,可以省去从日志工厂生成日志对象这一步,直接进行日志记录,具体注解根据日志工具的不同而不同,同时,可以在注解中使用topic来指定生成log对象时的类名。不同的日志注解总结如下(上面是注解,下面是实际作用):
@CommonsLogprivate static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);@JBossLogprivate static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);@Logprivate static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());@Log4jprivate static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);@Log4j2private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);@Slf4jprivate static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);@XSlf4jprivate static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
关于lombok的注解先写到这里,当然,还有其他一些注解需要大家自己去摸索,同时lombok一直在扩展,将来肯定会加入更多的注解元素,拭目以待了。
myBatis中where标签的使用:
where标记的作用类似于动态sql中的set标记,他的作用主要是用来简化sql语句中where条件判断的书写的,如下所示:
<select id="selectByParams" parameterType="map" resultType="user">
select * from user
<where>
<if test="id != null ">id=#{id}</if>
<if test="name != null and name.length()>0" >and name=#{name}</if>
<if test="gender != null and gender.length()>0">and gender = #{gender}</if>
</where>
</select>
在上述SQL中加入ID的值为null的话,那么打印出来的SQL为:select * from user where name="xx" and gender="xx"
where 标记会自动将其后第一个条件的and或者是or给忽略掉
如果直接用Where,不用标签则会打出:select * from user where and name="xx" and gender="xx"报错,所以用<where>标签,相当于用where 1=1...;
mysql如何用order by 自定义排序
原表 user:
id name roleId
1 aaa 1
2 bbb 2
3 ccc 3
4 ddd 4
5 eee 51,MySQL可以通过field()函数自定义排序,格式:field(value,str1,str2,str3,str4),value与str1、str2、str3、str4比较,返回1、2、3、4,如遇到null或者不在列表中的数据则返回0.
例如:select * from user order by field(roleId,2,3,4,1,5);
结果:
id name roleId
2 bbb 2
3 ccc 3
4 ddd 4
1 aaa 1
5 eee 5
2,locate(substr,str)函数返回子串substr在字符串str中第一次出现的位置,可以根据该函数进行排序
例如:select * from user order by locate(id,'2,3,1,5,4');
结果:
id name roleId
2 bbb 2
3 ccc 3
1 aaa 1
5 eee 5
4 ddd 4
MyBatis写sql注意事项:
括号必须放在外边,不能<foreach collection="certNos" item="certNo" separator=",">(#{certNo})</foreach>,但是批量保存确实这样
拼接的模糊查询经典例子
去重
mySql的一种异常信息:
column in where clause is ambiguous MySQL异常,在多表连接查询中,若连接条件字段在多个表中同名,却没有使用全限定名称,如 logicdeleteFlag,执行时会报这个异常,MySQL没办法识别这个字段指的是哪个表的字段。必须使用全限定名称,如:tableName.logicdeleteFlag(若没有相同的字段可以不给权限,建议都给权限,避免出错)。
6. JSON.parseObject,是将Json字符串转化为相应的对象;JSON.toJSONString则是将对象转化为Json字符串。在前后台的传输过程中,Json字符串是相当常用的:如下所示,其中Staff是员工对象/** * json字符串转化为对象 */ String jsonString = "{name:'Antony',age:'12',sex:'male',telephone:'88888'}"; Staff staff = JSON.parseObject(jsonString, Staff.class); System.out.println(staff.toString()); /** * 对象转化为json字符串 */ String jsonStr = JSON.toJSONString(staff); System.out.println(jsonStr);
在JSON.parseObject 的时候,会去填充名称相同的属性。对于Json字符串中没有,而model类有的属性,会为null;对于model类没有,而Json字符串有的属性,不做任何处理。
7.foreach中获取元素在集合中的位置
8.项目开发中git的一些语句:
①查看当前git的版本git rev-parse head
9.StringBuffer获取某个位置的字符
StringBuffer s = new StringBuffer(“1,2,3”),获取3
Char s =s.charAt(s.length()-1),字符串只有==方法没有equals方法
//删除某个索引的字符,假设删除s中的3
s.deleteCharAt(s.length()-1)
10. 集合与数组的相互转化:
List,Set转换为数组的方法:网络路径:https://www.cnblogs.com/annieBaby/p/4889406.html
toArray函数有两种形式,一种无参数,一种带参数,注意带参数形式中,要指明数组的大小。
参考代码:
public void convertCollectionToArray() {
List list = new ArrayList();
Object[] objectArray1 = list.toArray();
String[] array1 = list.toArray(new String[list.size()]);
Set set = new HashSet();
Object[] objectArray2 = set.toArray();
String[] array2 = set.toArray(new String[set.size()]);
}
反过来,数组转换为List,Set。
Integer[] numbers = {7, 7, 8, 9, 10, 8, 8, 9, 6, 5, 4};
// To convert an array into a Set first we convert it to a List. Next
// with the list we create a HashSet and pass the list as the constructor.
List list = Arrays.asList(numbers);
Set set = new HashSet(list);
注意:对于int[]数组不能直接这样做,因为asList()方法的参数必须是对象。应该先把int[]转化为Integer[]。对于其他primitive类型的数组也是如此,必须先转换成相应的wrapper类型数组。
1 2 3 4 5 6 7 8 |
int[] numbers = {7, 7, 8, 9, 10, 8, 8, 9, 6, 5, 4}; int size = numbers.length; Integer[] array = new Integer[size]; for (int i = 0; i < numbers.length; i++) { Integer integer = numbers[i]; array[i] = integer; } List list = Arrays.asList(array); |
9.Spring中@Resource与@Autowired与@Component注解的总结:http://blog.csdn.net/wxw520zdh/article/details/52733811###;
10.myBatis实现批量修改经典例子
<update id="updateOrderEndDateAndSate"> UPDATE HRSC_ORDER <trim prefix=" SET " suffixOverrides=","> <trim prefix=" ORDER_END_DATE = CASE " suffix=" END,"> <foreach collection="orderList" item="item"> <if test="item.orderEndDate != null"> WHEN ORDER_ID = #{item.orderId} THEN #{item.orderEndDate} </if> </foreach> </trim> <trim prefix=" ORDER_STATE = CASE " suffix=" END,"> <foreach collection="orderList" item="item"> <if test="item.orderState != null"> WHEN ORDER_ID = #{item.orderId} THEN #{item.orderState} </if> </foreach> </trim> <trim prefix=" LEAVE_OPER_TIME = CASE " suffix=" END,"> <foreach collection="orderList" item="item"> <if test="item.leaveOperTime != null"> WHEN ORDER_ID = #{item.orderId} THEN #{item.leaveOperTime} </if> </foreach> </trim> <trim prefix=" REVOKE_REASON = CASE " suffix=" END,"> <foreach collection="orderList" item="item"> <if test="item.revokeReason != null"> WHEN ORDER_ID = #{item.orderId} THEN #{item.revokeReason} </if> </foreach> </trim> </trim> WHERE ORDER_ID IN <foreach collection="orderList" item="item" open="(" separator="," close=")"> #{item.orderId} </foreach> </update>
myBatis实现查询,一对多的情况,一个人(身份证号唯一确定一个人)一种险种(社保月度明细id和险种一一对应)对应一条问题人员数据(所得都是一个业务月份),现在需要查询的结果为一个人一条数据,将险种和问题人员状态封装成一个对象QuestionPerTypeState,查询代码如下,查询语句没有任何变化,都是查询一条,一条的,只是有了resultMap
<select id="findQuestionPerList" resultMap="findQuestionPerMap"> SELECT E.CERT_NO,Q.SINS_DET_ID,Q.QUESTION_PER_STATE FROM SINS_EMP_INFO E JOIN SINS_QUESTION_PER Q ON E.SINS_EMP_ID=E.SINS_EMP_ID WHERE 1=1 <if test="isEffect !=null">AND E.IS_EFFECT=#{isEffect} AND Q.IS_EFFECT=#{isEffect}</if> <if test="sinsAcctId !=null">AND Q.SINS_ACCT_ID =#{sinsAcctId}</if> <if test="natMon !=null">AND Q.NAT_MON=#{natMon}</if> </select> <!-- 使用resultMap映射实体类和字段之间的一一对应关系--> <resultMap id="findQuestionPerMap" type="com.sinosoft.cpyy.model.apply.SinsQuestionPer"> <id property="certNo" column="CERT_NO"/>#主键 <collection property="questionPerTypeStates" ofType="com.sinosoft.cpyy.model.apply.QuestionPerTypeState">#一般集合属性 <id property="sinsDetId" column="SINS_DET_ID"/>#主键 <result property="questionPerState" column="QUESTION_PER_STATE"/>#一般属性 </collection> </resultMap>
<resultMap></resultMap>应用
<!--查询社保实时数据--> <select id="findActualData" parameterType="com.sinosoft.cpyy.model.actualData.ActualData" resultMap="findProductMap"> SELECT e.EMP_NAME,e.CERT_NO,e.PER_COM_CODE,e.HOUSEHOLD_PROY,m.EXECUTE_AREA_ID,m.NAT_MON natMonNew,m.APPLY_MON applyMonNew,m.SINS_STATE,m.PRODUCT_ID, m.STATE,m.PER_RADIX,m.UNIT_PAY,m.PER_PAY,m.PAY_FEE_WAY, a.UNIT_SINS_NO,a.SINS_ACCT_NAME,q.DATA_SOURCE,q.QUESTION_PER_TYPE,m.BUSI_CUST_NAME, m.SIGN_SUPP_NAME,CONCAT(e.CERT_NO,'+',m.NAT_MON) title,m.CRE_ROLE_ID FROM SINS_MONTHLY_DET m JOIN SINS_EMP_INFO e ON m.SINS_EMP_ID =e.SINS_EMP_ID JOIN SINS_ACCT_INFO a ON m.CUST_SINS_ID = a.SINS_ACCT_ID LEFT JOIN SINS_QUESTION_PER q ON m.SINS_DET_ID = q.SINS_DET_ID WHERE 1=1 <if test="isEffect !=null">AND m.IS_EFFECT=#{isEffect} AND e.IS_EFFECT=#{isEffect} AND a.IS_EFFECT=#{isEffect} AND (q.IS_EFFECT =#{isEffect} OR q.IS_EFFECT IS NULL) </if> <if test="certNos !=null and certNos.size>0">AND CONCAT(e.CERT_NO,'+',m.NAT_MON) IN (<foreach collection="certNos" item="certNo" separator=","> #{certNo} </foreach>) </if> <if test="empName !=null and empName !=''">AND e.EMP_NAME lIKE CONCAT('%',#{empName},'%')</if> <if test="productIdList !=null and productIdList.size>0">AND m.PRODUCT_ID IN( <foreach collection="productIdList" item="productId" separator=","> #{productId} </foreach> ) </if> <if test="natMonNew !=null and natMonNew !=''">AND m.NAT_MON =#{natMonNew}</if> <if test="applyMonNew !=null and applyMonNew !=''">AND m.APPLY_MON =#{applyMonNew}</if> <if test="executeAreaId !=null and executeAreaId !=''">AND m.EXECUTE_AREA_ID=#{executeAreaId}</if> <if test="state != null and state !=''">AND m.STATE =#{state}</if> <if test="custId !=null and custId !=''">AND m.CUST_ID =#{custId}</if> <if test="signSuppId !=null and signSuppId !=''">AND m.SIGN_SUPP_ID =#{signS uppId}</if> <if test="custSinsId !=null and custSinsId !=''">AND m.CUST_SINS_ID =#{custSinsId}</if> <if test="unitSinsNo !=null and unitSinsNo !=''">AND a.UNIT_SINS_NO =#{unitSinsNo}</if> GROUP BY e.CERT_NO,m.NAT_MON,m.APPLY_MON,m.PRODUCT_ID </select>
<!-- 使用resultMap映射实体类和字段之间的一一对应关系--> <resultMap id="findProductMap" type="com.sinosoft.cpyy.model.actualData.ActualData"> <id property="title" column="title"/> <result property="creRoleId" column="CRE_ROLE_ID"/> <result property="certNo" column="CERT_NO"/> <result property="empName" column="EMP_NAME"/> <result property="perComCode" column="PER_COM_CODE"/> <result property="householdProy" column="HOUSEHOLD_PROY"/> <result property="executeAreaId" column="EXECUTE_AREA_ID"/> <result property="natMonNew" column="natMonNew"/> <result property="applyMonNew" column="applyMonNew"/> <result property="sinsState" column="SINS_STATE"/> <result property="state" column="STATE"/> <result property="payFeeWay" column="PAY_FEE_WAY"/> <result property="unitSinsNo" column="UNIT_SINS_NO"/> <result property="sinsAcctName" column="SINS_ACCT_NAME"/> <result property="dataSource" column="DATA_SOURCE"/> <result property="questionPerType" column="QUESTION_PER_TYPE"/> <result property="busiCustName" column="BUSI_CUST_NAME"/> <result property="signSuppName" column="SIGN_SUPP_NAME"/> <collection property="actualProductList" ofType="com.sinosoft.cpyy.model.actualData.ActualProduct"> <id property="productId" column="PRODUCT_ID"/> <result property="perRadix" column="PER_RADIX"/> <result property="perPay" column="PER_PAY"/> <result property="unitPay" column="UNIT_PAY"/> </collection> </resultMap>