1.注解
package com.seesource.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
/**
* 映射在数据表中的字段名
* @return
*/
public String value() default "";
}
package com.seesource.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 主键标识
* @author Administrator
*
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
}
package com.seesource.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 主键生成策略
* @author Administrator
*
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Strategy {
int value() default StrategyType.INCREMENT;
}
package com.seesource.annotation;
public interface StrategyType {
int ASSIGNED = 0; //由程序提供
int INCREMENT = 1; //自增(不需要提供)
}
package com.seesource.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
/**
* 映射到数据库中的数据表名
* @return
*/
public String value() default "";
}
dao实现
package com.seesource.dao;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public interface DataSourceFactory {
public DataSource createDataSource();
}
package com.seesource.dao;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import javax.naming.NamingException;
import com.seesource.annotation.Column;
import com.seesource.annotation.Id;
import com.seesource.annotation.Strategy;
import com.seesource.annotation.StrategyType;
import com.seesource.annotation.Table;
import com.seesource.exception.NotDefineColumnException;
import com.seesource.exception.NotDefinePrimaryKeyException;
import com.seesource.exception.NotDefineTableException;
public class GenericDao<T> {
private Class clazz;
private String table;//数据库表名
private ColumnItem id;//主键字段名
private int strategy = StrategyType.INCREMENT;//主键生成策略
//String:字段名 Field:相应的实体get方法
private List<ColumnItem> columns = new ArrayList<ColumnItem>();
private static ThreadLocal tansaction_connecton_map = new ThreadLocal();
private DataSourceFactory dataSourceFactory;
/**
* 获得参数T的实际类型
* @return
*/
private Class getGenericType() {
Class clazz = getClass();
Type genType = clazz.getGenericSuperclass();
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
return (Class) params[0];
}
/**
* 初始化
*/
public void init()throws NotDefineTableException,NotDefineColumnException,NotDefinePrimaryKeyException,Exception{
Class clazz = getGenericType();
this.clazz = clazz;
Table ta = (Table)clazz.getAnnotation(Table.class);
if(ta == null || ta.value().trim().equals(""))
throw new NotDefineTableException(this.clazz.toString() + "----未设置表名!");
this.table = ta.value();
for (Field f : clazz.getDeclaredFields()) {
Column anno = f.getAnnotation(Column.class);
if (anno != null) {
String columnName = anno.value();
if(columnName == null || columnName.trim().equals(""))
throw new NotDefineColumnException(f.getName() + "----未设置字段名!");
ColumnItem column = new ColumnItem(columnName, f, new PropertyDescriptor(f.getName(), this.clazz));
//判断是否是主键
Id idAnno = f.getAnnotation(Id.class);
if(idAnno != null){
this.id = column; //获得主键
Strategy strategyAnno = f.getAnnotation(Strategy.class);
if(strategyAnno != null)//获得主键生成策略
this.strategy = strategyAnno.value();
continue;
}
columns.add(column);
}else{
throw new NotDefineColumnException(f.getName() + "----未设置字段名!");
}
}
if(this.id == null)
throw new NotDefinePrimaryKeyException(this.clazz.toString() + "----未设置主键!");
}
/**
* 添加记录
* @param rec
* @return
* @throws SQLException
*/
public int save(T entity) throws Exception {
List<Object> params = new ArrayList<Object>();
StringBuffer sb = new StringBuffer("INSERT INTO ");
StringBuffer sb_values = new StringBuffer();
sb.append(this.table);
sb.append(" (");
if(this.strategy == StrategyType.ASSIGNED){
PropertyDescriptor pd = this.id.propertyDescriptor;
Method getMethod = pd.getReadMethod();
Object value = getMethod.invoke(entity);
sb.append(this.id.columnName);
sb.append(",");
sb_values.append("?,");
params.add(value);
}
for (ColumnItem entry : columns) {
PropertyDescriptor pd = entry.propertyDescriptor;
Method getMethod = pd.getReadMethod();
Object value = getMethod.invoke(entity);
if(value == null)//不对空值进行操作
continue;
sb.append(entry.columnName);
sb.append(",");
params.add(value);
sb_values.append("?,");
}
sb.deleteCharAt(sb.length() - 1);
sb_values.deleteCharAt(sb_values.length() - 1);
sb.append(") VALUES (");
sb.append(sb_values.toString());
sb.append(')');
Connection con = null;
PreparedStatement stmt = null;
con = getConnection();
stmt = con.prepareStatement(sb.toString());
setParams(stmt, params.toArray());
int nums = stmt.executeUpdate(); //返回受影响的行数
closeStatement(stmt);
closeConnection(con);
return nums;
}
/**
* 修改
* @param sql
* @param params
* @return
*/
public int update(T entity) throws Exception {
StringBuilder sb = new StringBuilder("UPDATE ");
sb.append(this.table);
sb.append(" SET ");
List<Object> paramList = new ArrayList<Object>();
for (ColumnItem entry : columns) {
Field field = entry.theField;
PropertyDescriptor pd = entry.propertyDescriptor;
Method getMethod = pd.getReadMethod();
Object value = getMethod.invoke(entity);
sb.append(entry.columnName);
sb.append(" = ?,");
paramList.add(value);
}
sb.deleteCharAt(sb.length() - 1);
sb.append(" WHERE ");
sb.append(this.id.columnName);
sb.append(" = ?");
PropertyDescriptor pd = this.id.propertyDescriptor;
Method getMethod = pd.getReadMethod();
Object value = getMethod.invoke(entity);
paramList.add(value);
Connection con = null;
PreparedStatement stmt = null;
con = getConnection();
stmt = con.prepareStatement(sb.toString());
setParams(stmt, paramList.toArray());
int nums = stmt.executeUpdate(); //返回受影响的行数
closeStatement(stmt);
closeConnection(con);
return nums;
}
/**
* 删除
* @param sql
* @param params
* @return
*/
public int delete(T entity) throws Exception {
StringBuilder sb = new StringBuilder("delete from ");
sb.append(this.table);
sb.append(" where ");
sb.append(this.id.columnName);
sb.append(" = ?");
PropertyDescriptor pd = this.id.propertyDescriptor;
Method getMethod = pd.getReadMethod();
Object value = getMethod.invoke(entity);
Object[] params = new Object[1];
params[0] = value;
Connection con = null;
PreparedStatement stmt = null;
con = getConnection();
stmt = con.prepareStatement(sb.toString());
setParams(stmt, params);
int nums = stmt.executeUpdate(); //返回受影响的行数
closeStatement(stmt);
closeConnection(con);
return nums;
}
/**
* 查询
* @param sql
* @param params
* @return
*/
public List<T> find(String sql, Object[] params){
List<T> list = new ArrayList<T>();
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
con = this.getConnection();
stmt = con.prepareStatement(sql);
setParams(stmt, params);
rs = stmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while(rs != null && rs.next()){
T entity = (T)this.clazz.newInstance();
for(int i = 0; i<columnCount; i++){
String columnName = rsmd.getColumnName(i+1);
ColumnItem columnItem = getColumnItem(columnName);
if(columnItem != null){
PropertyDescriptor pd = columnItem.propertyDescriptor;
Method setMethod = pd.getWriteMethod();
Object value = rs.getObject(columnName);
setMethod.invoke(entity, value);
}
}
list.add(entity);
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
closeResultSet(rs);
closeStatement(stmt);
closeConnection(con);
}
return list;
}
/**
* 通过主键获得单个实例
* 如果库中无此实例,则返回null
* @param entity
* @return
*/
public T get(T entity)throws Exception{
StringBuffer sb = new StringBuffer("select * from ");
sb.append(this.table);
sb.append(" where ");
sb.append(this.id.columnName);
sb.append(" = ?");
PropertyDescriptor pd = this.id.propertyDescriptor;
Method getMethod = pd.getReadMethod();
Object id_value = getMethod.invoke(entity);
Object[] params = new Object[1];
params[0] = id_value;
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
con = this.getConnection();
stmt = con.prepareStatement(sb.toString());
setParams(stmt, params);
rs = stmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
if(rs != null && rs.next()){
for(int i = 0; i<columnCount; i++){
String columnName = rsmd.getColumnName(i+1);
ColumnItem columnItem = getColumnItem(columnName);
if(columnItem != null){
pd = columnItem.propertyDescriptor;
Method setMethod = pd.getWriteMethod();
Object value = rs.getObject(columnName);
setMethod.invoke(entity, value);
}
}
return entity;
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
closeResultSet(rs);
closeStatement(stmt);
closeConnection(con);
}
return null;
}
/**
* 统计数量
* @param sql
* @param params
* @return
*/
public long count(String sql, Object[] params){
long count = 0;
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
con = this.getConnection();
stmt = con.prepareStatement(sql);
setParams(stmt, params);
rs = stmt.executeQuery();
if(rs != null && rs.next()){
count = rs.getLong(1);
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
closeResultSet(rs);
closeStatement(stmt);
closeConnection(con);
}
return count;
}
/**
* 判断实体注解配置中是否有此字段
* @param columnName
* @return
*/
private ColumnItem getColumnItem(String columnName){
if(this.id.columnName.equals(columnName))
return this.id;
for(int i = 0; i<this.columns.size(); i++){
ColumnItem item = this.columns.get(i);
if(columnName.equals(item.columnName))
return item;
}
return null;
}
/**
* 关闭ResultSet
* @param rs
*/
protected void closeResultSet(ResultSet rs){
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 关闭Statement
* @param stmt
*/
protected void closeStatement(Statement stmt){
try {
if(stmt != null){
stmt.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 归还连接
* @param con
*/
public void closeConnection(Connection con){
try {
Object obj = tansaction_connecton_map.get();
if(obj == null && con != null){ //不在事务控制中时直接关闭
con.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 开启事务
* @return
*/
public void startTransaction()throws SQLException,NamingException{
Connection con = createConnection();
con.setAutoCommit(false);
tansaction_connecton_map.set(con);
}
/**
* 提交事务
* @return
*/
public void commit()throws SQLException{
Object obj = tansaction_connecton_map.get();
if(obj != null){
Connection con = (Connection)obj;
con.commit();
}
}
/**
* 回滚事务
* @return
*/
public void rollback(){
try {
Object obj = tansaction_connecton_map.get();
if(obj != null){
Connection con = (Connection)obj;
con.rollback();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 销毁事务,释放连接
* @return
* @throws SQLException
* @throws NamingException
*/
public void distroyTransaction(){
try {
Object obj = tansaction_connecton_map.get();
if(obj != null){
Connection con = (Connection)obj;
con.setAutoCommit(true);
con.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
tansaction_connecton_map.set(null);
}
}
private Connection createConnection() throws SQLException, NamingException{
Connection con = this.dataSourceFactory.createDataSource().getConnection();
return con;
}
/**
* 获得数据库连接
* @return
* @throws SQLException
* @throws NamingException
*/
public Connection getConnection() throws SQLException, NamingException{
Connection con = null;
Object obj = tansaction_connecton_map.get();
if(obj != null){
con = (Connection)obj;
}else{
con = createConnection();
}
return con;
}
/**
* 设置参数
* @param stmt
* @param params
* @throws SQLException
*/
protected void setParams(PreparedStatement stmt, Object[] params) throws SQLException{
for(int i = 0; i<params.length;){//int, short, long, float, double, boolean, byte, char, List
if(params[i] == null){
stmt.setObject(i+1, null);
i++;
continue;
}
if(params[i] instanceof String){
stmt.setString(i+1, (String)params[i]);
i++;
continue;
}
if(params[i] instanceof Integer){
stmt.setInt(i+1, (Integer)params[i]);
i++;
continue;
}
if(params[i] instanceof Short){
stmt.setShort(i+1, (Short)params[i]);
i++;
continue;
}
if(params[i] instanceof Long){
stmt.setLong(i+1, (Long)params[i]);
i++;
continue;
}
if(params[i] instanceof Float){
stmt.setFloat(i+1, (Float)params[i]);
i++;
continue;
}
if(params[i] instanceof Double){
stmt.setDouble(i+1, (Double)params[i]);
i++;
continue;
}
if(params[i] instanceof Date){
stmt.setDate(i+1, (Date)params[i]);
i++;
continue;
}
if(params[i] instanceof Timestamp){
stmt.setTimestamp(i+1, (Timestamp)params[i]);
i++;
continue;
}
if(params[i] instanceof Boolean){
stmt.setBoolean(i+1, (Boolean)params[i]);
i++;
continue;
}
if(params[i] instanceof Byte){
stmt.setByte(i+1, (Byte)params[i]);
i++;
continue;
}
}
}
public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
this.dataSourceFactory = dataSourceFactory;
}
class ColumnItem{
public ColumnItem(String columnName, Field theField, PropertyDescriptor propertyDescriptor){
this.columnName = columnName;
this.theField = theField;
this.propertyDescriptor = propertyDescriptor;
}
String columnName;
Field theField;
PropertyDescriptor propertyDescriptor;
}
}
exception实现
package com.seesource.exception;
public class NotDefineColumnException extends Exception{
public NotDefineColumnException(){
super("未设置字段名!");
}
public NotDefineColumnException(String msg){
super(msg);
}
}
package com.seesource.exception;
/**
* 未定义主键异常
* @author Administrator
*
*/
public class NotDefinePrimaryKeyException extends Exception{
public NotDefinePrimaryKeyException(){
super("未定义主键");
}
public NotDefinePrimaryKeyException(String msg){
super(msg);
}
}
package com.seesource.exception;
public class NotDefineTableException extends Exception{
public NotDefineTableException(){
super("未设置表名!");
}
public NotDefineTableException(String msg){
super(msg);
}
}
如何使用:
package com.seesource.persist;
import java.sql.Date;
import java.sql.Timestamp;
import com.seesource.annotation.Column;
import com.seesource.annotation.Id;
import com.seesource.annotation.Strategy;
import com.seesource.annotation.StrategyType;
import com.seesource.annotation.Table;
@Table("user")
public class User {
@Column("id_")
@Id
@Strategy(StrategyType.INCREMENT)
private int id;
@Column("name_")
private String name;
@Column("date_")
private Timestamp date;
public Timestamp getDate() {
return date;
}
public void setDate(Timestamp date) {
this.date = date;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.seesource.dao;
import com.seesource.persist.User;
public class UserDao extends GenericDao<User>{
}
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import com.seesource.dao.DataSourceFactory;
public class MyDataSourceFactory implements DataSourceFactory{
private DataSource dataSource;
public MyDataSourceFactory()throws SQLException, NamingException{
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/xinwei");
this.dataSource = ds;
System.out.println("------------------------------已经创建了dataSource-----------------------------------------");
}
public DataSource createDataSource(){
return this.dataSource;
}
}
场景1(增加记录)
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
UserDao dao = new UserDao();
DataSourceFactory dataSource = new MyDataSourceFactory();
dao.setDataSourceFactory(dataSource);
dao.init();
User entity = new User();
entity.setName("张三");
entity.setDate(new java.sql.Timestamp(new java.util.Date().getTime()));
dao.save(entity);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
场景2(查询)
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
UserDao dao = new UserDao();
DataSourceFactory dataSource = new MyDataSourceFactory();
dao.setDataSourceFactory(dataSource);
dao.init();
String sql = "select * from user";
List<User> users = dao.find(sql, new Object[0]);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
场景3(业务级事务)
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
UserDao dao = new UserDao();
try {
DataSourceFactory dataSource = new MyDataSourceFactory();
dao.setDataSourceFactory(dataSource);
dao.init();
dao.startTransaction();//开始事务
User entity = new User();
entity.setId(8);
entity.setName("张三");
entity.setDate(new java.sql.Timestamp(new java.util.Date().getTime()));
int rat = dao.update(entity);
if(rat == 0){
dao.rollback();
}else{
rat = dao.delete(entity);
if(rat == 0){
dao.rollback();
}else{
dao.commit();//提交事务
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
dao.rollback();
}finally{
dao.distroyTransaction();//销毁事务
}
}