11.24

cd /home/app/sxpservice/logs/apps && ll && tail -200f server.log    查看日志

 

11.24

 

策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

介绍

意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。

何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。

如何解决:将这些算法封装成一个一个的类,任意地替换。

关键代码:实现同一个接口。

应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。

优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。

使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

实现

我们将创建一个定义活动的 Strategy 接口和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。

StrategyPatternDemo,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化。

 

步骤 1

创建一个接口。

Strategy.java

public interface Strategy {

   public int doOperation(int num1, int num2);

}

步骤 2

创建实现接口的实体类。

OperationAdd.java

public class OperationAdd implements Strategy{

   @Override

   public int doOperation(int num1, int num2) {

      return num1 + num2;

   }

}

OperationSubstract.java

public class OperationSubstract implements Strategy{

   @Override

   public int doOperation(int num1, int num2) {

      return num1 - num2;

   }

}

OperationMultiply.java

public class OperationMultiply implements Strategy{

   @Override

   public int doOperation(int num1, int num2) {

      return num1 * num2;

   }

}

步骤 3

创建 Context 类。

Context.java

public class Context {

   private Strategy strategy;

 

   public Context(Strategy strategy){

      this.strategy = strategy;

   }

 

   public int executeStrategy(int num1, int num2){

      return strategy.doOperation(num1, num2);

   }

}

步骤 4

使用 Context 来查看当它改变策略 Strategy 时的行为变化。

StrategyPatternDemo.java

public class StrategyPatternDemo {

   public static void main(String[] args) {

      Context context = new Context(new OperationAdd());        

      System.out.println("10 + 5 = " + context.executeStrategy(10, 5));

 

      context = new Context(new OperationSubstract());        

      System.out.println("10 - 5 = " + context.executeStrategy(10, 5));

 

      context = new Context(new OperationMultiply());        

      System.out.println("10 * 5 = " + context.executeStrategy(10, 5));

   }

}

步骤 5

验证输出。

10 + 5 = 15

10 - 5 = 5

10 * 5 = 50

 

MD5

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文件是否一致的。

java实现代码:

package com.cn.单向加密;

 

import java.math.BigInteger;

import java.security.MessageDigest;

/*

MD5(Message Digest algorithm 5,信息摘要算法)

通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串

Digest:汇编

*/

public class MD5 {

    public static final String KEY_MD5 = "MD5";  

 

    public static  String  getResult(String inputStr)

    {

        System.out.println("=======加密前的数据:"+inputStr);

        BigInteger bigInteger=null;

 

        try {

         MessageDigest md = MessageDigest.getInstance(KEY_MD5);  

         byte[] inputData = inputStr.getBytes();

         md.update(inputData);  

         bigInteger = new BigInteger(md.digest());  

        } catch (Exception e) {e.printStackTrace();}

        System.out.println("MD5加密后:" + bigInteger.toString(16));  

        return bigInteger.toString(16);

    }

 

    public static void main(String args[])

    {

        try {

             String inputStr = "简单加密8888888888888888888";  

             getResult(inputStr);

        } catch (Exception e) {

            e.printStackTrace();

        }

 

    }

 

}

MD5算法具有以下特点:

1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、弱抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
5、强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。
MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等。

 

 

StringUtils常用的方法

 

1. 检查字符串是否为空:

 

 static boolean isBlank(CharSequence str)  判断字符串是否为空或null;
 static boolean isNotBlank(CharSequence str) 判断字符串是否非空或非null;

 

 StringUtils.isBlank("a");
 返回结果为: false;

 

2. 缩进字符串:

 

 static String abbreviate(String str, int maxWidth) 缩进字符串,第二个参数至少为4(包括...)

 

 StringUtils.abbreviate("abcdefg", 20);
 返回结果为:abcdefg (正常显示)

 StringUtils.abbreviate("abcdefg", 4);
 返回结果为:a...

 

3. 首字母大写:

 

 static String capitalize(String str) 首字母大写
 static String uncapitalize(String str)首字母小写  

 

 StringUtils.capitalize("abcdefg");
 返回结果:Abcdefg

 

