一:版本一.这种存在一个问题就是每执行一次操作都会创建一次Connection链接和且释放一次链接

1:创建pojo对象(OR映射,一个pojo类对应一张数据库表)

  1.  
  1. package com.yinfu.dao;
  2.  
  3. public class Employee {
  4.  
  5. private int id;
  6. private String name;
  7. private String password;
  8. public int getId() {
  9. return id;
  10. }
  11. public void setId(int id) {
  12. this.id = id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. public String getPassword() {
  21. return password;
  22. }
  23. public void setPassword(String password) {
  24. this.password = password;
  25. }
  26. @Override
  27. public String toString() {
  28. return "Employee [id=" + id + ", name=" + name + ", password=" + password + "]";
  29. }
  30. public Employee(int id, String name, String password) {
  31. super();
  32. this.id = id;
  33. this.name = name;
  34. this.password = password;
  35. }
  36. public Employee() {
  37. super();
  38. }
  39. }

pojo对象

2:创建数据库连接用的数据文件,用于外界读取数据(properties文件):

driver=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/test user=root password=song12345

3:创建数据库连接和关闭连接的工具类(被重复使用的方法可以写在工具类中):

  1. package com.yinfu.utils;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.sql.Connection;
  6. import java.sql.DriverManager;
  7. import java.sql.PreparedStatement;
  8. import java.sql.ResultSet;
  9. import java.sql.SQLException;
  10. import java.util.Properties;
  11. /**
  12. * JDBC的工具类,封装了jdbc的一些方法
  13. * @author lusong
  14. *
  15. */
  16. public class JDBCUtils {
  17.  
  18. //关闭jdbc的链接
  19. /**
  20. * 关闭statement和connection
  21. * @param ps
  22. * @param conn
  23. */
  24. public static void release(PreparedStatement ps, Connection conn){
  25. try {
  26. if(ps != null){
  27. ps.close();
  28. }
  29. } catch (SQLException e) {
  30. e.printStackTrace();
  31. }finally{
  32. try {
  33. if(conn != null){
  34. conn.close();
  35. }
  36. } catch (SQLException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. }
  41. public static void release(ResultSet result,PreparedStatement ps, Connection conn){
  42. try {
  43. if(result != null){
  44. result.close();
  45. }
  46. } catch (SQLException e1) {
  47. e1.printStackTrace();
  48. }finally{
  49. try {
  50. if(ps != null){
  51. ps.close();
  52. }
  53. } catch (SQLException e) {
  54. e.printStackTrace();
  55. }finally{
  56. try {
  57. if(conn != null){
  58. conn.close();
  59. }
  60. } catch (SQLException e) {
  61. e.printStackTrace();
  62. }
  63. }
  64. }
  65.  
  66. }
  67.  
  68. //获取jdbc的链接
  69. /**
  70. * 用于创建jdbc链接的工具类对象
  71. * @return
  72. */
  73. public static Connection getConnetions() {
  74. Connection conn = null;
  75. String driverClass = null;
  76. String jdbcUrl = null;
  77. String user = null;
  78. String password = null;
  79.  
  80. try {
  81. //读取配置文件中的配置
  82. InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
  83. Properties properties = new Properties();
  84. properties.load(is);
  85. driverClass = properties.getProperty("driver");
  86. jdbcUrl = properties.getProperty("jdbcUrl");
  87. user = properties.getProperty("user");
  88. password = properties.getProperty("password");
  89. //注册驱动程序
  90. Class.forName(driverClass);
  91. //实际应该这样写(由于对应的应用程序中有一个对应的静态代码块,自动回将驱动的类对象进行驱动加载)
  92. //DriverManager.registerDriver((Driver) Class.forName(driverClass).newInstance());
  93.  
  94. conn = DriverManager.getConnection(jdbcUrl,user,password);
  95.  
  96. } catch (IOException e) {
  97. // TODO Auto-generated catch block
  98. e.printStackTrace();
  99. }catch (SQLException e) {
  100. // TODO Auto-generated catch block
  101. e.printStackTrace();
  102. }catch (ClassNotFoundException e) {
  103. // TODO Auto-generated catch block
  104. e.printStackTrace();
  105. }
  106. return conn;
  107. }
  108. }

4:用Junit测试实现的JDBC实现数据库的增删改查操作:

  1. package com.yinfu.test;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.sql.Connection;
  6. import java.sql.DriverManager;
  7. import java.sql.PreparedStatement;
  8. import java.sql.ResultSet;
  9. import java.sql.SQLException;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. import java.util.Properties;
  13.  
  14. import org.junit.Test;
  15.  
  16. import com.yinfu.dao.Employee;
  17. import com.yinfu.utils.JDBCUtils;
  18.  
  19. public class JDBCTest {
  20.  
  21. @Test
  22. public void testUpdate(){
  23. //曾
  24. String sql = "insert into employee (Id,Name,Password) values (1,'wangba',131)";
  25. //删
  26. //String sql = "delete from employee where id = 1";
  27. //改
  28. //String sql = "update employee set name = 'fuck' where id = 2";
  29. //查
  30. String sqlQuery = "select * from employee";
  31. update(sql);
  32. testQueryObject(sqlQuery);
  33. }
  34.  
  35. public void testQueryObject(String sql){
  36. Employee employee = null;
  37. List<Employee> list = new ArrayList();
  38. Connection conn = null;
  39. PreparedStatement ps = null;
  40. ResultSet result = null;
  41. try {
  42. //创建连接
  43. conn = JDBCUtils.getConnetions();
  44. //创建prepareStatement对象,用于执行SQL
  45. ps = conn.prepareStatement(sql);
  46. //获取查询结果集
  47. result = ps.executeQuery();
  48. while(result.next()){
  49. employee = new Employee(result.getInt(1),result.getString(2),result.getString(3));
  50. list.add(employee);
  51. }
  52. System.out.println(list);
  53. } catch (Exception e) {
  54. e.printStackTrace();
  55. }finally{
  56. JDBCUtils.release(result, ps, conn);
  57. }
  58. }
  59.  
  60. public void update(String sql){
  61. Connection conn = null;
  62. PreparedStatement ps = null;
  63. try {
  64. //创建数据库连接
  65. conn = JDBCUtils.getConnetions();
  66. //创建执行SQL的prepareStatement对象
  67. ps = conn.prepareStatement(sql);
  68. //用于增删改操作
  69. int result = ps.executeUpdate();
  70. System.out.println(result);
  71. } catch (Exception e) {
  72. System.out.println("出现异常1="+e.toString());
  73. }finally{
  74. JDBCUtils.release(ps, conn);
  75. }
  76.  
  77. }
  78. }

Statement 和PrepareStatement的区别:

首先是执行SQL的方法:

statement: 

  Class.forName(jdbcDriver);

  Connection conn = DriverManager.getConnection(jdbcUrl,userName,password);

  String sql = "insert into employee () values ('','','')"

  Statement statement = conn.createStatement();

  statement.executeUpdate(sql);

  其中的SQL语句中若有要动态输入的数据时,需要用字符串拼接SQL,难以维护容易出错。

prepareStatement:

  Class.forName(jdbcDriver);

  Connection conn = DriverManager.getConnection(jdbcUrl,userName,password);

  String sql = "insert into employee () values ('','','')"

  PrepareStatement ps = conn.prepareStatement(sql);

  statement.executeUpdate();

  其中的SQL语句中要是有动态输入的数据时,可以用占位'?'符来代替:

  String sql = "insert into employee () values (?,?,?)";

  然后用prepareStatement接口中的方法来动态赋值:

  ps.setXXX(int paramIndex ,Object value);//参数含义:占位符对应的索引值,该索引值对应的参数值;

2:(利用反射工具类)升级版查询:利用反射和JDBC元数据编写通用的查询单条记录方法(ResultSetMetaData是结果集的元数据对象):

1:创建反射工具类:

  1. package com.yinfu.utils;
  2.  
  3. import java.lang.reflect.Field;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. import java.lang.reflect.Modifier;
  7. import java.lang.reflect.ParameterizedType;
  8. import java.lang.reflect.Type;
  9.  
  10. /**
  11. * 反射的 Utils 函数集合 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
  12. *
  13. * @author Administrator
  14. *
  15. */
  16. public class ReflectionUtils {
  17.  
  18. /**
  19. * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型 如: public EmployeeDao extends
  20. * BaseDao<Employee, String>
  21. *
  22. * @param clazz
  23. * @param index
  24. * @return
  25. */
  26. @SuppressWarnings("unchecked")
  27. public static Class getSuperClassGenricType(Class clazz, int index) {
  28. Type genType = clazz.getGenericSuperclass();
  29.  
  30. if (!(genType instanceof ParameterizedType)) {
  31. return Object.class;
  32. }
  33.  
  34. Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
  35.  
  36. if (index >= params.length || index < 0) {
  37. return Object.class;
  38. }
  39.  
  40. if (!(params[index] instanceof Class)) {
  41. return Object.class;
  42. }
  43.  
  44. return (Class) params[index];
  45. }
  46.  
  47. /**
  48. * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型 如: public EmployeeDao extends
  49. * BaseDao<Employee, String>
  50. *
  51. * @param <T>
  52. * @param clazz
  53. * @return
  54. */
  55. @SuppressWarnings("unchecked")
  56. public static <T> Class<T> getSuperGenericType(Class clazz) {
  57. return getSuperClassGenricType(clazz, 0);
  58. }
  59.  
  60. /**
  61. * 循环向上转型, 获取对象的 DeclaredMethod
  62. *
  63. * @param object
  64. * @param methodName
  65. * @param parameterTypes
  66. * @return
  67. */
  68. public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes) {
  69.  
  70. for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
  71. .getSuperclass()) {
  72. try {
  73. // superClass.getMethod(methodName, parameterTypes);
  74. return superClass.getDeclaredMethod(methodName, parameterTypes);
  75. } catch (NoSuchMethodException e) {
  76. // Method 不在当前类定义, 继续向上转型
  77. }
  78. // ..
  79. }
  80.  
  81. return null;
  82. }
  83.  
  84. /**
  85. * 使 filed 变为可访问
  86. *
  87. * @param field
  88. */
  89. public static void makeAccessible(Field field) {
  90. if (!Modifier.isPublic(field.getModifiers())) {
  91. field.setAccessible(true);
  92. }
  93. }
  94.  
  95. /**
  96. * 循环向上转型, 获取对象的 DeclaredField
  97. *
  98. * @param object
  99. * @param filedName
  100. * @return
  101. */
  102. public static Field getDeclaredField(Object object, String filedName) {
  103.  
  104. for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass
  105. .getSuperclass()) {
  106. try {
  107. return superClass.getDeclaredField(filedName);
  108. } catch (NoSuchFieldException e) {
  109. // Field 不在当前类定义, 继续向上转型
  110. }
  111. }
  112. return null;
  113. }
  114.  
  115. /**
  116. * 直接调用对象方法, 而忽略修饰符(private, protected)
  117. *
  118. * @param object
  119. * @param methodName
  120. * @param parameterTypes
  121. * @param parameters
  122. * @return
  123. * @throws InvocationTargetException
  124. * @throws IllegalArgumentException
  125. */
  126. public static Object invokeMethod(Object object, String methodName, Class<?>[] parameterTypes, Object[] parameters)
  127. throws InvocationTargetException {
  128.  
  129. Method method = getDeclaredMethod(object, methodName, parameterTypes);
  130.  
  131. if (method == null) {
  132. throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
  133. }
  134.  
  135. method.setAccessible(true);
  136.  
  137. try {
  138. return method.invoke(object, parameters);
  139. } catch (IllegalAccessException e) {
  140. System.out.println("不可能抛出的异常");
  141. }
  142.  
  143. return null;
  144. }
  145.  
  146. /**
  147. * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
  148. *
  149. * @param object
  150. * @param fieldName
  151. * @param value
  152. */
  153. public static void setFieldValue(Object object, String fieldName, Object value) {
  154. Field field = getDeclaredField(object, fieldName);
  155.  
  156. if (field == null)
  157. throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
  158.  
  159. makeAccessible(field);
  160.  
  161. try {
  162. field.set(object, value);
  163. } catch (IllegalAccessException e) {
  164. System.out.println("不可能抛出的异常");
  165. }
  166. }
  167.  
  168. /**
  169. * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
  170. *
  171. * @param object
  172. * @param fieldName
  173. * @return
  174. */
  175. public static Object getFieldValue(Object object, String fieldName) {
  176. Field field = getDeclaredField(object, fieldName);
  177.  
  178. if (field == null)
  179. throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
  180.  
  181. makeAccessible(field);
  182.  
  183. Object result = null;
  184.  
  185. try {
  186. result = field.get(object);
  187. } catch (IllegalAccessException e) {
  188. System.out.println("不可能抛出的异常");
  189. }
  190.  
  191. return result;
  192. }
  193. }

