zoukankan      html  css  js  c++  java
  • 完整的MVC框架(前端、后台和数据库)

    终于学完了数据库的连接,可以做一个完整的项目了,以前做的练习都没有关联到数据库,没法进行事务。

     

    MVC框架

    先上图:

    老师画的图,有点乱,但是大概意思还是可以理解。

    这个练习是简单的存储一个学生读了哪些书,存进数据库中,当然也可以查询。

    主页图:

    代码奉上:

    index.jsp

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
    2. <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
    3.   
    4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    5. <html>  
    6.   <head>  
    7.       
    8.     <title>学生图书信息管理</title>  
    9.   </head>  
    10.     
    11.   <body>  
    12.     <br><a href='<c:url value="/StudServlet?cmd=query"></c:url>' >学生图书信息查询</a>  
    13.     <br/><br/>  
    14.     <hr/>  
    15.     <form action='<c:url value="/StudServlet?cmd=save"></c:url>' method="post">  
    16.         姓名<input type="text" name="name" /><br/><br/>  
    17.     <fieldset style=" 200px">  
    18.         <legend>图书1</legend>  
    19.         书名<input type="text" name="bookName" />  
    20.         价格<input type="text" name="price" />  
    21.     </fieldset>  
    22.     <fieldset style=" 200px">  
    23.         <legend>图书2</legend>  
    24.         书名<input type="text" name="bookName" />  
    25.         价格<input type="text" name="price" />  
    26.     </fieldset>  
    27.     <input type="submit" value="保存">  
    28.     </form>  
    29.     <br/>  
    30.     <a href='<c:url value="StudServlet?cmd=abc"></c:url>' >只是随便转转,不要开启事务</a>  
    31.   </body>  
    32. </html>  
    33. </span>  


    index请求的servlet.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.stud.servlet;  
    2.   
    3. import java.io.IOException;  
    4. import java.util.List;  
    5. import java.util.Map;  
    6.   
    7. import javax.servlet.ServletException;  
    8. import javax.servlet.http.HttpServlet;  
    9. import javax.servlet.http.HttpServletRequest;  
    10. import javax.servlet.http.HttpServletResponse;  
    11.   
    12. import cn.hncu.domain.Book;  
    13. import cn.hncu.domain.Stud;  
    14. import cn.hncu.stud.service.IStudService;  
    15. import cn.hncu.stud.service.IStudServiceImpl;  
    16. import cn.hncu.utils.TxProxy;  
    17.   
    18. public class StudServlet extends HttpServlet {  
    19. //  IStudService service=new IStudServiceImpl();//这是直接在service层中开启事务,也是version 1  
    20. //  IStudService service=TxProxy.getProxy(IStudServiceImpl.class);//version 2  
    21.     IStudService service=TxProxy.getProxy(new IStudServiceImpl());//version 3  
    22.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
    23.             throws ServletException, IOException {  
    24.   
    25.         doPost(request, response);  
    26.     }  
    27.   
    28.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
    29.             throws ServletException, IOException {  
    30.             request.setCharacterEncoding("utf-8");  
    31.             String cmd=request.getParameter("cmd");  
    32.             if("query".equals(cmd)){//不直接用cmd去判断,是为了防止cmd为null,更安全些  
    33.                 query(request, response);  
    34.             }else if("save".equals(cmd)){  
    35.                 save(request, response);  
    36.             }else if("abc".equals(cmd)){  
    37.                 abc(request,response);  
    38.             }  
    39.     }  
    40.   
    41.     private void query(HttpServletRequest request, HttpServletResponse response)  
    42.             throws ServletException, IOException {  
    43.         List<Map<String,String>> stud=service.query();  
    44.         request.setAttribute("stud", stud);  
    45.         request.getRequestDispatcher("/jsps/show.jsp").forward(request, response);  
    46.     }  
    47.     private void save(HttpServletRequest request, HttpServletResponse response)  
    48.             throws ServletException, IOException {  
    49.         //1.收集   2.组织  
    50.         String name=request.getParameter("name");  
    51.         //图书信息  
    52.         String[] bookNames=request.getParameterValues("bookName");  
    53.         String prices[]=request.getParameterValues("price");  
    54.           
    55.         Stud stud=new Stud();  
    56.         stud.setName(name);  
    57.         if(bookNames==null||bookNames.length==0){//防护一下,防止为空,下面的price也应该做防护的,我省略了  
    58.             return;  
    59.         }  
    60.         for(int i=0;i<bookNames.length;i++){  
    61.             Book book=new Book();  
    62.             book.setName(bookNames[i]);  
    63.             book.setPrice(Double.parseDouble(prices[i]));  
    64.   
    65.             //在这里完成两个值对象的“一对多”关系的数据封装  
    66.             stud.getBook().add(book);  
    67.             book.setStud(stud);  
    68.         }  
    69.           
    70.         //3 调用service层  
    71.         try {  
    72.             service.save(stud);//把stud放进去就可以  
    73.             System.out.println("SUCCESSFULL");  
    74.         } catch (Exception e) {  
    75.             //导向失败页面  
    76.         }  
    77.           
    78.     }  
    79.     private void abc(HttpServletRequest request, HttpServletResponse response)  
    80.             throws ServletException, IOException {  
    81.             service.abc();  
    82.     }  
    83. }  
    84. </span>  

    servlet要组织和封装从前台页面发来的数据,这里用了两个值对象:

    Stud.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.domain;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. /*  
    7.  * 一对多中“一方”值对象的建法  
    8.  */  
    9. public class Stud {  
    10.     private String id;  
    11.     private String name;  
    12.       
    13.     //为多方开一个集合,用来体现多表中“一对多”的关系  
    14.     private List<Book> books=new ArrayList<Book>();//注意:该集合要在类构造或之前就new出来  
    15.   
    16.     public String getId() {  
    17.         return id;  
    18.     }  
    19.   
    20.     public void setId(String id) {  
    21.         this.id = id;  
    22.     }  
    23.   
    24.     public String getName() {  
    25.         return name;  
    26.     }  
    27.   
    28.     public void setName(String name) {  
    29.         this.name = name;  
    30.     }  
    31.   
    32.     public List<Book> getBook() {  
    33.         return books;  
    34.     }  
    35.   
    36.     public void setBook(List<Book> book) {  
    37.         this.books = book;  
    38.     }  
    39.   
    40.     @Override  
    41.     public String toString() {  
    42.         return "Stud [id=" + id + ", name=" + name + ", book=" + books + "]";  
    43.     }  
    44.       
    45. }  
    46. </span>  

    Book.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.domain;  
    2. /*  
    3.  * 一对多中的“多”方值对象的建法  
    4.  */  
    5. public class Book {  
    6.     private Integer id;//基本数据类型全用包装类来声明,为以后使用框架做技术准备----包装类能够兼容框架(因为一般框架都会使用类反射)  
    7.     private String name;  
    8.     private Double price;  
    9.       
    10.     //专为“一”方添加一个对象类型的变量(不直接使用String studid)-----体现多表中的“一对多”关系  
    11.     private Stud stud=new Stud();//设置书的主人  
    12.   
    13.     public Integer getId() {  
    14.         return id;  
    15.     }  
    16.   
    17.     public void setId(Integer id) {  
    18.         this.id = id;  
    19.     }  
    20.   
    21.     public String getName() {  
    22.         return name;  
    23.     }  
    24.   
    25.     public void setName(String name) {  
    26.         this.name = name;  
    27.     }  
    28.   
    29.     public Double getPrice() {  
    30.         return price;  
    31.     }  
    32.   
    33.     public void setPrice(Double price) {  
    34.         this.price = price;  
    35.     }  
    36.   
    37.     public Stud getStud() {  
    38.         return stud;  
    39.     }  
    40.   
    41.     public void setStud(Stud stud) {  
    42.         this.stud = stud;  
    43.     }  
    44.       
    45.     //多表关联时toString()有一个陷阱:不要出现一方输出另外一方,另外一方又输出这一方的情况,形成无穷循环  
    46.     @Override  
    47.     public String toString() {  
    48.         return "Book [id=" + id + ", name=" + name + ", price=" + price + "]";  
    49.     }  
    50.       
    51.       
    52. }  
    53. </span>  



     

    servlet调用service,service被动态代理的TxProxy.java

    1. <span style="font-size:14px;">package cn.hncu.utils;  
    2.   
    3. import java.lang.reflect.InvocationHandler;  
    4. import java.lang.reflect.Method;  
    5. import java.lang.reflect.Proxy;  
    6. import java.sql.Connection;  
    7.   
    8. public class TxProxy implements InvocationHandler {  
    9.     private Object srcObj=null;  
    10.     private TxProxy(Object srcObj) {  
    11.         this.srcObj=srcObj;  
    12.     }  
    13.     /*version 1  
    14.     public static Object getProxy(Object srcObj){  
    15.         Object newObj=Proxy.newProxyInstance(  
    16.                 TxProxy.class.getClassLoader(),   
    17.                 srcObj.getClass().getInterfaces(),   
    18.                 new TxProxy(srcObj));  
    19.         return newObj;  
    20.     }  
    21.     */  
    22.     /*version 2  
    23.     public static<T> T getProxy(Class<T> c){  
    24.         Object obj=null;  
    25.         try {  
    26.             obj = c.newInstance();  
    27.         } catch (Exception e) {  
    28.             throw new RuntimeException(c+"没有空参方法!");  
    29.         }  
    30.         Object newObj=Proxy.newProxyInstance(  
    31.                 TxProxy.class.getClassLoader(),   
    32.                 obj.getClass().getInterfaces(),   
    33.                 new TxProxy(obj));  
    34.         return (T)newObj;  
    35.     }  
    36.     */  
    37.     public static<T> T getProxy(T srcObj){  
    38.         Object newObj=Proxy.newProxyInstance(  
    39.                 TxProxy.class.getClassLoader(),   
    40.                 srcObj.getClass().getInterfaces(),   
    41.                 new TxProxy(srcObj));  
    42.         return (T)newObj;  
    43.     }  
    44.     /*version 1与version 2公用  
    45.     @Override  
    46.     public Object invoke(Object proxy, Method method, Object[] args)  
    47.             throws Throwable {  
    48.         Connection con=null;  
    49.         Object returnObj=null;  
    50.           
    51.         try {  
    52.             con=ConnUtils5.getConn();  
    53.             con.setAutoCommit(false);  
    54.             System.out.println("开启事务.........");  
    55.               
    56.             returnObj=method.invoke(srcObj, args);//放行  
    57.               
    58.             con.commit();//  
    59.             System.out.println("提交事务.......");  
    60.         } catch (Exception e) {  
    61.             con.rollback();  
    62.             System.out.println("回滚事务.........");  
    63.         }finally{  
    64.             try {  
    65.                 con.setAutoCommit(true);  
    66.                 con.close();  
    67.             } catch (Exception e) {  
    68.                 throw new RuntimeException(e.getMessage(), e);  
    69.             }  
    70.         }  
    71.           
    72.         return returnObj;  
    73.     }  
    74.     */  
    75.     @Override  
    76.     public Object invoke(Object proxy, Method method, Object[] args)  
    77.             throws Throwable {  
    78.         if(method.isAnnotationPresent(Transaction.class)){  
    79.             System.out.println("此方法存在注解,进行拦截......");  
    80.             Connection con=null;  
    81.             Object returnObj=null;  
    82.               
    83.             try {  
    84.                 con=ConnUtils5.getConn();  
    85.                 con.setAutoCommit(false);  
    86.                 System.out.println("开启事务.........");  
    87.                   
    88.                 returnObj=method.invoke(srcObj, args);//放行  
    89.                   
    90.                 con.commit();//  
    91.                 System.out.println("提交事务.......");  
    92.             } catch (Exception e) {  
    93.                 con.rollback();  
    94.                 System.out.println("回滚事务.........");  
    95.             }finally{  
    96.                 try {  
    97.                     con.setAutoCommit(true);  
    98.                     con.close();  
    99.                 } catch (Exception e) {  
    100.                     throw new RuntimeException(e.getMessage(), e);  
    101.                 }  
    102.             }  
    103.               
    104.             return returnObj;  
    105.         }  
    106.         System.out.println("没有注解,直接放行....");  
    107.         return method.invoke(srcObj, args);  
    108.     }  
    109.       
    110. }  
    111. </span>  


    service层的接口IStudService.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.stud.service;  
    2.   
    3. import java.util.List;  
    4. import java.util.Map;  
    5.   
    6. import cn.hncu.domain.Stud;  
    7. import cn.hncu.utils.Transaction;  
    8.   
    9. public interface IStudService {  
    10.     public abstract List<Map<String,String>> query();  
    11.       
    12.     @Transaction  
    13.     public abstract void save(Stud stud) throws Exception ;  
    14.   
    15.     public abstract void abc();  
    16. }  
    17. </span>  

    接口用到的注解:

    Transaction.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.utils;  
    2.   
    3. import java.lang.annotation.ElementType;  
    4. import java.lang.annotation.Retention;  
    5. import java.lang.annotation.RetentionPolicy;  
    6. import java.lang.annotation.Target;  
    7.   
    8.   
    9. @Target(value=ElementType.METHOD)  
    10. @Retention(RetentionPolicy.RUNTIME)  
    11. public @interface Transaction {  
    12. }  
    13. </span>  


     


    实现类IStudServiceImpl.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.stud.service;  
    2.   
    3. import java.sql.Connection;  
    4. import java.sql.SQLException;  
    5. import java.util.List;  
    6. import java.util.Map;  
    7.   
    8. import cn.hncu.domain.Stud;  
    9. import cn.hncu.stud.dao.BookDAO;  
    10. import cn.hncu.stud.dao.BookJdbcDao;  
    11. import cn.hncu.stud.dao.StudDAO;  
    12. import cn.hncu.stud.dao.StudJdbcDao;  
    13. import cn.hncu.utils.ConnUtils5;  
    14. /*  
    15.  * 我们以后开发时通常要采用一个dao独立操作一个表,系统中有几个实体表就写几个dao,  
    16.  * 框架也是这么做的,架构好。  
    17.  *   
    18.  * 采用事务的场合:  
    19.  * 1.如果只有一个dao,但要执行多条sql语句且涉及增、删、改操作时要开启事务  
    20.  * 2.如果一个service调用多个dao,通常也要开启事务  
    21.  */  
    22. public class IStudServiceImpl implements IStudService{  
    23.       
    24.     public IStudServiceImpl() {  
    25.     }  
    26.     StudDAO stuDao=new StudJdbcDao();  
    27.     BookDAO booDao=new BookJdbcDao();  
    28.     @Override  
    29.     public List<Map<String, String>> query() {  
    30.         return stuDao.query();  
    31.     }  
    32.     /*  
    33.      * 事务要在service层做,dao层抛异常,在service抓异常,然后就行事务回滚,或者没有异常,提交  
    34.      * 但是,service拿到的要和dao拿到的是同一个Connection对象,否则无法进行提交或者回滚  
    35.      */  
    36.     @Override  
    37.     public void save(Stud stud) throws Exception {  
    38.         stuDao.save(stud);  
    39.         booDao.save(stud.getBook());  
    40.     }  
    41.     @Override  
    42.     public void abc() {  
    43.         System.out.println("什么都不做,只是来转转.....");  
    44.           
    45.     }  
    46.       
    47. }  
    48. </span>  


    service调用dao层,由于要一个表要对应一个dao,这里有stud表和book表,所以有两个dao

    接口StudDAO.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.stud.dao;  
    2.   
    3. import java.util.List;  
    4. import java.util.Map;  
    5.   
    6. import cn.hncu.domain.Stud;  
    7.   
    8. public interface StudDAO {  
    9.     public abstract List<Map<String,String>> query();  
    10.   
    11.     public abstract void save(Stud stud) throws Exception;  
    12. }  
    13. </span>  


    实现类StudJdbcDao.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.stud.dao;  
    2.   
    3. import java.sql.Connection;  
    4. import java.sql.PreparedStatement;  
    5. import java.sql.ResultSet;  
    6. import java.sql.SQLException;  
    7. import java.util.ArrayList;  
    8. import java.util.HashMap;  
    9. import java.util.List;  
    10. import java.util.Map;  
    11. import java.util.UUID;  
    12.   
    13. import cn.hncu.domain.Stud;  
    14. import cn.hncu.utils.ConnUtils5;  
    15.   
    16. public class StudJdbcDao implements StudDAO{  
    17.   
    18.     @Override  
    19.     public List<Map<String, String>> query() {  
    20.         List<Map<String, String>> list=new ArrayList<Map<String,String>>();  
    21.         //一个map就是一行数据,List<Map<>>就是整个数据表  
    22.         Connection con=ConnUtils5.getConn();  
    23.         try {  
    24.             ResultSet rs=con.createStatement().executeQuery("select * from stud");  
    25.             while(rs.next()){  
    26.                 Map<String, String> map=new HashMap<String, String>();  
    27.                 map.put("id", rs.getString("id"));  
    28.                 map.put("name", rs.getString("name"));  
    29.                 list.add(map);  
    30.             }  
    31.             rs.close();  
    32.         } catch (SQLException e) {  
    33.             e.printStackTrace();  
    34.         }finally{  
    35.             try {  
    36.                 con.close();  
    37.             } catch (SQLException e) {  
    38.                 e.printStackTrace();  
    39.             }  
    40.         }  
    41.         return list;  
    42.     }  
    43.   
    44.   
    45.     @Override  
    46.     public void save(Stud stud) throws Exception {  
    47.         Connection con=ConnUtils5.getConn();  
    48.         String id=UUID.randomUUID().toString().replace("-", "");  
    49.         String sql="insert into stud(id,name) values(?,?)";  
    50.         PreparedStatement pst=con.prepareStatement(sql);  
    51.         pst.setString(1, id);  
    52.         pst.setString(2, stud.getName());  
    53.         pst.executeUpdate();  
    54. //      int a=pst.executeUpdate();  
    55.         //System.out.println("影响 "+a+" 行");  
    56.         stud.setId(id);//为了“多方能够拿到一方的id,在这里补一方的id”  
    57.     }  
    58.   
    59. }  
    60. </span>  


    接口BookDAO.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.stud.dao;  
    2.   
    3. import java.util.List;  
    4.   
    5. import cn.hncu.domain.Book;  
    6.   
    7. public interface BookDAO {  
    8.     public abstract void save(List<Book> list) throws Exception;  
    9. }  
    10. </span>  


    实现类BookJdbcDao.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.stud.dao;  
    2.   
    3. import java.sql.Connection;  
    4. import java.sql.PreparedStatement;  
    5. import java.sql.SQLException;  
    6. import java.util.List;  
    7.   
    8. import cn.hncu.domain.Book;  
    9. import cn.hncu.utils.ConnUtils5;  
    10.   
    11. public class BookJdbcDao implements BookDAO{  
    12.   
    13.   
    14.     @Override  
    15.     public void save(List<Book> list) throws Exception {  
    16.         Connection con=ConnUtils5.getConn();  
    17.         String sql="insert into book(name,price,studid) values(?,?,?)";  
    18.         //          INSERT INTO book(NAME,price,studid) VALUES("aa",33.5,"1");  
    19.         PreparedStatement pst=con.prepareStatement(sql);  
    20.         for(Book book:list){  
    21.             pst.setString(1, book.getName());  
    22.             pst.setDouble(2, book.getPrice());  
    23.             pst.setString(3, book.getStud().getId());  
    24.             pst.addBatch();//此处不要参数!!!!!添加到批处理(有很多条sql语句要执行时,用批处理)  
    25.         }  
    26.         pst.executeBatch();//执行批处理  
    27.       
    28.     }  
    29.       
    30. }  
    31. </span>  

    类和包:


    效果图:

    存储到数据库:

    学生表:

    图书表:

    查询:

    在项目中又有两个新的知识点:

    ThreadLocal类:

    java.lang.ThreadLocal<T>

    这个类本质上就是里面维护着一个HashMap<Thread,Object>,key为线程,get方法就是通过Thread.currentThread()判断当前线程,然后在map中找到对应的Object,然后返回出去。

    即:同一个线程拿同一个对象,不同线程则是不同对象。

    这里做了一些练习:

    ThreadLocalUtil.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.threadLocDemo;  
    2.   
    3. import java.util.Random;  
    4. public class ThreadLocalUtil {  
    5. //  private static ThreadLocal<Object> t1=new ThreadLocal<Object>();//线程管理池Map<Thread,Object>  
    6.     private static MyThreadLocal<Object> t1=new MyThreadLocal<Object>();//线程管理池Map<Thread,Object>  
    7.       
    8.     public static Object getObj(){  
    9.         Object obj=t1.get();//从池中拿一个obj  
    10.         if(obj==null){//如果池中没有  
    11.             Random r=new Random();  
    12.             obj=r.nextInt(500);  
    13.             t1.set(obj);//则new obj放进池中去  
    14.         }  
    15.         return obj;  
    16.     }  
    17. }  
    18. </span>  

    测试类Client.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.threadLocDemo;  
    2.   
    3. import org.junit.Test;  
    4.   
    5. public class Client {  
    6.       
    7.     @Test  
    8.     public void test1(){  
    9.         Object o1=ThreadLocalUtil.getObj();  
    10.         Object o2=ThreadLocalUtil.getObj();  
    11.         System.out.println("o1: "+o1+",o2: "+o2);  
    12.         System.out.println("o1==o2?  "+(o1==o2));  
    13.     }  
    14.     @Test  
    15.     public void test2(){  
    16.         test1();  
    17.         System.out.println();  
    18.         Object o3=ThreadLocalUtil.getObj();  
    19.         Object o4=ThreadLocalUtil.getObj();  
    20.         System.out.println("o3: "+o3+",o4: "+o4);  
    21.         System.out.println("o3==o4?  "+(o3==o4));  
    22.         System.out.println();  
    23.         new Thread(){  
    24.             @Override  
    25.             public void run() {  
    26.                 Object o4=ThreadLocalUtil.getObj();  
    27.                 Object o5=ThreadLocalUtil.getObj();  
    28.                 System.out.println("o4: "+o4+",o5: "+o5);  
    29.                 System.out.println("o4==o5?  "+(o4==o5));  
    30.                 System.out.println();  
    31.             }  
    32.         }.start();  
    33.     }  
    34.     /*  
    35.      * 测试结果:obj1,obj2,obj3,obj4由于是同一个线程,所以obj也都相同,  
    36.      * obj5和obj6两者相同,但是他们是另外一个线程获取的,所以和obj1`obj4是不相等的  
    37.      */  
    38. }  
    39. </span>  


    测试图:

    在知道ThreadLocal的功能后,我们自己模拟了一下它的功能:

    MyThreadLocal.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">package cn.hncu.threadLocDemo;  
    2.   
    3. import java.util.HashMap;  
    4. import java.util.Map;  
    5. /*  
    6.  * 自己模拟ThreadLocal功能,便于理解  
    7.  * 虽然表面的功能能够模拟出来,但是ThreadLocal真正的功能远远比这强,比如内存管理  
    8.  */  
    9. public class MyThreadLocal<Object> {  
    10.     private Map<Thread, Object> map=new HashMap<Thread, Object>();  
    11.       
    12.     public Object get(){  
    13.         Thread t=Thread.currentThread();  
    14.         return map.get(t);  
    15.     }  
    16.     public void set(Object obj){  
    17.         map.put(Thread.currentThread(), obj);  
    18.     }  
    19. }  
    20. </span>  


    同样可以得出一样的结果,但是仅仅只是模拟了表面功能!


    动态代理模板

    前面已经贴出代码,但是这里用到了类反射、注解、泛型和动态代理,这几个知识点不是很熟,所以在这里再写遍,提醒一下自己!

    TxProxy.java

    [plain] view plain copy
     print?在CODE上查看代码片派生到我的代码片
      1. <span style="font-size:14px;">package cn.hncu.utils;  
      2.   
      3. import java.lang.reflect.InvocationHandler;  
      4. import java.lang.reflect.Method;  
      5. import java.lang.reflect.Proxy;  
      6. import java.sql.Connection;  
      7.   
      8. public class TxProxy implements InvocationHandler {  
      9.     private Object srcObj=null;  
      10.     private TxProxy(Object srcObj) {  
      11.         this.srcObj=srcObj;  
      12.     }  
      13.       
      14.     public static<T> T getProxy(T srcObj){  
      15.         Object newObj=Proxy.newProxyInstance(  
      16.                 TxProxy.class.getClassLoader(),   
      17.                 srcObj.getClass().getInterfaces(),   
      18.                 new TxProxy(srcObj));  
      19.         return (T)newObj;  
      20.     }  
      21.       
      22.     @Override  
      23.     public Object invoke(Object proxy, Method method, Object[] args)  
      24.             throws Throwable {  
      25.         if(method.isAnnotationPresent(Transaction.class)){  
      26.             System.out.println("此方法存在注解,进行拦截......");  
      27.             Connection con=null;  
      28.             Object returnObj=null;  
      29.               
      30.             try {  
      31.                 con=ConnUtils5.getConn();  
      32.                 con.setAutoCommit(false);  
      33.                 System.out.println("开启事务.........");  
      34.                   
      35.                 returnObj=method.invoke(srcObj, args);//放行  
      36.                   
      37.                 con.commit();//  
      38.                 System.out.println("提交事务.......");  
      39.             } catch (Exception e) {  
      40.                 con.rollback();  
      41.                 System.out.println("回滚事务.........");  
      42.             }finally{  
      43.                 try {  
      44.                     con.setAutoCommit(true);  
      45.                     con.close();  
      46.                 } catch (Exception e) {  
      47.                     throw new RuntimeException(e.getMessage(), e);  
      48.                 }  
      49.             }  
      50.               
      51.             return returnObj;  
      52.         }  
      53.         System.out.println("没有注解,直接放行....");  
      54.         return method.invoke(srcObj, args);  
      55.     }  
      56.       
      57. }  
      58. </span>  
  • 相关阅读:
    设计模式——适配器模式
    设计模式——模板方法模式
    03-Web开发(上)
    02-配置文件
    01-QuickStart
    34-多线程(下)
    33-IO(下)
    15-后端编译与优化(待补充)
    14-线程安全与锁优化
    13-JUC(下)
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/6736920.html
Copyright © 2011-2022 走看看