4. 字符串显示在一个大字符串的位置:

 

 static String center(String str, int size);  默认以空格填充
 static String center(String str, int size, String padString); 其余位置字符串填充
 public static String leftPad(String str,int size); 左侧空格填充
 public static String leftPad(String str,int size,String padStr);左侧字符串填充
 public static String rightPad(String str,int size); 左侧空格填充
 public static String rightPad(String str,int size,String padStr);左侧字符串填充
 

 StringUtils.center("abcdefg", 20);
 返回结果:      abcdefg      

 StringUtils.center("abcdefg", 20,"*_");
 返回结果:*_*_*_abcdefg*_*_*_*

 StringUtils.leftPad("abc", 10, "*");
 返回结果:*******abc

 

5. 重复字符串次数

 

 static String repeat(String str, int repeat);

 

 StringUtils.repeat("abc", 5); 
 返回结果:abcabcabcabcabc

 

6. 是否全是大写,是否全是小写(3.0版本)

 

 public static boolean isAllLowerCase(String str);
 public static boolean isAllUpperCase(String str);

 

 StringUtils.isAllLowerCase("abC");
 返回结果:false

 

7. 是否都是由字母组成:

 

 public static boolean isAlpha(String str);  只由字母组成
 public static boolean isAlphaSpace(String str); 只有字母和空格组成
 public static boolean isAlphanumeric(String str);只由字母和数字组成
 public static boolean isAlphanumericSpace(String str);只由字母数字和空格组成
 public static boolean isNumeric(String str);只由数字组成
 public static boolean isNumericSpace(String str);只由数字和空格组成

 

 StringUtils.isAlpha("a2bdefg");
 返回结果:false

 

8. 小字符串在大字符串中的匹配次数

 

public static int countMatches(String str,String sub);

 

StringUtils.countMatches("ababsssababa", "ab");
 返回结果:4

 

9. 字符串倒转

 

 public static String reverse(String str);

 

 StringUtils.reverse("abcdef");
 返回结果:fedcba

 

10. 大小写转换,空格不动
 

 public static String swapCase(String str);

 

 StringUtils.swapCase("I am a-A*a")
 返回结果:i AM A-a*A

 

 

 

 

 

 

ArrayUtils是专门用来处理数组的工具类,提供很多有用的方法,下面是其一个方法蓝图:

 
 

ArrayUtils.png
 
 

添加方法

 

add(boolean[] array,boolean element)等等

 

add(T[] array,int index,T element)等等

 

addAll(boolean[] array1,boolean... array2)等等

 
    //添加元素到数组中        
    ArrayUtils.add([true, false], true) = [true, false, true]    
 
    //将元素插入到指定位置的数组中
    ArrayUtils.add(["a"], 1, null)     = ["a", null]
     ArrayUtils.add(["a"], 1, "b")      = ["a", "b"]
     ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
 
    ArrayUtils.add(["a", "b"], ["c", "d"]) = ["a", "b", "c","d"]
 

克隆方法

 

clone(boolean[] array)等等

 
    ArrayUtils.clone(newint[] { 3, 2, 4 }); = {3,2,4}
 

包含方法

 

contains(boolean[] array,boolean valueToFind)

 
    // 查询某个Object是否在数组中
    ArrayUtils.contains(newint[] { 3, 1, 2 }, 1); =  true
 

获取长度方法

 

getLength(Object array)

 
    ArrayUtils.getLength(["a", "b", "c"]) = 3
 

获取索引方法

 

indexOf(boolean[] array,boolean valueToFind)

 

indexOf(boolean[] array,boolean valueToFind,int startIndex)

 
    //查询某个Object在数组中的位置,可以指定起始搜索位置,找不到返回-1
    //从正序开始搜索,搜到就返回当前的index否则返回-1
    ArrayUtils.indexOf(newint[] { 1, 3, 6 }, 6); =  2
    ArrayUtils.indexOf(newint[] { 1, 3, 6 }, 2); =  -1
 
    //从逆序开始搜索,搜到就返回当前的index,否则返回-1
    ArrayUtils.lastIndexOf(newint[] { 1, 3, 6 }, 6); =  2
 
    //从逆序索引为2开始搜索,,搜到就返回当前的index,否则返回-1
    ArrayUtils.lastIndexOf(new Object[]{"33","yy","uu"}, "33",2 ) = 0
 

判空方法

 

isEmpty(boolean[] array)等等

 