反射工具类

2:编写通用查询:

  1. package com.yinfu.test;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.sql.Connection;
  6. import java.sql.DriverManager;
  7. import java.sql.PreparedStatement;
  8. import java.sql.ResultSet;
  9. import java.sql.ResultSetMetaData;
  10. import java.sql.SQLException;
  11. import java.util.ArrayList;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. import java.util.Properties;
  16.  
  17. import org.junit.Test;
  18.  
  19. import com.yinfu.dao.Employee;
  20. import com.yinfu.utils.JDBCUtils;
  21. import com.yinfu.utils.ReflectionUtils;
  22.  
  23. public class JDBCTest {
  24.  
  25. @Test
  26. public void testUpdate(){
  27. //查
  28. String sqlQuery = "select id, name, password from employee where name = ?";
  29. Object employee = testQueryObject(Employee.class,sqlQuery,"zhangsan");
  30. System.out.println("利用反射="+employee);
  31. }
  32.  
  33. public <T> T testQueryObject(Class<T> clazz, String sql, Object ... args){
  34. T object = null;
  35. Map<String, Object> map = new HashMap<String, Object>();
  36. Connection conn = null;
  37. PreparedStatement ps = null;
  38. ResultSet resultSet = null;
  39. try {
  40. //创建连接
  41. conn = JDBCUtils.getConnetions();
  42. //创建prepareStatement对象,用于执行SQL
  43. ps = conn.prepareStatement(sql);
  44. //将参数赋值到sql的所需参数中
  45. for(int i = 0 ; i < args.length ; i++){
  46. ps.setObject(i+1, args[i]);
  47. }
  48. //一:根据SQL语句和传入的参数得到结果集,此结果集中全部是纯数据值,不带列名;
  49. resultSet = ps.executeQuery();
  50. //二:利用ResultSet对象得到ResultSetMetaData对象jdbc的元数据,根据此对象可以知道SQL语句查询了哪些列,以及列的别名是什么(具体参考JDBC的API进行学习)
  51. ResultSetMetaData rsmd = resultSet.getMetaData();
  52. while(resultSet.next()){
  53. //把列名的别名和列值分别取出来放到map中作为键值出现(resultSet和rsmd结合得到的就是一个表,和数据库表一样),由ResultSetMetaData得到每一列的别名, //由ResultSet 得到对应的值
  54. for(int i=0;i<rsmd.getColumnCount();i++){
  55. String columnLabel = rsmd.getColumnLabel(i+1);
  56. Object columnValue = resultSet.getObject(columnLabel);
  57. map.put(columnLabel, columnValue);
  58. }
  59. }
  60. //利用反射创建class对应的对象
  61. object = (T) clazz.newInstance();
  62. //遍历map对象,用反射填充对象属性值
  63. for(Map.Entry<String, Object> entry : map.entrySet()){
  64. String fieldName = entry.getKey();
  65. Object fieldValue = entry.getValue();
  66. //利用反射工具類(属性名对应map的key值,属性名对应map的value值)
  67. ReflectionUtils.setFieldValue(object, fieldName, fieldValue);
  68. }
  69. } catch (Exception e) {
  70. e.printStackTrace();
  71. }finally{
  72. JDBCUtils.release(resultSet, ps, conn);
  73. }
  74. return object;
  75. }
  76. }

