在java开发中访问数据库的框架有JPA,Mybatis,Hibernate,原生JDBC,个人都有很长使用经历.JPA,Hibernate作为纯OR框架,封装比较完整,几乎能解决所有数据访问的问题,但java语言远不如SQL使用方便灵活,差不多完全丧失了SQL灵活性.原生的JDBC使用成本稍高,灵活性很好.Mybatis作为不完全的OR映射框架,既保留了SQL的灵活,又实现部分的OR使用比较方便,近年在开发中使用的比例逐步提高.
个人认为在绝大多数项目中使用springJDBC也是一个不错的选择.以下代码针对有一定开发经验的读者,预备知识,java其础,数据库,springboot maven等
环境准备:eclipse或IDEA,mysql 搭建springboot环境
目录结构:
QQ截图20180713114748.png
pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gzz</groupId>
<artifactId>springbootjdbc</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 测试工具 (可以不用) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 谷歌工具 (可以不用) -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
</dependency>
<!-- 简化代码 (可以不用) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d[%F:%L][%p]:%m%n</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="ERROR"/>
<logger name="com.netflix" level="ERROR"/>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
只要对springJDBC稍加封装便可以得到非常灵活彪悍的基础工具类
数据访问公共类
package com.dl.notebook.common.base;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
/**
* @功能描述:dao类公共类
* @author http://www.gaozz.club
* @date 2018-07-13
*/
@Scope("prototype")
public class BaseDao {
protected final Log logger = LogFactory.getLog(BaseDao.class);
@Autowired
protected JdbcTemplate jdbcTemplate;
@Autowired
protected NamedParameterJdbcTemplate nameJdbcTemplate;
/**
* @功能描述:分页
*/
protected <T> Page<T> queryPage(String sql, BaseCondition cond, Class<T> clazz) {
String countSQL = "SELECT count(1) FROM (" + sql + ") t";
int rowCount = jdbcTemplate.queryForObject(countSQL, cond.getArray(), Integer.class);
int pageSize = cond.getSize();
int curPage = cond.getPage();
int pageCount = rowCount % pageSize == 0 ? rowCount / pageSize : rowCount / pageSize + 1;
String listSql = sql + " LIMIT " + curPage * pageSize + "," + pageSize;
List<T> dataList = jdbcTemplate.query(listSql.toString(), cond.getArray(), new BeanPropertyRowMapper<T>(clazz));
return new Page<T>(dataList, cond.getPage(), rowCount, cond.getSize(), pageCount);
}
/**
* @功能描述:批操作
*/
protected <T> int[] batchOperate(List<T> list, String sql) {
SqlParameterSource[] params = new SqlParameterSource[list.size()];
for (int i = 0; i < list.size(); i++) {
params[i] = new BeanPropertySqlParameterSource(list.get(i));
}
return nameJdbcTemplate.batchUpdate(sql, params);
}
/**
* @功能描述:插入记录反加主键
*/
protected <T> long saveKey(T t, String sql, String id) {
KeyHolder keyHolder = new GeneratedKeyHolder();
SqlParameterSource params = new BeanPropertySqlParameterSource(t);
nameJdbcTemplate.update(sql, params, keyHolder, new String[] { id });
return keyHolder.getKey().longValue();
}
}
分页工具
package com.dl.notebook.common.base;
import java.util.ArrayList;
import java.util.List;
/**
* @功能描述:分页工具
* @author http://www.gaozz.club
* @date 2018-07-13
*/
public class Page<T> {
private List<T> dataList = new ArrayList<>();// 数据列表
private int pageSize = 10;// 页大小
private long rowCount;// 记录数
private int curpage = 0;// 当前页
private int pageCount;// 总页数
public Page(List<T> dataList, int curpage, long rowCount, int pagesize, int pageCount) {
this.dataList.addAll(dataList);
this.pageSize = pagesize;
this.rowCount = rowCount;
this.curpage = curpage;
this.pageCount = pageCount;
}
public List<T> getDataList() {
return dataList;
}
public void setDataList(List<T> dataList) {
this.dataList = dataList;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public long getRowCount() {
return rowCount;
}
public void setRowCount(long rowCount) {
this.rowCount = rowCount;
}
public int getCurpage() {
return curpage;
}
public void setCurpage(int curpage) {
this.curpage = curpage;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
拼加查询条件的基础类这是非常核心的代码可以使得我的在程序中非常灵活的拼加查询条件大大简化我的开发,具体可参考测试类中的queryList
package com.dl.notebook.common.base;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @功能说明:拼加页面查询条件的基础类
* @author http://www.gaozz.club
* @date 2018-02-15
*/
public abstract class BaseCondition {
private List<Object> paramList = new ArrayList<Object>();// 参数值
private StringBuffer condition = new StringBuffer();// 条件语句
private Integer size = 10;// 页大小(每页记录条)
private Integer page = 0;// 当前页码
/**
* @功能: 拼加条件使用等于大于小于....运算符(String类型)
*/
protected void add(String value, String strSQL) {
if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件使用等于大于小于....运算符(Short类型)
*/
protected void add(Short value, String strSQL) {
if (null != strSQL && null != value && !"".equals(strSQL)) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
protected void add(Byte value, String strSQL) {
if (null != strSQL && null != value && !"".equals(strSQL)) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件使用等于大于小于....运算符(String类型)
*/
protected void add(Float value, String strSQL) {
if (null != strSQL && null != value && !"".equals(strSQL)) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件使用等于大于小于....运算符(Long类型)
*/
protected void add(Long value, String strSQL) {
if (null != strSQL && null != value && !"".equals(strSQL)) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件使用等于大于小于....运算符(Boolean类型)
*/
protected void add(Boolean value, String strSQL) {
if (null != strSQL && null != value && !"".equals(strSQL)) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件使用等于大于小于....运算符(BigDecimal类型)
*/
protected void add(BigDecimal value, String strSQL) {
if (null != strSQL && null != value && !"".equals(strSQL)) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件使用等于大于小于....运算符(Integer类型)
*/
protected void add(Integer value, String strSQL) {
if (null != value && !"".equals(strSQL) && null != strSQL) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件使用等于大于小于....运算符(Date类型)
*/
protected void add(Date value, String strSQL) {
if (null != value && !"".equals(strSQL) && null != strSQL) {
condition.append(" " + strSQL);
paramList.add(value);
}
}
/**
* @功能: 拼加条件
*/
protected void add(String strSQL) {
if (null != strSQL && !"".equals(strSQL)) {
condition.append(" " + strSQL);
}
}
/**
* @功能: 拼加条件
*/
protected void add(List<?> ids, String strSQL) {
if (null != strSQL && !"".equals(strSQL) && ids != null && ids.size() > 0) {
condition.append(" " + strSQL + SqlUtil.ArrayToIn(ids));
}
}
/**
* @param value
* :属性名称
* @param strSQL
* :参数SQL字符
* @param posLike
* :字句中百分号出现位置
* @return strSQL:拼加后SQL字符包括占位符
* @功能: 拼加条件使用like关键字模糊查询时
*/
protected void add(String value, String strSQL, int pos) {
if (null != strSQL && null != value && !"".equals(strSQL) && !"".equals(value)) {
condition.append(" " + strSQL);
if (pos == 1) {
paramList.add("%" + value);
} else if (pos == 2) {
paramList.add(value + "%");
} else if (pos == 3) {
paramList.add("%" + value + "%");
}
}
}
/**
* @功能: 将List转为数组
*/
public Object[] getArray() {
return paramList.toArray();
}
/**
* @功能: 取条件字符串
*/
public String getCondition() {
// 清除查询条件
condition.setLength(0);
paramList.clear();
addCondition();
return condition.toString();
}
/**
* @功能: 拼加条件方法
*/
public abstract void addCondition();
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
}
代码工具
package com.dl.notebook.common.base;
import java.text.SimpleDateFormat;
import java.util.List;
import com.google.common.base.Joiner;
/**
* @功能描述:代码工具
* @author http://www.gaozz.club
* @date 2018-07-13
*/
public class SqlUtil {
/**
* @方法说明:数据库中执行的SQL语句
*/
public static String showSql(String sql, Object[] obj) {
String param;
for (int j = 0; null != obj && j < obj.length; j++) {
param = "null";
if (null != obj[j]) {
String cname = obj[j].getClass().getName();
if (cname.contains("Date") || cname.contains("Timestamp")) {
param = "'" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(obj[j]) + "'";
} else if (cname.contains("String")) {
param = "'" + (String) obj[j] + "'";
} else {
param = obj[j].toString();
}
}
sql = sql.replaceFirst("[?]", param);
}
return sql;
}
/**
* @方法说明:把组数拼接成IN语句
*/
public static String ArrayToIn(Long ids[]) {
return new StringBuffer(" IN (").append(Joiner.on(",").join(ids)).append(")").toString();
}
/**
* @方法说明:把组数拼接成IN语句
*/
public static String ArrayToIn(Integer ids[]) {
return new StringBuffer(" IN (").append(Joiner.on(",").join(ids)).append(")").toString();
}
/**
* @方法说明:把组数拼接成IN语句
*/
public static String ArrayToIn(String ids[]) {
return new StringBuffer(" IN ('").append(Joiner.on("','").join(ids)).append("')").toString();
}
/**
* @方法说明:把List拼接成IN语句(数值型)
*/
public static String ArrayToIn(List<?> ids) {// 数值IN字符窜
return new StringBuffer(" ('").append(Joiner.on("','").join(ids)).append("')").toString();
}
}
至此我们的准备工作已完成下次我们来编写业务代码。
网友评论