isNotEmpty(T[] array)   

 
    //判断数组是否为空(null和length=0的时候都为空)
    ArrayUtils.isEmpty(newint[0]); =  true
    ArrayUtils.isEmpty(new Object[] { null }); = false
 

长度相等判断方法

 

isSameLength(boolean[] array1,boolean[] array2)

 
    //判断两个数组的长度是否相等
    ArrayUtils.isSameLength(new Integer[] { 1, 3, 5 }, new Long[] { "1", "3", "5"}); = true
 

空数组转换

 

nullToEmpty(Object[] array)等等

 
    //讲null转化为相应数组
    int [] arr1 = null;
    int [] arr2 = ArrayUtils.nullToEmpty(arr1);
 

删除元素方法

 

remove(boolean[] array,int index)等等

 

removeElement(boolean[] array,boolean element)

 

removeAll(T[] array,int... indices)

 

removeElements(T[] array,T... values)

 
   //删除指定下标的元素        
   ArrayUtils.remove([true, false], 1)       = [true]
    ArrayUtils.remove([true, true, false], 1) = [true, false]
 
   //删除第一次出现的元素
   ArrayUtils.removeElement([true, false], false)      = [true]
    ArrayUtils.removeElement([true, false, true], true) = [false, true]
 
   //删除所有出现的下标的元素
   ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
    ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
 
   //删除数组出现的所有元素
   ArrayUtils.removeElements(["a", "b"], "a", "c")      = ["b"]
    ArrayUtils.removeElements(["a", "b", "a"], "a")      = ["b", "a"]
    ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
 

反转方法

 

reverse(boolean[] array)等等

 

reverse(boolean[] array,int startIndexInclusive,int endIndexExclusive)

 
   //反转数组
   int[] array =newint[] { 1, 2, 5 };
   ArrayUtils.reverse(array);// {5,2,1}
 
   //指定范围的反转数组,排除endIndexExclusive的
   int[] array =new int[] {1, 2, 5 ,3,4,5,6,7,8};
   ArrayUtils.reverse(array,2,5);
   System.out.println(ArrayUtils.toString(array)); = {1,2,4,3,5,5,6,7,8}
 

截取数组

 

subarray(boolean[] array,int startIndexInclusive,int endIndexExclusive)

 
    //截取数组
    ArrayUtils.subarray(newint[] { 3, 4, 1, 5, 6 }, 2, 4); =  {1,5}
    //起始index为2(即第三个数据)结束index为4的数组
    ArrayUtils.subarray(newint[] { 3, 4, 1, 5, 6 }, 2, 10); =  {1,5,6}
    //如果endIndex大于数组的长度,则取beginIndex之后的所有数据
 

打印数组方法

 

toString(Object array)        

 

toString(Object array,String stringIfNull)

 
    //打印数组
    ArrayUtils.toString(newint[] { 1, 4, 2, 3 }); =  {1,4,2,3}
    ArrayUtils.toString(new Integer[] { 1, 4, 2, 3 }); =  {1,4,2,3}
    //如果为空,返回默认信息
    ArrayUtils.toString(null, "I'm nothing!"); =  I'm nothing!
 

数组类型转换

 

toPrimitive(Boolean[] array,boolean valueForNull)

 

Boolean[] toObject(boolean[] array)

 

Map<Object,Object> toMap(Object[] array)

 

<T> T[] toArray(T... items)

 
    //基本数据类型数组与外包型数据类型数组互转
    ArrayUtils.toObject(new int[] { 1, 2 }); = new Integer[]{Integer,Integer}
    ArrayUtils.toPrimitive(new Integer[] { new Integer(1), new Integer(2) }); = new int[]{1,2}
 
    //将二维数组转换为Map对象,数组类型必须为Map.Entry or an Array这种类型,一个作为key,一个作为value
    Map colorMap = ArrayUtils.toMap(new Object[][] {
            {"RED", "#FF0000"},
            {"GREEN", "#00FF00"},
            {"BLUE", "#0000FF"}}
    );
 
    //根据传入的参数,转换为对应的数组
    String[] array = ArrayUtils.toArray("1", "2");
    //创建String或者Number类型的数组
    String[] emptyArray = ArrayUtils.<String>toArray();
    Number[] emptyArray2 = ArrayUtils.<Number>toArray();


