Conventiondao是基于Spring Jdbc、Freemarker以及一些约定的规则而实现的O/R Mapping 框架,只要简单的配置一下DTO与数据库表之间的对应关系就可以拥有这个数据库表的增删、改查等功能。
约定
字段名和pojo属性的对应,camel case(驼峰表示法),例如:表字段user_name 对应 Pojo的userName
表主键对应pojo的id(每个表只允许有一个主键)
配置文件
dao.properties
# id主键生成策略: # id_table, 生成的一个数据表, 用来存放全局自增长的id # uuid, java 生成的唯一的32位id, 推荐 # none, 或不配置, 那么没有任何策略被使用, 这个时候应该使用数据自身的策略,如 mysql的自增长主键,oralce的序列等 idGenerator=uuid # java属性和数据库字段的转换策略 conventionStrategy=com.rework.joss.persistence.convention.APPConventionStrategy # pojo中关于createdate和updatedate的字段名 createdateProperty=createdate updatedateProperty=updatedate #如果debug为true那么每次都重新加载sqlmap debug=true
sqlmap文件
为了避免java代码中充斥了大量的sql代码,同时也为了维护方便,于是引入sqlmap文件的概念,统一在这个文件中配置sql代码,类似Mybatis的mapper.xml文件。
格式说明:key=sql; 一定要以分号结尾。
sqlmap默认位置,与DAO在同一目录,文件后缀.sqlmap,命名与DAO名称一致。
sqlmap语法:freemarker
例:
select * from gy_user where username = #${username}# //可自定义sqlmap文件位置,配置属性mappingFile @DAO(pojo=TestDTO.class, table="dao_test", mappingFile="/com/rework/test/test.sqlmap")
查询
普通查询
1. public List query()
返回:处理后的结果集
2. public BaseObject queryForBaseObject(Object pojoOrMap)
返回:查询对象 参数: pojoOrMap:封装查询属性条件,如果是map,注意key值为DTO属性值
注意:如果查询出多条符合条件的数据则报错 org.springframework.dao.IncorrectResultSizeDataAccessException
3. public Object queryForBaseObjectByTpl(String sqlTemplate, Object paramObject)
返回:查询对象 参数: sqlTemplate:自己的查询sql paramObject:封装查询条件,推荐map形式
4. public List queryForListByTpl(String sqlTemplate, Object paramObject, Class requireType)
返回:满足条件的结果集合 参数: sqlTemplate:自己的查询sql paramObject:封装的查询参数,使用map即可 requireType: 如果返回LIst要加泛型指定类型,使用null,否则可使用Map.class,可以将查询结果按表字段-字段值形式封装到对象中
5. public List queryByTpl(String sqlTemplate)
返回:满足条件的结果集合 参数: sqlTemplate: 自己的查询sql
6. public List queryByTpl(String sqlTemplate, Object paramObject)
返回:满足条件的结果集合 参数: sqlTemplate:自己的查询sql paramObject: 封装查询参数,推荐用map
7. public List queryByTpl(String sqlTemplate, Object paramObject, Map paramMap)
返回:满足条件的结果集合 参数: sqlTemplate: 自己的查询sql paramObject: DTO中有的属性可封装成查询对象 paramMap:需要的其他查询条件使用map
8. public List queryByTpl(String sqlTemplate, int begin, int interval)
返回: 满足条件的结果集合的指定部分 参数: sqlTemplate:自己的查询sql begin:开始条数(从0开始) interval: 间隔(截取几条)
9.public List queryByTpl(String sqlTemplate, Object paramObject, int begin, int end)
返回: 满足条件的结果集合的指定部分 参数: sqlTemplate:自己的查询sql paramObject: 封装查询条件 begin: 开始条数 end:截取几条(间隔)
查询数量
1. public Integer queryCountByTpl(String sqlTemplate, Object paramObject)
返回:查询结果数 参数: sqlTemplate:查询数量sql语句,如果不是SELECT开头语句会强制转换 paramObject:参数对象,建议传参数map(可使用ConventionUtils的toMap方法)map中key为sqlmap中freemaker语法¥{}中值,value为参数
2. public Integer queryCountByTpl(String sqlTemplate, Object... paramObject)
返回:查询结果数 参数: sqlTemplate: 查询数量sql语句 Object... paramObject:可变参数,依次填入参数名称,参数值,形成参数数组,底层使用ConventionUtils.toMap()方法转换
3. public Integer queryCountByTpl(String sqlTemplate)
返回:查询结果数 参数: sqlTemplate: 查询数量sql语句 没有查询条件,实际调用queryForObjectByTpl(sqlTemplate, (Object) null, Integer.class)
保存
1. public void create(BaseObject dto)
参数: BaseObject dto:需要保存的DTO对象 如果DTO没有设主键id值且配置文件中配置了主键生成策略,则会自动生成主键
2. public void create(BaseObject[] dtos) // 批量插入方法
3. public String createAndId(BaseObject dto)
返回: 保存DTO后生成的主键id 参数: BaseObject dto: 需要保存的DTO对象删除
删除
1. public void remove(String id)
参数: id: 删除DTO对象的主键id
2. public void remove(String[] ids) //批量删除
参数: ids: 主键id数组
3. public int removeByCondition(BaseObject dto) //根据DTO中的属性删除
参数: BaseObject dto: 将删除依据的属性封到DTO中,实际调用excuteUpdate("remove", dto, true) 底层将根据DTO中封装的属性拼装sql语句执行
4. public int removeByCondition(Map paramMap)
参数: Map paramMap:将删除条件封装到map中,实际调用toPojo()方法,使用方法3更为灵活, 注意:map的key值为DTO属性名,如果传入key值在属性中不存在,则不拼删除条件造成 全表删除,相当与方法3传入空对象
更新
11. public int update(BaseObject dto)
返回: 受影响的行数 参数: BaseObject dto:更新的属性封装到DTO,属性不能为空,否则报错,必须包含主键id作 为识别标志
12. public int update(Map beanMap)
返回: 受影响的行数 参数: beanMap:参数map,实际调用excuteUpdate(String sqlMapKey, Object dto, boolean isEmpty)
13. public int updateByTpl(String sqlTemplate, Object paramObject)
返回: 受影响的行数 参数: sqlTemplate:自己的SQL更新语句 paramObject:参数对象,推荐使用map封装参数,key对应sqlmap中freemarker语法所取值,value为参数,参数顺序随意
14. public void updateByTpl(String sqlTemplate, Object... paramObjects)
参数: sqlTemplate:自己的SQL更新语句 paramObjects: 可变参数,实际会通过ConventionUtils.toMap()方法转成map,使用方法13
完整示例
// 确定表和DTO对象的依赖关系 @DAO(table = "jw_course_manage", pojo = CourseManageDTO.class) public class CourseManageDAO extends AbstractConventionDAO{ public int getCountByTsqk(String tsqk) { return queryCountByTpl("getCountByTsqk","tsqk",tsqk); } } //在sqlmap中编写sqlTemplate,注意以;结尾 CourseManageDAO.sqlmap getCountByTsqk = select count(course_manage_id) from jw_course_manage where tsqk=#${tsqk}#; //测试,使用spring测试框架 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:conf/AppApplicationContext.xml") public class Test { @Autowired private CourseDAO courseDAO; @Autowired private CourseManageDAO dao; @org.junit.Test public void test() { int counts = dao.getCountByTsqk("单双周"); System.out.println(counts); } //参考: jdbcTemplate /*实现方式:DAO的实现类继承JdbcDaoSupport类(对jdbcTemplate进行重构和封装),获得jdbcTemplate对数据库操作的方法 ConventionDao框架中加入了对参数的处理,结果集的处理,以约定的形式实现O/Rmapping 具体可看源码研究 */ public class CourseManageDAO extends AbstractConventionDAO public class AbstractConventionDAO extends BaseDAOByConvention public class BaseDAOByConvention extends JdbcDaoSupport implements IBaseDAO //方法 1. 增删改操作 public int update(String sql, Object... args) //------>调用public int update(String sql ,PreparedStatementSetter pss) //------>调用protected int update(final PreparedStatementCreator psc, // final PreparedStatementSetter pss) //------>调用public <T> T execute(PreparedStatementCreator psc,PreparedStatementCallback<T> action) //------> 基本JDBC操作 public void update(Student stu) { super.getJdbcTemplate().update("update stu set name=?,age=? where id=?",stu.getName(),stu.getAge(),stu.getId()); } //2. 查询操作 public <T> T queryForObject(String sql, Object[] args, RowMapper<T> rowMapper) public <T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper) //case 1: public Student get(int id) { //找不到时会报错 return super.getJdbcTemplate().queryForObject("select id,name,age from stu where id=?", new Object[] {id}, new RowMapper<Student>() { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student stu = new Student(); stu.setId(rs.getInt("id")); stu.setName(rs.getString("name")); stu.setAge(rs.getInt("age")); return stu; } }); } //case 2: public Student get(int id) { List<Student> list = jdbcTemplate.query("select id,name,age from stu where id=?", new Object[] {id}, new RowMapper<Student>() { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student stu = new Student(); stu.setId(rs.getInt("id")); stu.setName(rs.getString("name")); stu.setAge(rs.getInt("age")); return stu; } }); return list.size()==1?list.get(0):null; } //case 3: public List<Student> listAll() { return super.getJdbcTemplate().query("select * from stu", new Object[] {}, new RowMapper<Student>() { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student stu = new Student(); stu.setId(rs.getInt("id")); stu.setName(rs.getString("name")); stu.setAge(rs.getInt("age")); return stu; } }); } //--->public <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse) //--->public <T> T query(String sql, PreparedStatementSetter pss, ResultSetExtractor<T> rse) //--->public <T> T query(PreparedStatementCreator psc,final PreparedStatementSetter pss , // final ResultSetExtractor<T> rse) //--->public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action) //------>JDBC查询