3:利用BeanUtils工具类实现查询多条记录(添加commons-beanutils.jar和commons-logging.jar):

  1. package com.yinfu.test;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.sql.Connection;
  6. import java.sql.DriverManager;
  7. import java.sql.PreparedStatement;
  8. import java.sql.ResultSet;
  9. import java.sql.ResultSetMetaData;
  10. import java.sql.SQLException;
  11. import java.util.ArrayList;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. import java.util.Map;
  15. import java.util.Properties;
  16.  
  17. import org.apache.commons.beanutils.BeanUtils;
  18. import org.junit.Test;
  19.  
  20. import com.yinfu.dao.Employee;
  21. import com.yinfu.utils.JDBCUtils;
  22. import com.yinfu.utils.ReflectionUtils;
  23.  
  24. public class JDBCTest {
  25.  
  26. @Test
  27. public void testUpdate(){
  28. //查多条
  29. String sqlQueryList = "select id, name, password from employee";
  30. List<Employee> testQueryList = testQueryList(Employee.class,sqlQueryList);
  31. System.out.println("查询多条:"+testQueryList);
  32.  
  33. }
  34.  
  35. //查询多条记录
  36. public <T> List<T> testQueryList(Class<T> clazz, String sql, Object ...args ){
  37. //用于接收返回值
  38. T object = null;
  39. List<T> list = new ArrayList<>();
  40. Connection conn = null;
  41. PreparedStatement rs = null;
  42. ResultSet resultSet = null;
  43. try {
  44. //获取数据库连接
  45. conn = JDBCUtils.getConnetions();
  46. rs = conn.prepareStatement(sql);
  47. //填充占位符
  48. for(int i = 0; i < args.length; i++){
  49. rs.setObject(i+1, args[i]);
  50. }
  51. //获取结果集
  52. resultSet = rs.executeQuery();
  53. //1:准备一个List<Map<String, Object>>集合,其中key为列名,value为列值,每一个map对应一条记录
  54. List<Map<String, Object>> listMap = new ArrayList<>();
  55. //2:得到jdbc的元数据
  56. ResultSetMetaData rsmd = rs.getMetaData();
  57. while(resultSet.next()){
  58. Map<String, Object> map = new HashMap<>();
  59. for(int i = 0; i < rsmd.getColumnCount(); i++){
  60. //游标是从1开始的
  61. String columnLabel = rsmd.getColumnLabel(i+1);
  62. Object columnValue = resultSet.getObject(columnLabel);
  63. map.put(columnLabel, columnValue);
  64. }
  65. //3:把一条记录map放入到listMap中
  66. listMap.add(map);
  67. }
  68.  
  69. /*//上面一段代码可以这样写
  70. List<String> labelList = getColumnLabels(resultSet);
  71. while(resultSet.next()){
  72. Map<String, Object> map = new HashMap<>();
  73. for(String columnLabel : labelList){
  74. Object columnValue = resultSet.getObject(columnLabel);
  75. map.put(columnLabel, columnValue);
  76. }
  77. //3:把一条记录map放入到listMap中
  78. listMap.add(map);
  79. }*/
  80.  
  81. //4:遍历listMap集合,把其中的每一个map都转换成对应的Class对象,并放到list中进行返回
  82. if(listMap.size()>0){
  83. for(Map<String, Object> mapObj : listMap){
  84. //有记录就通过反射得到对应的类对象
  85. object = clazz.newInstance();
  86. for(Map.Entry<String, Object> entry : mapObj.entrySet()){
  87. String propertyName = entry.getKey();
  88. Object propertyValue = entry.getValue();
  89. //利用工具类beanutils进行实体类转换
  90. BeanUtils.setProperty(object, propertyName, propertyValue);
  91. }
  92. list.add(object);
  93. }
  94. }
  95.  
  96. } catch (Exception e) {
  97. e.printStackTrace();
  98. }
  99.  
  100. return list;
  101. }
  102.  
  103. private List<String> getColumnLabels(ResultSet resultSet) throws SQLException{
  104. ResultSetMetaData rsmd = resultSet.getMetaData();
  105. List<String> list = new ArrayList<>();
  106. for(int i = 0; i<rsmd.getColumnCount(); i++){
  107. list.add(rsmd.getColumnLabel(i+1));
  108. }
  109. return list;
  110. }
  111. }