作者:阿_毅
链接:http://www.jianshu.com/p/7461c79f0113
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

 

@responsebody表示该方法的返回结果直接写入HTTP response body中。
它的使用情况如下:
1、一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。

2、一般是指定要response 的type。比如json 或 xml 可以直接用jackson或jaxb的包,然后就可以自动返回了,xml中也无需多的配置,就可以使用。

好处是:GET模式下,这里使用了@PathVariable绑定输入参数,非常适合Restful风格。因为隐藏了参数与路径的关系,可以提升网站的安全性,静态化页面,降低恶意攻击风险。
POST模式下,使用@RequestBody绑定请求对象,Spring会帮你进行协议转换,将Json、Xml协议转换成你需要的对象。
@ResponseBody可以标注任何对象,由Srping完成对象——协议的转换。
坏处是:返回之前,若前端编码格式不一致,很容易导致乱码。

 

@responsebody表示该方法的返回结果直接写入HTTP response body中

一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。

 

 

Java 同步和异步交换数据

同步:A跟B说给我一杯水,B去倒水,A等着,B倒完水,给A拿来,A喝水,A继续做其他事情
异步:A跟B说给我一杯水,B去倒水,A去做其他事情,B倒完水,跟A说水来了,A放下其他事情喝水,A喝完水继续做其他事情

 

交互模型就是Ajax在Browser端引入一个执行引擎,它一边应付user的请求,一边把某些必须交给服务器处理的东西背地里传送给服务器,同时背地里把结果准备好(接受服务器端的数据),展现给客户的技术模式。Ajax增强了用户的操作性。

而同步就是整个页面都刷新,异步就是只刷新用了Ajax技术的部分

 

 

Spring-jdbc:JdbcTemplate使用简介

原创 2016年08月16日 11:18:14

为了使 JDBC 更加易于使用,Spring 在 JDBCAPI 上定义了一个抽象层, 以此建立一个JDBC存取框架.

作为 SpringJDBC 框架的核心, JDBC 模板的设计目的是为不同类型的JDBC操作提供模板方法. 每个模板方法都能控制整个过程,并允许覆盖过程中的特定任务.通过这种方式,可以在尽可能保留灵活性的情况下,将数据库存取的工作量降到最低.

JdbcTemplate主要提供以下五类方法:
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
query方法及queryForXXX方法:用于执行查询相关语句;
call方法:用于执行存储过程、函数相关语句。

使用示例:

在数据库中先准备两张表:

 

 

在java工程中创建两个对应类:

[java] view plain copy

  1. public class Department {  
  2.     int id;  
  3.     String deptName;  
  4.     @Override  
  5.     public String toString() {  
  6.         return "Department [id=" + id + ", deptName=" + deptName + "]";  
  7.     }  
  8.       
  9. }  

[java] view plain copy

  1. public class Employee {  
  2.     int id;  
  3.     String lastName;  
  4.     String email;  
  5.     Department department;  
  6.     @Override  
  7.     public String toString() {  
  8.         return "Employee [id=" + id + ", lastName=" + lastName + ", email="  
  9.                 + email + ", department=" + department + "]";  
  10. 10.     }  
  11. 11.     public int getId() {  
  12. 12.         return id;  
  13. 13.     }  
  14. 14.     public void setId(int id) {  
  15. 15.         this.id = id;  
  16. 16.     }  
  17. 17.     public String getLastName() {  
  18. 18.         return lastName;  
  19. 19.     }  
  20. 20.     public void setLastName(String lastName) {  
  21. 21.         this.lastName = lastName;  
  22. 22.     }  
  23. 23.     public String getEmail() {  
  24. 24.         return email;  
  25. 25.     }  
  26. 26.     public void setEmail(String email) {  
  27. 27.         this.email = email;  
  28. 28.     }  
  29. 29.     public Department getDepartment() {  
  30. 30.         return department;  
  31. 31.     }  
  32. 32.     public void setDepartment(Department department) {  
  33. 33.         this.department = department;  
  34. 34.     }  
  35. 35.       
  36. 36.       

37. }  



引入Spring框架相关的jar包以及c3p0和mysql连接jar包。为了对方法进行测试,这里还需要引入JUnit4.这里以导入外部属性文件的方式来配置数据源:

jdbc.properties文件内容如下:

