网站架构设计图,网站搜索功能设计,wordpress 插件开启,代理网页游戏需要什么条件啊在最近的一个工作中#xff0c;为了简单方便我就是用了Spring自带的JdbcTemplate来访问数据库#xff0c;我以为之前自己很熟练的掌握#xff0c;后来才发现我太天真了#xff0c;踩了很多坑。
基本方法
JdbcTemplate自带很多方法可以执行SQL语句,以下我主要列举#xf…在最近的一个工作中为了简单方便我就是用了Spring自带的JdbcTemplate来访问数据库我以为之前自己很熟练的掌握后来才发现我太天真了踩了很多坑。
基本方法
JdbcTemplate自带很多方法可以执行SQL语句,以下我主要列举比较常用的方法
//执行SQL返回一个对象
Override
public T T queryForObject(String sql, RowMapperT rowMapper, Object... args)throws DataAccessException {ListT results query(sql, args, new RowMapperResultSetExtractorT(rowMapper, 1));return DataAccessUtils.requiredSingleResult(results);
}//同上不过多要传入返回值的对象的Class
Override
public T T queryForObject(String sql, ClassT requiredType)throws DataAccessException {return queryForObject(sql, getSingleColumnRowMapper(requiredType));
}//执行SQL返回一个Map对象
Override
public MapString, Object queryForMap(String sql, Object... args)throws DataAccessException {return queryForObject(sql, args, getColumnMapRowMapper());
}//执行SQL返回一个List对象
Override
public T ListT query(String sql, Object[] args, RowMapperT rowMapper) throws DataAccessException {return query(sql, args, new RowMapperResultSetExtractorT(rowMapper));
}//执行SQL返回一个List对象
Override
Override
public T ListT queryForList(String sql, ClassT elementType, Object... args)throws DataAccessException {return query(sql, args, getSingleColumnRowMapper(elementType));
}//执行一条SQL主要用于更新、新增数据
Override
public int update(String sql, Object... args) throws DataAccessException {return update(sql, newArgPreparedStatementSetter(args));
}//执行SQL返回一个List对象List里是Map对象
Override
public ListMapString, Object queryForList(String sql, Object... args) throws DataAccessException {return query(sql, args, getColumnMapRowMapper());
}注意点
至少返回一个对象
Override
public T T queryForObject(String sql, RowMapperT rowMapper, Object... args)throws DataAccessException {ListT results query(sql, args, new RowMapperResultSetExtractorT(rowMapper, 1));return DataAccessUtils.requiredSingleResult(results);
}public RowMapperResultSetExtractor(RowMapperT rowMapper, int rowsExpected) {Assert.notNull(rowMapper, RowMapper is required);this.rowMapper rowMapper;this.rowsExpected rowsExpected;
}以上代码就是可以知道必须返回一个对象不能返回null如果从数据库查找发现没有一条信息吻合就会报错报以下的错误
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 0所以如果不确定是否有信息就使用query、queryForList来避免错误。返回单对象一般会有这样的限制如果自己不确定可以使用该方法的时候看一下源码设置了1就代表必须要有一个值。
返回指定对象
JdbcTemplate里面这样的方法就是可以传入了一个对象的Class值就可以返回该对象的值但是需要注意它只支持基础类型
//例如它支持以下的写法
public Integer getCourseCount(String sql){return (Integer) jdbcTemplate.queryForObject(sql,java.lang.Integer.class);
}通过源代码发现ClassT requiredType这个参数支持以下类型源代码就是从primitiveWrapperTypeMap查找是否是一下类型
primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
primitiveWrapperTypeMap.put(Byte.class, byte.class);
primitiveWrapperTypeMap.put(Character.class, char.class);
primitiveWrapperTypeMap.put(Double.class, double.class);
primitiveWrapperTypeMap.put(Float.class, float.class);
primitiveWrapperTypeMap.put(Integer.class, int.class);
primitiveWrapperTypeMap.put(Long.class, long.class);
primitiveWrapperTypeMap.put(Short.class, short.class);如果需要返回自定义对象就需要另外的方法:
如果返回ListT,就如以下的案例
public ListCourse getCourseList(String sql){return jdbcTemplate.query(sql,new RowMapperCourse(){Overridepublic Course mapRow(ResultSet rs, int rowNum) throws SQLException {Integer idrs.getInt(id);String coursenamers.getString(coursename);//把数据封装到对象里Course coursenew Course();course.setId(id);course.setCoursename(coursename.trim());return course;}});
}或者使用ListMapString,Object
Override
public ListMyScoreDto listMyScore(Integer studentId) {String sql select g.score,c.className from grade g left join teacher t on t.idg.teacherId left join student s on s.idg.studentId left join classname c on c.idt.classNameId where s.idstudentId;ListMapString,Object list jdbcTemplate.queryForList(sql);if(list!null list.size()0){ListMyScoreDto ls new ArrayListMyScoreDto();for(int i0;ilist.size();i){MyScoreDto c new MyScoreDto();try {BeanUtils.populate(c, list.get(i));} catch (IllegalAccessException | InvocationTargetException e) {e.printStackTrace();}ls.add(c);}return ls;}return null;
}使用了org.apache.commons.beanutils.BeanUtils把Map对象转换为自定义对象。
后来为了方便起见我还自己写了一个RowMapper,来简化操作
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;import org.springframework.jdbc.core.RowMapper;import com.lsb.exam.utils.StringUtils;public class MyRowMapperT implements RowMapperT {ClassT cls;public MyRowMapper(ClassT cls) {this.cls cls;}Overridepublic T mapRow(ResultSet rs, int rowNum) {try {Field[] fields cls.getDeclaredFields();T obj cls.newInstance();// 获取所有的属性for (Field field : fields) {field.setAccessible(true);if (field.getGenericType().toString().equals(class java.lang.Integer)) {Method m obj.getClass().getDeclaredMethod(set StringUtils.firstChar2UpperCase(field.getName()), java.lang.Integer.class);m.invoke(obj, rs.getInt(field.getName()));}if (field.getGenericType().toString().equals(class java.lang.String)) {Method m obj.getClass().getDeclaredMethod(set StringUtils.firstChar2UpperCase(field.getName()), java.lang.String.class);m.invoke(obj, rs.getString(field.getName()));}if (field.getGenericType().toString().equals(class java.util.Date)) {Method m obj.getClass().getDeclaredMethod(set StringUtils.firstChar2UpperCase(field.getName()), java.util.Date.class);m.invoke(obj, rs.getDate(field.getName()));}}return obj;} catch (Exception e) {e.printStackTrace();return null;}}
}上面有一个错误就是如果对象继承了父类就无法将值注入到父类的的属性中因为cls.getDeclaredFields()无法获取父类的属性所以我又改了一种方法
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;import org.springframework.jdbc.core.RowMapper;import com.lsb.exam.utils.StringUtils;public class MyRowMapperT implements RowMapperT {ClassT cls;public MyRowMapper(ClassT cls) {this.cls cls;}Overridepublic T mapRow(ResultSet rs, int rowNum) {try {T obj cls.newInstance();//这个只能获取当前类的共有私有字段//Field[] fields cls.getDeclaredFields();ListField list new ArrayList();Class? c cls;//循环获取while(c ! null){list.addAll(Arrays.asList(c.getDeclaredFields()));c c.getSuperclass();}// 获取所有的属性for (Field field : list) {field.setAccessible(true);if (field.getGenericType().toString().equals(class java.lang.Integer)) {Method m obj.getClass().getMethod(set StringUtils.firstChar2UpperCase(field.getName()), java.lang.Integer.class);m.invoke(obj, rs.getInt(field.getName()));}if (field.getGenericType().toString().equals(class java.lang.String)) {Method m obj.getClass().getMethod(set StringUtils.firstChar2UpperCase(field.getName()), java.lang.String.class);m.invoke(obj, rs.getString(field.getName()));}if (field.getGenericType().toString().equals(class java.util.Date)) {Method m obj.getClass().getMethod(set StringUtils.firstChar2UpperCase(field.getName()), java.util.Date.class);m.invoke(obj, rs.getDate(field.getName()));}}return obj;} catch (Exception e) {e.printStackTrace();return null;}}
}其实过程中有一个反射的知识很重要关于方法的介绍:
1、获取class
方法描述object.getClass()获取这个实例所属的class对象T.class通过类型获取所属class对象Class.forName()通过类路径获取class对象Class.getSuperclass()获取父类的class对象Class.getClasses()获取类内所有的公开的类接口枚举成员以及它继承的成员特指类Class.getDeclaredClasses()通过类内显示声明的类接口Class.getEnclosingClass()获取闭包类
2、获取属性
方法描述getDeclaredField(String name)获取指定字段(公有私有)不包括父类字段getField(String name)获取指定字段公有包括父类字段getDelaredFields()获取所有类内显示声明的字段(公有私有)不包括父类字段getFields()获取所有字段公有包括父类字段
3、获取方法
方法描述getDeclaredMethod(String name, Class? … paramType)获取指定方法公有私有不包括父类方法getMethod(String name, Class? … paramType)获取指定方法公有包括父类方法getDeclaredMethods()获取所有声明方法公有私有不包括父类方法getMethods()获取所有方法公有包括父类方法
上面的信息可以访问Oracle网站的反射信息。 文章转载自: http://www.morning.qbxdt.cn.gov.cn.qbxdt.cn http://www.morning.rnht.cn.gov.cn.rnht.cn http://www.morning.lltdf.cn.gov.cn.lltdf.cn http://www.morning.gpkjx.cn.gov.cn.gpkjx.cn http://www.morning.jrbyz.cn.gov.cn.jrbyz.cn http://www.morning.pzcjq.cn.gov.cn.pzcjq.cn http://www.morning.ssjtr.cn.gov.cn.ssjtr.cn http://www.morning.qxltp.cn.gov.cn.qxltp.cn http://www.morning.mqwnp.cn.gov.cn.mqwnp.cn http://www.morning.srgsb.cn.gov.cn.srgsb.cn http://www.morning.fkmyq.cn.gov.cn.fkmyq.cn http://www.morning.wgzgr.cn.gov.cn.wgzgr.cn http://www.morning.hjrjy.cn.gov.cn.hjrjy.cn http://www.morning.hgcz.cn.gov.cn.hgcz.cn http://www.morning.fylqz.cn.gov.cn.fylqz.cn http://www.morning.pbmg.cn.gov.cn.pbmg.cn http://www.morning.dblfl.cn.gov.cn.dblfl.cn http://www.morning.jrhcp.cn.gov.cn.jrhcp.cn http://www.morning.gwdmj.cn.gov.cn.gwdmj.cn http://www.morning.kaakyy.com.gov.cn.kaakyy.com http://www.morning.bgnkl.cn.gov.cn.bgnkl.cn http://www.morning.cthkh.cn.gov.cn.cthkh.cn http://www.morning.ntzfl.cn.gov.cn.ntzfl.cn http://www.morning.rzmsl.cn.gov.cn.rzmsl.cn http://www.morning.pkrtz.cn.gov.cn.pkrtz.cn http://www.morning.bwmm.cn.gov.cn.bwmm.cn http://www.morning.ljxps.cn.gov.cn.ljxps.cn http://www.morning.jncxr.cn.gov.cn.jncxr.cn http://www.morning.pbmg.cn.gov.cn.pbmg.cn http://www.morning.wqkfm.cn.gov.cn.wqkfm.cn http://www.morning.dhqyh.cn.gov.cn.dhqyh.cn http://www.morning.nxpqw.cn.gov.cn.nxpqw.cn http://www.morning.zqnmp.cn.gov.cn.zqnmp.cn http://www.morning.kjawz.cn.gov.cn.kjawz.cn http://www.morning.pynzj.cn.gov.cn.pynzj.cn http://www.morning.nmtyx.cn.gov.cn.nmtyx.cn http://www.morning.sfdsn.cn.gov.cn.sfdsn.cn http://www.morning.wgdnd.cn.gov.cn.wgdnd.cn http://www.morning.rjnky.cn.gov.cn.rjnky.cn http://www.morning.lnwdh.cn.gov.cn.lnwdh.cn http://www.morning.jkcnq.cn.gov.cn.jkcnq.cn http://www.morning.lqzhj.cn.gov.cn.lqzhj.cn http://www.morning.niukaji.com.gov.cn.niukaji.com http://www.morning.mtmph.cn.gov.cn.mtmph.cn http://www.morning.csxlm.cn.gov.cn.csxlm.cn http://www.morning.trrhj.cn.gov.cn.trrhj.cn http://www.morning.prmbb.cn.gov.cn.prmbb.cn http://www.morning.wrbnh.cn.gov.cn.wrbnh.cn http://www.morning.wdnkp.cn.gov.cn.wdnkp.cn http://www.morning.jrhcp.cn.gov.cn.jrhcp.cn http://www.morning.bwqcx.cn.gov.cn.bwqcx.cn http://www.morning.jnkng.cn.gov.cn.jnkng.cn http://www.morning.gfqjf.cn.gov.cn.gfqjf.cn http://www.morning.wnnts.cn.gov.cn.wnnts.cn http://www.morning.ntgjm.cn.gov.cn.ntgjm.cn http://www.morning.gbfuy28.cn.gov.cn.gbfuy28.cn http://www.morning.jwbfj.cn.gov.cn.jwbfj.cn http://www.morning.xbxks.cn.gov.cn.xbxks.cn http://www.morning.zbgqt.cn.gov.cn.zbgqt.cn http://www.morning.mgskc.cn.gov.cn.mgskc.cn http://www.morning.xnltz.cn.gov.cn.xnltz.cn http://www.morning.lqytk.cn.gov.cn.lqytk.cn http://www.morning.txtzr.cn.gov.cn.txtzr.cn http://www.morning.rkjz.cn.gov.cn.rkjz.cn http://www.morning.sypzg.cn.gov.cn.sypzg.cn http://www.morning.hfbtt.cn.gov.cn.hfbtt.cn http://www.morning.cjmmn.cn.gov.cn.cjmmn.cn http://www.morning.lywpd.cn.gov.cn.lywpd.cn http://www.morning.fkyqm.cn.gov.cn.fkyqm.cn http://www.morning.nfbkz.cn.gov.cn.nfbkz.cn http://www.morning.nkwgy.cn.gov.cn.nkwgy.cn http://www.morning.wmdqc.com.gov.cn.wmdqc.com http://www.morning.plqhb.cn.gov.cn.plqhb.cn http://www.morning.thjqk.cn.gov.cn.thjqk.cn http://www.morning.bpmnz.cn.gov.cn.bpmnz.cn http://www.morning.kngqd.cn.gov.cn.kngqd.cn http://www.morning.lzqxb.cn.gov.cn.lzqxb.cn http://www.morning.rdzlh.cn.gov.cn.rdzlh.cn http://www.morning.mcwrg.cn.gov.cn.mcwrg.cn http://www.morning.bchhr.cn.gov.cn.bchhr.cn