查询多条记录

4:可以用获取PrepareStatement的另一个重载方法得到,然后再用此对象的getGeneratedKeys()方法得到插入的数据时自动生成的ID的结果集,此结果集就一列,列名为:GENERATED_K。

用jdbc连接数据库并简单执行SQL语句的更多相关文章

  1. JDBC进阶之PreparedStatement执行SQL语句(MySQL)

    一.什么是PreparedStatement           参阅Java API文档,我们可以知道,PreparedStatement是Statement的子接口(如图所示),表示预编译的 SQ ...

  2. JDBC连接MYSQL,批量执行SQL语句或在执行一个SQL语句之前执行一个SQL语句

    conn = MysqlJdbcUtils.getConnection(); Statement ps=conn.createStatement(); ps.addBatch("trunca ...

  3. BIML 101 - ETL数据清洗 系列 - BIML 快速入门教程 - 连接数据库执行SQL语句

    BIML 101 - BIML 快速入门教程 第一节 连接数据库执行SQL语句 本小节将用BIML建一个简单的可以执行的包. 新建一个biml文件,贴入下面的代码 1 <Biml xmlns=& ...

  4. JDBC详解系列(四)之建立Stament和执行SQL语句

    建立Stament   在获得连接之后,我们就可以跟数据库进行交互了.   在JDBC中,我们发送SQL语句到数据库这些操作时通过Stament,Preparement,CallableStateme ...

  5. JDBC中执行SQL语句的方式

    一.执行DDL.DML语句 DDL.DML分别表示数据库定义语言.数据库操纵语言,操控这两种语言应该使用Statement对象的executeUpdate方法. 代码如下: public static ...

  6. 10.1(java学习笔记)JDBC基本操作(连接,执行SQL语句,获取结果集)

    一.JDBC JDBC的全称是java database connection java数据库连接. 在java中需要对数据库进行一系列的操作,这时就需要使用JDBC. sun公司制定了关于数据库操作 ...

  7. JDBC课程2--实现Statement(用于执行SQL语句)--使用自定义的JDBCTools的工具类静态方法,包括insert/update/delete三合一

    /**JDBC课程2--实现Statement(用于执行SQL语句) * 1.Statement :用于执行SQL语句的对象: * 1): 通过Connection 的createStatement( ...

  8. JDBC第一篇--【介绍JDBC、使用JDBC连接数据库、简单的工具类】

    1.什么是JDBC JDBC全称为:Java Data Base Connectivity,它是可以执行SQL语句的Java API 2.为什么我们要用JDBC 市面上有非常多的数据库,本来我们是需要 ...

  9. JDBC【介绍JDBC、使用JDBC连接数据库、简单的工具类】

    1.什么是JDBC JDBC全称为:Java Data Base Connectivity,它是可以执行SQL语句的Java API 2.为什么我们要用JDBC 市面上有非常多的数据库,本来我们是需要 ...

随机推荐

  1. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 629  Solved: 371[Submit][Status ...

  2. Spring Boot应用的启动和停止(Spring Boot应用通过start命令启动)

    Spring Boot,作为Spring框架对“约定优先于配置(Convention Over Configuration)”理念的最佳实践的产物,它能帮助我们很快捷的创建出独立运行.产品级别的基于S ...

  3. Java 等额本金等额本息工具类

    原文:http://www.open-open.com/code/view/1449034309983 等额本息: /** * Description:等额本息工具类 * Copyright: Cop ...

  4. DELPHI跨平台的临界替代者

    在WINDOWS里面使用临界来保护多线程需要访问的共享对象,现在,DELPHI有了新的跨平台临界保护者--System.TMonitor 代码演示如下: FConnections := TObject ...

  5. php monolog 的写日志到unix domain socket 测试终于成功

    在另外一个客户端执行 php s.php后, 通过nc -lU /tmp/tg.sck 建立的unix domain socket 有接收到消息. <?php require 'vendor/a ...

  6. react 组件之间传值

    谈及React时,就会想到一个很重要的思想,就是组件化思想.它将可以重用的部分进行组件化开发,形成一个个相对独立的组件,那么组件化后,你也会提出些疑问,组件与组件之间,将怎样进行信息的传递呢?下面来介 ...

  7. MySQL 当记录不存在时插入,当记录存在时更新

    第一种: 示例一:插入多条记录 假设有一个主键为 client_id 的 clients 表,可以使用下面的语句: INSERT INTO clients (client_id,client_name ...

  8. java-组合优于继承

    组合和继承.都能实现对类的扩展. 差别例如以下表所看到的 组合 继承 has-a关系 is-a关系 执行期决定 编译期决定 不破坏封装,总体和局部松耦合 破坏封装,子类依赖父类 支持扩展,任意添加组合 ...

  9. C++ 虚函数与纯虚函数 浅析

    [摘要] 在虚函数与纯虚函数的学习中.要求理解虚函数与纯虚函数的定义,了解虚函数与纯虚函数在实例化上的差异.掌握两者在实现上的必要性.熟悉纯虚函数在子类与孙类的函数类型.本文即针对上述问题展开阐述. ...

  10. python itertools

    1 product 1.1 一个generator函数 因此它的返回值是一个iterator,可以用for遍历. 1.2 计算product的参数分类 1.2.1 dict和list 只用了dict的 ...