手写 | mybatis框架
定义的注解
@Documented
@Target ( ElementType. METHOD )
@Retention ( RetentionPolicy. RUNTIME )
public @interface ExtInsert {
String value ( ) ;
}
@Documented
@Target ( ElementType. PARAMETER )
@Retention ( RetentionPolicy. RUNTIME )
public @interface ExtParam {
String value ( ) ;
}
@Documented
@Retention ( RetentionPolicy. RUNTIME )
@Target ( ElementType. METHOD )
public @interface ExtSelect {
String value ( ) ;
}
Dao层接口:
public interface UserDao {
@ExtInsert ( "insert into t_users(userName,userAge) values(#{userName},#{userAge})" )
public int insertUser ( @ExtParam ( "userName" ) String userName, @ExtParam ( "userAge" ) Integer userAge) ;
@ExtSelect ( "select * from User where userName=#{userName} and userAge=#{userAge} " )
void selectUser ( @ExtParam ( "userName" ) String name, @ExtParam ( "userAge" ) Integer userAge) ;
}
加载了mapper接口
public class SqlSession {
public static < T > T getMepper ( Class classz ) {
return ( T ) Proxy. newProxyInstance ( classz. getClassLoader ( ) , new Class [ ] { classz } , new MyIvocationHandler ( classz) ) ;
}
}
public class MyInvocationHandlerMbatis implements InvocationHandler {
private Object object;
public MyInvocationHandlerMbatis ( Object object) {
this . object = object;
}
public Object invoke ( Object proxy, Method method, Object[ ] args) throws Throwable {
System. out. println ( "使用动态代理技术拦截接口方法开始" ) ;
ExtInsert extInsert = method. getDeclaredAnnotation ( ExtInsert. class ) ;
if ( extInsert != null ) {
return extInsert ( extInsert, proxy, method, args) ;
}
ExtSelect extSelect = method. getDeclaredAnnotation ( ExtSelect. class ) ;
if ( extSelect != null ) {
String selectSQL = extSelect. value ( ) ;
ConcurrentHashMap< Object, Object> paramsMap = paramsMap ( proxy, method, args) ;
List< String> sqlSelectParameter = SQLUtils. sqlSelectParameter ( selectSQL) ;
List< Object> sqlParams = new ArrayList < > ( ) ;
for ( String parameterName : sqlSelectParameter) {
Object parameterValue = paramsMap. get ( parameterName) ;
sqlParams. add ( parameterValue) ;
}
String newSql = SQLUtils. parameQuestion ( selectSQL, sqlSelectParameter) ;
System. out. println ( "newSQL:" + newSql + ",sqlParams:" + sqlParams. toString ( ) ) ;
ResultSet res = JDBCUtils. query ( newSql, sqlParams) ;
if ( ! res. next ( ) ) {
return null ;
}
res. previous ( ) ;
Class< ? > returnType = method. getReturnType ( ) ;
Object object = returnType. newInstance ( ) ;
while ( res. next ( ) ) {
Field[ ] declaredFields = returnType. getDeclaredFields ( ) ;
for ( Field field : declaredFields) {
String fieldName = field. getName ( ) ;
Object fieldValue = res. getObject ( fieldName) ;
field. setAccessible ( true ) ;
field. set ( object, fieldValue) ;
}
}
return object;
}
return null ;
}
private Object extInsert ( ExtInsert extInsert, Object proxy, Method method, Object[ ] args) {
String insertSql = extInsert. value ( ) ;
ConcurrentHashMap< Object, Object> paramsMap = paramsMap ( proxy, method, args) ;
String[ ] sqlInsertParameter = SQLUtils. sqlInsertParameter ( insertSql) ;
List< Object> sqlParams = sqlParams ( sqlInsertParameter, paramsMap) ;
String newSQL = SQLUtils. parameQuestion ( insertSql, sqlInsertParameter) ;
System. out. println ( "newSQL:" + newSQL + ",sqlParams:" + sqlParams. toString ( ) ) ;
return JDBCUtils. insert ( newSQL, false , sqlParams) ;
}
private List< Object> sqlParams ( String[ ] sqlInsertParameter, ConcurrentHashMap< Object, Object> paramsMap) {
List< Object> sqlParams = new ArrayList < > ( ) ;
for ( String paramName : sqlInsertParameter) {
Object paramValue = paramsMap. get ( paramName) ;
sqlParams. add ( paramValue) ;
}
return sqlParams;
}
private ConcurrentHashMap< Object, Object> paramsMap ( Object proxy, Method method, Object[ ] args) {
ConcurrentHashMap< Object, Object> paramsMap = new ConcurrentHashMap < > ( ) ;
Parameter[ ] parameters = method. getParameters ( ) ;
for ( int i = 0 ; i < parameters. length; i++ ) {
Parameter parameter = parameters[ i] ;
ExtParam extParam = parameter. getDeclaredAnnotation ( ExtParam. class ) ;
if ( extParam != null ) {
String paramName = extParam. value ( ) ;
Object paramValue = args[ i] ;
paramsMap. put ( paramName, paramValue) ;
}
}
return paramsMap;
}
public Object extInsertSQL ( ) {
return object;
}
}
工具类:
package com. sym. Util;
import java. sql. * ;
import java. util. List;
public final class JDBCUtils {
private static String connect;
private static String driverClassName;
private static String URL ;
private static String username;
private static String password;
private static boolean autoCommit;
private static Connection conn;
static {
config ( ) ;
}
private static void config ( ) {
driverClassName = "com.mysql.jdbc.Driver" ;
URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8" ;
username = "root" ;
password = "123456" ;
autoCommit = false ;
}
private static boolean load ( ) {
try {
Class. forName ( driverClassName) ;
return true ;
} catch ( ClassNotFoundException e) {
System. out. println ( "驱动类 " + driverClassName + " 加载失败" ) ;
}
return false ;
}
private static boolean invalid ( ) {
if ( conn != null ) {
try {
if ( conn. isClosed ( ) || ! conn. isValid ( 3 ) ) {
return true ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
return false ;
} else {
return true ;
}
}
public static Connection connect ( ) {
if ( invalid ( ) ) {
load ( ) ;
try {
conn = DriverManager. getConnection ( URL , username, password) ;
} catch ( SQLException e) {
System. out. println ( "建立 " + connect + " 数据库连接失败 , " + e. getMessage ( ) ) ;
}
}
return conn;
}
public static void transaction ( ) {
try {
conn. setAutoCommit ( autoCommit) ;
} catch ( SQLException e) {
System. out. println ( "设置事务的提交方式为 : " + ( autoCommit ? "自动提交" : "手动提交" ) + " 时失败: " + e. getMessage ( ) ) ;
}
}
public static Statement statement ( ) {
Statement st = null ;
connect ( ) ;
transaction ( ) ;
try {
st = conn. createStatement ( ) ;
} catch ( SQLException e) {
System. out. println ( "创建 Statement 对象失败: " + e. getMessage ( ) ) ;
}
return st;
}
private static PreparedStatement prepare ( String SQL , boolean autoGeneratedKeys) {
PreparedStatement ps = null ;
connect ( ) ;
transaction ( ) ;
try {
if ( autoGeneratedKeys) {
ps = conn. prepareStatement ( SQL , Statement. RETURN_GENERATED_KEYS ) ;
} else {
ps = conn. prepareStatement ( SQL ) ;
}
} catch ( SQLException e) {
System. out. println ( "创建 PreparedStatement 对象失败: " + e. getMessage ( ) ) ;
}
return ps;
}
public static ResultSet query ( String SQL , List< Object> params) {
if ( SQL == null || SQL . trim ( ) . isEmpty ( ) || ! SQL . trim ( ) . toLowerCase ( ) . startsWith ( "select" ) ) {
throw new RuntimeException ( "你的SQL语句为空或不是查询语句" ) ;
}
ResultSet rs = null ;
if ( params. size ( ) > 0 ) {
PreparedStatement ps = prepare ( SQL , false ) ;
try {
for ( int i = 0 ; i < params. size ( ) ; i++ ) {
ps. setObject ( i + 1 , params. get ( i) ) ;
}
rs = ps. executeQuery ( ) ;
} catch ( SQLException e) {
System. out. println ( "执行SQL失败: " + e. getMessage ( ) ) ;
}
} else {
Statement st = statement ( ) ;
try {
rs = st. executeQuery ( SQL ) ;
} catch ( SQLException e) {
System. out. println ( "执行SQL失败: " + e. getMessage ( ) ) ;
}
}
return rs;
}
private static Object typeof ( Object o) {
Object r = o;
if ( o instanceof java. sql. Timestamp ) {
return r;
}
if ( o instanceof java. util. Date ) {
java. util. Date d = ( java. util. Date) o;
r = new java. sql. Date ( d. getTime ( ) ) ;
return r;
}
if ( o instanceof Character || o. getClass ( ) == char. class ) {
r = String. valueOf ( o) ;
return r;
}
return r;
}
public static boolean execute ( String SQL , Object... params) {
if ( SQL == null || SQL . trim ( ) . isEmpty ( ) || SQL . trim ( ) . toLowerCase ( ) . startsWith ( "select" ) ) {
throw new RuntimeException ( "你的SQL语句为空或有错" ) ;
}
boolean r = false ;
SQL = SQL . trim ( ) ;
SQL = SQL . toLowerCase ( ) ;
String prefix = SQL . substring ( 0 , SQL . indexOf ( " " ) ) ;
String operation = "" ;
switch ( prefix) {
case "create" :
operation = "create table" ;
break ;
case "alter" :
operation = "update table" ;
break ;
case "drop" :
operation = "drop table" ;
break ;
case "truncate" :
operation = "truncate table" ;
break ;
case "insert" :
operation = "insert :" ;
break ;
case "update" :
operation = "update :" ;
break ;
case "delete" :
operation = "delete :" ;
break ;
}
if ( params. length > 0 ) {
PreparedStatement ps = prepare ( SQL , false ) ;
Connection c = null ;
try {
c = ps. getConnection ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
try {
for ( int i = 0 ; i < params. length; i++ ) {
Object p = params[ i] ;
p = typeof ( p) ;
ps. setObject ( i + 1 , p) ;
}
ps. executeUpdate ( ) ;
commit ( c) ;
r = true ;
} catch ( SQLException e) {
System. out. println ( operation + " 失败: " + e. getMessage ( ) ) ;
rollback ( c) ;
}
} else {
Statement st = statement ( ) ;
Connection c = null ;
try {
c = st. getConnection ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
try {
st. executeUpdate ( SQL ) ;
commit ( c) ;
r = true ;
} catch ( SQLException e) {
System. out. println ( operation + " 失败: " + e. getMessage ( ) ) ;
rollback ( c) ;
}
}
return r;
}
public static int insert ( String SQL , boolean autoGeneratedKeys, List< Object> params) {
int var = - 1 ;
if ( SQL == null || SQL . trim ( ) . isEmpty ( ) ) {
throw new RuntimeException ( "你没有指定SQL语句,请检查是否指定了需要执行的SQL语句" ) ;
}
if ( ! SQL . trim ( ) . toLowerCase ( ) . startsWith ( "insert" ) ) {
System. out. println ( SQL . toLowerCase ( ) ) ;
throw new RuntimeException ( "你指定的SQL语句不是插入语句,请检查你的SQL语句" ) ;
}
SQL = SQL . trim ( ) ;
SQL = SQL . toLowerCase ( ) ;
if ( params. size ( ) > 0 ) {
PreparedStatement ps = prepare ( SQL , autoGeneratedKeys) ;
Connection c = null ;
try {
c = ps. getConnection ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
try {
for ( int i = 0 ; i < params. size ( ) ; i++ ) {
Object p = params. get ( i) ;
p = typeof ( p) ;
ps. setObject ( i + 1 , p) ;
}
int count = ps. executeUpdate ( ) ;
if ( autoGeneratedKeys) {
ResultSet rs = ps. getGeneratedKeys ( ) ;
if ( rs. next ( ) ) {
var = rs. getInt ( 1 ) ;
}
} else {
var = count;
}
commit ( c) ;
} catch ( SQLException e) {
System. out. println ( "数据保存失败: " + e. getMessage ( ) ) ;
rollback ( c) ;
}
} else {
Statement st = statement ( ) ;
Connection c = null ;
try {
c = st. getConnection ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
try {
int count = st. executeUpdate ( SQL ) ;
if ( autoGeneratedKeys) {
ResultSet rs = st. getGeneratedKeys ( ) ;
if ( rs. next ( ) ) {
var = rs. getInt ( 1 ) ;
}
} else {
var = count;
}
commit ( c) ;
} catch ( SQLException e) {
System. out. println ( "数据保存失败: " + e. getMessage ( ) ) ;
rollback ( c) ;
}
}
return var ;
}
private static void commit ( Connection c) {
if ( c != null && ! autoCommit) {
try {
c. commit ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
private static void rollback ( Connection c) {
if ( c != null && ! autoCommit) {
try {
c. rollback ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
public static void release ( Object cloaseable) {
if ( cloaseable != null ) {
if ( cloaseable instanceof ResultSet ) {
ResultSet rs = ( ResultSet) cloaseable;
try {
rs. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( cloaseable instanceof Statement ) {
Statement st = ( Statement) cloaseable;
try {
st. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
if ( cloaseable instanceof Connection ) {
Connection c = ( Connection) cloaseable;
try {
c. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
}
}
}
}
}
工具类2
package com. sym. Util;
import java. util. ArrayList;
import java. util. List;
public class SQLUtils {
public static String[ ] sqlInsertParameter ( String sql) {
int startIndex = sql. indexOf ( "values" ) ;
int endIndex = sql. length ( ) ;
String substring = sql. substring ( startIndex + 6 , endIndex) . replace ( "(" , "" ) . replace ( ")" , "" ) . replace ( "#{" , "" )
. replace ( "}" , "" ) ;
String[ ] split = substring. split ( "," ) ;
return split;
}
public static List< String> sqlSelectParameter ( String sql) {
int startIndex = sql. indexOf ( "where" ) ;
int endIndex = sql. length ( ) ;
String substring = sql. substring ( startIndex + 5 , endIndex) ;
String[ ] split = substring. split ( "and" ) ;
List< String> listArr = new ArrayList < > ( ) ;
for ( String string : split) {
String[ ] sp2 = string. split ( "=" ) ;
listArr. add ( sp2[ 0 ] . trim ( ) ) ;
}
return listArr;
}
public static String parameQuestion ( String sql, String[ ] parameterName) {
for ( int i = 0 ; i < parameterName. length; i++ ) {
String string = parameterName[ i] ;
sql = sql. replace ( "#{" + string + "}" , "?" ) ;
}
return sql;
}
public static String parameQuestion ( String sql, List< String> parameterName) {
for ( int i = 0 ; i < parameterName. size ( ) ; i++ ) {
String string = parameterName. get ( i) ;
sql = sql. replace ( "#{" + string + "}" , "?" ) ;
}
return sql;
}
public static void main ( String[ ] args) {
}
}