[plain] view plain copy

  1. user=root  
  2. password=123  
  3. driverClass=com.mysql.jdbc.Driver  
  4. jdbcUrl=jdbc:mysql:///spring  
  5.   
  6. initPoolSize=5  
  7. maxPoolSize=10  


在xml文件中,导入这个属性文件以及配置c3p0数据源:

[html] view plain copy

  1. <!-- 导入资源文件 -->  
  2. <context:property-placeholder location="classpath:jdbc.properties"/>  
  3.   
  4. <!-- 配置 c3p0 数据源 -->  
  5. <bean id="dataSource"  
  6.     class="com.mchange.v2.c3p0.ComboPooledDataSource">  
  7.     <property name="user" value="${user}"></property>     
  8.     <property name="password" value="${password}"></property>     
  9.     <property name="jdbcUrl" value="${jdbcUrl}"></property>   
  10. 10.     <property name="driverClass" value="${driverClass}"></property>   
  11. 11.       
  12. 12.     <property name="initialPoolSize" value="${initPoolSize}"></property>      
  13. 13.     <property name="maxPoolSize" value="${maxPoolSize}"></property>   

14. </bean>  


配置好dataSource后就可以用这个数据源来配置JdbcTemplate了,在xml文件中添加:

[html] view plain copy

  1. <!-- 配置 spring 的 JdbcTemplate -->  
  2. <bean id="jdbcTemplate"  
  3.     class="org.springframework.jdbc.core.JdbcTemplate">  
  4.     <property name="dataSource" ref="dataSource"></property>  
  5. </bean>  

接下来创建一个测试类对JdbcTemplate的方法进行测试:

[java] view plain copy

  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.   
  4. import org.junit.Test;  
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7. import org.springframework.jdbc.core.BeanPropertyRowMapper;  
  8. import org.springframework.jdbc.core.JdbcTemplate;  
  9. import org.springframework.jdbc.core.RowMapper;  
  10. 10.   

11. public class JDBCTest {  

  1. 12.       
  2. 13.     private ApplicationContext ctx= null;  
  3. 14.     private JdbcTemplate jdbcTemplate = null;  

15. //  private EmployeeDao employee;  

  1. 16.   
  2. 17.     {  
  3. 18.         ctx = new ClassPathXmlApplicationContext("ApplicationContext.xml");  
  4. 19.         jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");  
  5. 20.     }  
  6. 21.   
  7. 22.     /** 
  8. 23.      * 执行 INSERT,UPDATE,DELETE 
  9. 24.      */  
  10. 25.     @Test  
  11. 26.     public void testUpdate() {  
  12. 27.         String sql = "UPDATE employees SET last_name = ? WHERE id = ?";  
  13. 28.         jdbcTemplate.update(sql, "Jack", 5);  
  14. 29.     }  
  15. 30.     /** 
  16. 31.      * 测试批量更新操作 
  17. 32.      * 最后一个参数是 Object[] 的 List 类型:因为修改一条记录需要一个 Object 数组,修改多条记录就需要一个 List 来存放多个数组。 
  18. 33.      */  
  19. 34.     @Test  
  20. 35.     public void testBatchUpdate() {  
  21. 36.         String sql = "INSERT INTO employees(last_name, email, dept_id) VALUES(?,?,?)";  
  22. 37.           
  23. 38.         List<Object[]> batchArgs = new ArrayList<>();  
  24. 39.           
  25. 40.         batchArgs.add(new Object[]{"AA", "aa@atguigu.com", 1});  
  26. 41.         batchArgs.add(new Object[]{"BB", "bb@atguigu.com", 2});  
  27. 42.         batchArgs.add(new Object[]{"CC", "cc@atguigu.com", 3});  
  28. 43.         batchArgs.add(new Object[]{"DD", "dd@atguigu.com", 3});  
  29. 44.         batchArgs.add(new Object[]{"EE", "ee@atguigu.com", 2});  
  30. 45.           
  31. 46.         jdbcTemplate.batchUpdate(sql, batchArgs);  
  32. 47.     }  
  33. 48.       
  34. 49.     /** 
  35. 50.      * 从数据库中获取一条记录,实际得到对应的一个对象 
  36. 51.      * 注意:不是调用 queryForObject(String sql, Class<Employee> requiredType, Object... args) 方法! 
  37. 52.      * 而需要调用 queryForObject(String sql, RowMapper<Employee> rowMapper, Object... args) 
  38. 53.      * 1、其中的 RowMapper 指定如何去映射结果集的行,常用的实现类为 BeanPropertyRowMapper 
  39. 54.      * 2、使用 SQL中的列的别名完成列名和类的属性名的映射,例如 last_name lastName 
  40. 55.      * 3、不支持级联属性。 JdbcTemplate 只能作为一个 JDBC 的小工具, 而不是 ORM 框架 
  41. 56.      */  
  42. 57.     @Test  
  43. 58.     public void testQueryForObject() {  
  44. 59.         String sql = "SELECT id, last_name lastName,email,dept_id as \"department.id\" FROM employees WHERE ID = ?";  
  45. 60.         RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);  
  46. 61.         //在将数据装入对象时需要调用set方法。  
  47. 62.         Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);  
  48. 63.           
  49. 64.         System.out.println(employee);  
  50. 65.     }  
  51. 66.       
  52. 67.     /** 
  53. 68.      * 一次查询多个对象 
  54. 69.      * 注意:调用的不是 queryForList 方法 
  55. 70.      */  
  56. 71.     @Test  
  57. 72.     public void testQueryForList() {  
  58. 73.         String sql = "SELECT id, last_name lastName, email FROM employees WHERE id > ?";  
  59. 74.         RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);  
  60. 75.         List<Employee> employees = jdbcTemplate.query(sql, rowMapper,5);  
  61. 76.           
  62. 77.         System.out.println(employees);  
  63. 78.     }  
  64. 79.     /** 
  65. 80.      * 获取单个列的值或做统计查询 
  66. 81.      * 使用 queryForObject(String sql, Class<Long> requiredType)  
  67. 82.      */  
  68. 83.     @Test  
  69. 84.     public void testQueryForObject2() {  
  70. 85.         String sql = "SELECT count(id) FROM employees";  
  71. 86.         long count = jdbcTemplate.queryForObject(sql, Long.class);  
  72. 87.           
  73. 88.         System.out.println(count);  
  74. 89.     }     

90. }  


在实际的使用中,一般会创建一个dao类来封装对某个对象的所有增删改查操作.

比如,创建一个EmployeeDao类如下:

[java] view plain copy

  1. import org.springframework.beans.factory.annotation.Autowired;  
  2. import org.springframework.jdbc.core.BeanPropertyRowMapper;  
  3. import org.springframework.jdbc.core.JdbcTemplate;  
  4. import org.springframework.jdbc.core.RowMapper;  
  5. import org.springframework.stereotype.Repository;  
  6.   
  7. @Repository  
  8. public class EmployeeDao {  
  9.     @Autowired  
  10. 10.     private JdbcTemplate jdbcTemplate;  
  11. 11.       
  12. 12.     public Employee get(Integer id) {  
  13. 13.         String sql = "SELECT id, last_name lastName, email FROM employees WHERE id = ?";  
  14. 14.         RowMapper<Employee> rowMapper = new BeanPropertyRowMapper<>(Employee.class);  
  15. 15.         Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, id);  
  16. 16.           
  17. 17.         return employee;  
  18. 18.     }  

19. }  


在这个Dao类中实现了通过id来获取记录并封装成对象返回的方法。如果有需要还可以实现其他操作如插入、删除、更新等。

由于这里使用了注解来配置bean以及bean的自动装配,所以还需要在xml文件中添加(要先导入context命名空间):

[html] view plain copy

  1. <context:component-scan base-package="com.atguigu.spring.jdbc"></context:component-scan>  

测试一下EmployeeDao:

[java] view plain copy

  1. @Test  
  2. public void testEmployeeDao() {  
  3.     EmployeeDao employeeDao = (EmployeeDao) ctx.getBean("employeeDao");  
  4.     Employee employee = employeeDao.get(1);  
  5.     System.out.println(employee);  
  6. }  


打印输出如下:

 

总结:JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错。但是功能还是不够强大(比如不支持级联属性),在实际应用中还需要和hibernate、mybaties等框架混合使用。

 

posted @ 2017-11-27 09:19  lttwjt  阅读(127)  评论(0编辑  收藏  举报